Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first commit

  • Loading branch information...
commit 4f3e94ef81853415130dee8a49be7c58f0a2eedc 0 parents
@mrinalwadhwa authored
34 examples/databinding/src/Example.as
@@ -0,0 +1,34 @@
+package
+{
+ import flash.text.TextField;
+ import flash.display.Sprite;
+ import crayons.data.binding.Binder;
+
+ public class Example extends Sprite
+ {
+ private var source:SomeModel;
+ private var target:TextField;
+
+ private var binder:Binder;
+
+ public function Example()
+ {
+ super();
+
+ // you only need one of these throughout your app
+ binder = new Binder();
+
+ source = new SomeModel();
+ target = new TextField();
+
+ addChild(target);
+
+ // this binds source.data to target.text,
+ // provided source dispatches dataChanged when its data property changes
+ binder.bind(source.dataChanged, target, "text");
+
+ // this should set the data in the target text field
+ source.data = "Data Binding !";
+ }
+ }
+}
31 examples/databinding/src/SomeModel.as
@@ -0,0 +1,31 @@
+package
+{
+ import crayons.signals.ChangeSignal;
+
+ public class SomeModel
+ {
+ private var _data:String;
+ public var dataChanged:ChangeSignal;
+
+ public function SomeModel()
+ {
+ dataChanged = new ChangeSignal("data");
+ }
+
+ public function get data():String
+ {
+ return _data;
+ }
+
+ public function set data(value:String):void
+ {
+ if(_data == value)
+ return;
+
+ var old:String = value;
+ _data = value;
+ // dispatch change signal whenever data changes
+ dataChanged.dispatch(old, value);
+ }
+ }
+}
92 src/crayons/data/binding/Binder.as
@@ -0,0 +1,92 @@
+package crayons.data.binding
+{
+ import crayons.signals.ChangeSignal;
+
+ import flash.utils.Dictionary;
+
+
+
+ public class Binder
+ {
+
+ protected var bindings:Dictionary = null;
+ protected var allowOverwrites:Boolean = false;
+ protected var useWeakReferences:Boolean = false;
+
+
+
+ public function Binder(allowOverwrites:Boolean = false, useWeakReferences:Boolean = false)
+ {
+ this.bindings = new Dictionary(useWeakReferences);
+ this.useWeakReferences = useWeakReferences;
+ this.allowOverwrites = allowOverwrites;
+ }
+
+
+
+ public function bind(signal:ChangeSignal, host:*, property:String):void
+ {
+ createBinding(signal, host, property);
+ }
+
+
+
+ public function hasBinding(host:*, property:String):Boolean
+ {
+ if(bindings[host] == null)
+ return false;
+
+ var binding:Binding = bindings[host][property];
+ return binding != null && binding;
+ }
+
+
+
+ public function unbind(host:*, property:String):void
+ {
+ if(hasBinding(host, property))
+ {
+ var binding:Binding = bindings[host][property];
+
+ binding.signal.remove(binding);
+ binding = null;
+
+ delete bindings[host][property];
+ }
+ }
+
+
+
+ public function unbindAll():void
+ {
+ this.bindings = new Dictionary(useWeakReferences);
+ }
+
+
+
+ protected function createBinding(signal:ChangeSignal, host:*, property:String):void
+ {
+ if(bindings[host] == null)
+ {
+ bindings[host] = [];
+ }
+
+ if(bindings[host][property] != null && !allowOverwrites)
+ {
+ throw new Error("Binding previously defined");
+ }
+ else
+ {
+ if(hasBinding(host, property))
+ {
+ unbind(host, property);
+ }
+
+ var binding:Binding = new Binding(signal, host, property);
+ signal.add(binding);
+
+ bindings[host][property] = binding;
+ }
+ }
+ }
+}
38 src/crayons/data/binding/Binding.as
@@ -0,0 +1,38 @@
+package crayons.data.binding
+{
+ import crayons.signals.ChangeSignal;
+ import crayons.signals.ChangeSlot;
+
+
+
+ public class Binding implements ChangeSlot
+ {
+
+ private var _signal:ChangeSignal = null;
+ private var _host:*;
+ private var _property:*;
+
+
+
+ public function Binding(signal:ChangeSignal, host:*, property:*)
+ {
+ _signal = signal;
+ _host = host;
+ _property = property;
+ }
+
+
+
+ public function get signal():ChangeSignal
+ {
+ return _signal;
+ }
+
+
+
+ public function onChange(oldValue:*, newValue:*):void
+ {
+ _host[_property] = newValue;
+ }
+ }
+}
27 src/crayons/signals/ChangeFunctionSlot.as
@@ -0,0 +1,27 @@
+package crayons.signals
+{
+
+
+
+ public class ChangeFunctionSlot implements ChangeSlot
+ {
+
+ public var func:Function;
+
+
+
+ public function ChangeFunctionSlot(func:Function)
+ {
+ this.func = func;
+ }
+
+
+ public function onChange(oldValue:*, newValue:*):void
+ {
+ if(func != null)
+ {
+ func(oldValue, newValue);
+ }
+ }
+ }
+}
211 src/crayons/signals/ChangeSignal.as
@@ -0,0 +1,211 @@
+package crayons.signals
+{
+
+
+
+ /**
+ * A ChangeSignal signal holds a list of ChangeSlots and calls the onChange method on
+ * them all when the signal is "dispatched".
+ *
+ * This signal passes two parameters to its slots, oldValue and newValue
+ */
+ public class ChangeSignal
+ {
+
+ private var _propertyName:String;
+ private var _slots:Array = [];
+ private var _slotsNeedCopying:Boolean;
+ private var _numDispatchesInProgress:uint;
+
+
+
+ public function ChangeSignal(proptertyName:String = "")
+ {
+ _propertyName = proptertyName;
+ }
+
+
+
+ /**
+ *
+ * Name of the property whose change in value this signal represents
+ *
+ */
+ public function get propertyName():String
+ {
+ return _propertyName;
+ }
+
+
+
+ public function set propertyName(name:String):void
+ {
+ if(_propertyName != name)
+ {
+ _propertyName = name;
+ }
+ }
+
+
+
+ /**
+ * Add a slot to be called during dispatch
+ *
+ * @param slot ChangeSlot to add or a Functin to add via a ChangeFunctionSlot
+ * This method has no effect if the slot is null or the signal already has the slot.
+ */
+ public function add(slot:*):void
+ {
+ var s:ChangeSlot;
+
+ if(slot is Function)
+ {
+ s = new ChangeFunctionSlot(slot as Function);
+ }
+ else
+ {
+ s = slot;
+ }
+
+ // Only add valid slots we don't already have
+ if(!s || _slots.indexOf(s) >= 0)
+ {
+ return;
+ }
+
+ // Copy the list during dispatch
+ if(_slotsNeedCopying)
+ {
+ _slots = _slots.slice();
+ _slotsNeedCopying = false;
+ }
+
+ _slots[_slots.length] = s;
+ }
+
+
+
+ /**
+ * Remove a Function listener
+ *
+ * @param func
+ */
+ public function remove(slot:*):void
+ {
+ // Can't remove a slot we don't have
+ var index:int = indexOf(slot);
+ if(index < 0)
+ {
+ return;
+ }
+
+ // Copy the list during dispatch
+ if(_slotsNeedCopying)
+ {
+ _slots = _slots.slice();
+ _slotsNeedCopying = false;
+ }
+
+ _slots.splice(index, 1);
+ }
+
+
+
+ /**
+ * Remove all slots so that they are not called during dispatch
+ */
+ public function removeAll():void
+ {
+ if(_slotsNeedCopying)
+ {
+ _slots = [];
+ _slotsNeedCopying = false;
+ }
+ else
+ {
+ _slots.length = 0;
+ }
+ }
+
+
+
+ /**
+ * Check if the signal has a slot
+ *
+ * @param slot Slot to check
+ * @return If the signal has the given slot
+ */
+ public function has(slot:*):Boolean
+ {
+ return indexOf(slot) >= 0;
+ }
+
+
+
+ /**
+ * Get the number of slots the signal has
+ *
+ * @return The number of slots the signal has
+ */
+ public function get numSlots():uint
+ {
+ return _slots.length;
+ }
+
+
+
+ /**
+ * Get the index of a slot in the list of slots this signal has
+ *
+ * @return The index of the given slot in the list of slots this signal has or -1 if this signal
+ * does not have the given slot
+ */
+ public function indexOf(slot:*):int
+ {
+ if(slot is Function)
+ {
+ var l:int = _slots.length;
+ for(var i:int = 0;i < l;++i)
+ {
+ if(_slots[i]["func"] === slot)
+ return i;
+ }
+ }
+ else if (slot is ChangeSlot)
+ {
+ return _slots.indexOf(slot);
+ }
+
+ return -1;
+ }
+
+
+
+ /**
+ * Call all of the slots the signal has. Calls to add() or remove() by any slot in response to these
+ * calls will not change which slots are called or the order in which they are called during
+ * this particular dispatch.
+ *
+ * @param oldValue First argument to pass to the slots
+ * @param newValue Second argument to pass to the slots
+ */
+ public function dispatch(oldValue:*, newValue:*):void
+ {
+ var slots:Array = _slots;
+ _slotsNeedCopying = true;
+ _numDispatchesInProgress++;
+
+ for(var i:uint = 0, len:uint = slots.length;i < len;++i)
+ {
+ ChangeSlot(slots[i]).onChange(oldValue, newValue);
+ }
+
+ _numDispatchesInProgress--;
+
+ if(_numDispatchesInProgress == 0)
+ {
+ _slotsNeedCopying = false;
+ }
+ }
+ }
+}
11 src/crayons/signals/ChangeSlot.as
@@ -0,0 +1,11 @@
+package crayons.signals
+{
+
+
+
+ public interface ChangeSlot
+ {
+
+ function onChange(oldValue:*, newValue:*):void;
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.