lib/woyo/world/attributes.rb in woyo-world-0.0.8 vs lib/woyo/world/attributes.rb in woyo-world-0.0.9
- old
+ new
@@ -17,23 +17,60 @@
def initialize
@listeners = {}
end
- def add_attribute_listener attr, listener
- @listeners[attr] = listener
+ def add_listener attr, listener
+ @listeners[attr] ||= []
+ @listeners[attr] << listener
end
def []= attr, value
old_value = self[attr]
super
- if ( listener = @listeners[attr] ) && value != old_value
- listener.notify attr, value
+ if value != old_value
+ @listeners[attr].each { |listener| listener.notify attr, value } if @listeners[attr] # attribute listeners (groups, etc..)
+ @listeners[:*].each { |listener| listener.notify attr, value } if @listeners[:*] # wildcard listeners (trackers)
end
end
end
-
+
+ class ChangesHash < Hash
+
+ alias_method :names, :keys
+ alias_method :set, :[]=
+
+ def notify attr, value
+ self[attr] = value
+ end
+
+ end
+
+ def changes
+ @changes ? @changes.merge!( dependent_changes ) : nil
+ end
+
+ def dependent_changes
+ remaining_attrs = @attributes.names - @changes.names
+ dependent_attrs = remaining_attrs.select do |attr|
+ @attributes[attr].kind_of?( Hash ) && ! ( @attributes[attr].keys & @changes.names ).empty?
+ end
+ dependent_attrs.each_with_object({}) do |attr,hash|
+ hash[attr] = send attr
+ end
+ end
+
+ def track_changes
+ @changes = ChangesHash.new
+ @attributes ||= Woyo::Attributes::AttributesHash.new
+ @attributes.add_listener :*, @changes # :* indicates listener for changes to all attributes
+ end
+
+ def clear_changes
+ @changes.clear
+ end
+
def attribute *attrs, &block
attributes *attrs, &block
end
def attributes *attrs, &block