Skip to content

Instantly share code, notes, and snippets.

@renatoathaydes
Last active December 30, 2015 07:09
Show Gist options
  • Save renatoathaydes/7794202 to your computer and use it in GitHub Desktop.
Save renatoathaydes/7794202 to your computer and use it in GitHub Desktop.
Example of binding properties for Ceylon.
"A read-only property."
shared interface Property<out Prop> {
"Gets the value of this property."
shared formal Prop get;
"On change of the value of this property, the given function will be invoked."
shared formal void onChange(Anything(Prop) runOnChange);
}
"A write-only property."
shared interface Writable<in Prop> {
"Sets the value of this property."
shared formal void set(Prop prop);
}
"""A read/write property.
It can be exposed as a read-only [[Property]] or a write-only [[Writable]].
"""
shared class ObjectProperty<Prop>(Prop prop)
satisfies Property<Prop>&Writable<Prop>
given Prop satisfies Object {
variable Prop property = prop;
variable {Anything(Prop)*} toNotify = {};
get => property;
shared actual void set(Prop prop) {
if (prop == property) { return; }
property = prop;
for (notify in toNotify) {
notify(prop);
}
}
shared actual void onChange(Anything(Prop) runOnChange) {
toNotify = toNotify.chain({ runOnChange });
runOnChange(get);
}
}
shared alias BooleanProperty => ObjectProperty<Boolean>;
shared alias StringProperty => ObjectProperty<String>;
shared alias FloatProperty => ObjectProperty<Float>;
shared alias IntegerProperty => ObjectProperty<Integer>;
/** TESTS **/
import ceylon.test { test }
test void testPropertiesOfDifferentTypes() {
ObjectProperty<String> strProperty = ObjectProperty("hi");
ObjectProperty<Boolean> boolProperty = ObjectProperty(true);
void updateString(Boolean b) {
if (b) {
strProperty.set("Natallia");
} else {
strProperty.set("Renato");
}
}
boolProperty.set(true);
boolProperty.onChange(updateString);
assert(boolProperty.get == true);
assert(strProperty.get == "Natallia");
boolProperty.set(false);
assert(strProperty.get == "Renato");
}
test void testPropertiesOfTheSameType() {
ObjectProperty<String> strProp1 = ObjectProperty("hi");
ObjectProperty<String> strProp2 = ObjectProperty("ho");
strProp1.onChange(strProp2.set);
assert(strProp1.get == strProp2.get);
strProp1.set("Bye");
assert(strProp2.get == "Bye");
}
test void testCircularBinding() {
ObjectProperty<String> strProp1 = ObjectProperty("hi");
ObjectProperty<String> strProp2 = ObjectProperty("ho");
strProp1.onChange(strProp2.set);
strProp2.onChange(strProp1.set);
assert(strProp1.get == strProp2.get);
strProp1.set("Bye");
assert(strProp2.get == "Bye");
strProp2.set("Ok");
assert(strProp1.get == "Ok");
assert(strProp1.get == strProp2.get);
}
@renatoathaydes
Copy link
Author

Property holders can choose to expose their properties as read-only Bindables, write-only Writables, or both read-write ObjectProperty.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment