Last active
December 30, 2015 07:09
-
-
Save renatoathaydes/7794202 to your computer and use it in GitHub Desktop.
Example of binding properties for Ceylon.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Property holders can choose to expose their properties as read-only
Bindable
s, write-onlyWritable
s, or both read-writeObjectProperty
.