@@ -39,23 +39,67 @@ class State
39
39
class << self
40
40
attr_reader :current_observer
41
41
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
+
42
66
def initialize_states ( object , initial_values ) # initialize objects' name/value pairs
43
67
states [ object ] . merge! ( initial_values || { } )
44
68
end
45
69
46
70
def get_state ( object , name , current_observer = @current_observer )
47
71
# get current value of name for object, remember that the current object depends on this state,
48
72
# 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
50
79
states [ object ] [ name ]
51
80
end
52
81
53
- def set_state ( object , name , value , wait_till_thread_completes = nil )
82
+ def set_state ( object , name , value , delay = nil )
54
83
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 ) }
59
103
end
60
104
value
61
105
end
0 commit comments