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