@@ -39,23 +39,67 @@ class State
3939 class << self
4040 attr_reader :current_observer
4141
42+ def has_observers? ( object , name )
43+ !observers_by_name [ object ] [ name ] . empty?
44+ end
45+
46+ def bulk_update
47+ saved_bulk_update_flag = @bulk_update_flag
48+ @bulk_update_flag = true
49+ yield
50+ ensure
51+ @bulk_update_flag = saved_bulk_update_flag
52+ end
53+
54+ def set_state2 ( object , name , value , updates , exclusions = nil )
55+ # set object's name state to value, tell all observers it has changed.
56+ # Observers must implement update_react_js_state
57+ object_needs_notification = object . respond_to? :update_react_js_state
58+ observers_by_name [ object ] [ name ] . dup . each do |observer |
59+ next if exclusions && exclusions . include? ( observer )
60+ updates [ observer ] += [ object , name , value ]
61+ object_needs_notification = false if object == observer
62+ end
63+ updates [ object ] += [ nil , name , value ] if object_needs_notification
64+ end
65+
4266 def initialize_states ( object , initial_values ) # initialize objects' name/value pairs
4367 states [ object ] . merge! ( initial_values || { } )
4468 end
4569
4670 def get_state ( object , name , current_observer = @current_observer )
4771 # get current value of name for object, remember that the current object depends on this state,
4872 # current observer can be overriden with last param
49- new_observers [ current_observer ] [ object ] << name if current_observer && !new_observers [ current_observer ] [ object ] . include? ( name )
73+ if current_observer && !new_observers [ current_observer ] [ object ] . include? ( name )
74+ new_observers [ current_observer ] [ object ] << name
75+ end
76+ if @delayed_updates && @delayed_updates [ object ] [ name ]
77+ @delayed_updates [ object ] [ name ] [ 1 ] << current_observer
78+ end
5079 states [ object ] [ name ]
5180 end
5281
53- def set_state ( object , name , value , wait_till_thread_completes = nil )
82+ def set_state ( object , name , value , delay = nil )
5483 states [ object ] [ name ] = value
55- if wait_till_thread_completes
56- notify_observers_after_thread_completes ( object , name , value )
57- elsif @rendering_level == 0
58- notify_observers ( object , name , value )
84+ if delay || @bulk_update_flag
85+ @delayed_updates ||= Hash . new { |h , k | h [ k ] = { } }
86+ @delayed_updates [ object ] [ name ] = [ value , Set . new ]
87+ @delayed_updater ||= after ( 0.001 ) do
88+ delayed_updates = @delayed_updates
89+ @delayed_updates = Hash . new { |h , k | h [ k ] = { } } # could this be nil???
90+ @delayed_updater = nil
91+ updates = Hash . new { |hash , key | hash [ key ] = Array . new }
92+ delayed_updates . each do |object , name_hash |
93+ name_hash . each do |name , value_and_set |
94+ set_state2 ( object , name , value_and_set [ 0 ] , updates , value_and_set [ 1 ] )
95+ end
96+ end
97+ updates . each { |observer , args | observer . update_react_js_state ( *args ) }
98+ end
99+ else
100+ updates = Hash . new { |hash , key | hash [ key ] = Array . new }
101+ set_state2 ( object , name , value , updates )
102+ updates . each { |observer , args | observer . update_react_js_state ( *args ) }
59103 end
60104 value
61105 end
0 commit comments