glimmer 2.4.0 → 2.5.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,13 +19,13 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
- require 'glimmer/data_binding/observable'
22
+ require 'glimmer/data_binding/observable_hashable'
23
23
  require 'glimmer/data_binding/observer'
24
24
 
25
25
  module Glimmer
26
26
  module DataBinding
27
27
  module ObservableModel
28
- include Observable
28
+ include ObservableHashable
29
29
 
30
30
  class Notifier
31
31
  include Observer
@@ -40,25 +40,26 @@ module Glimmer
40
40
  end
41
41
  end
42
42
 
43
- PROPERTY_WRITER_FACTORY = lambda do |property_name|
43
+ PROPERTY_WRITER_FACTORY = lambda do |property_name, options|
44
44
  property_writer_name = "#{property_name}="
45
45
  lambda do |value|
46
46
  old_value = self.send(property_name)
47
- unregister_dependent_observers(property_name, old_value) # remove dependent observers previously installed in ensure_array_object_observer and ensure_hash_object_observer
47
+ unregister_dependent_observers(property_name, old_value) # remove dependent observers previously installed in ensure_array_object_observer
48
48
  self.send("__original__#{property_writer_name}", value)
49
49
  notify_observers(property_name)
50
- ensure_array_object_observer(property_name, value, old_value)
51
- ensure_hash_object_observer(property_name, value, old_value)
50
+ ensure_array_object_observer(property_name, value, old_value, options)
52
51
  end
53
52
  end
54
-
53
+
55
54
  def add_observer(observer, property_name, options = {})
56
55
  return observer if has_observer?(observer, property_name)
57
56
  property_observer_list(property_name) << observer
58
57
  add_property_writer_observers(property_name, options)
58
+ open_struct_loaded = !!::OpenStruct rescue false
59
+ add_key_writer_observer(property_name, options) if is_a?(Struct) || (open_struct_loaded && is_a?(OpenStruct))
59
60
  observer
60
61
  end
61
-
62
+
62
63
  def remove_observer(observer, property_name, options = {})
63
64
  if has_observer?(observer, property_name)
64
65
  property_observer_list(property_name).delete(observer)
@@ -67,10 +68,11 @@ module Glimmer
67
68
  end
68
69
 
69
70
  def remove_observers(property_name)
70
- property_observer_hash[property_name.to_sym].each do |observer|
71
+ property_key = property_name&.to_sym
72
+ property_observer_hash[property_key].each do |observer|
71
73
  remove_observer(observer, property_name)
72
74
  end
73
- property_observer_hash.delete(property_name.to_sym)
75
+ property_observer_hash.delete(property_key)
74
76
  end
75
77
 
76
78
  def remove_all_observers
@@ -91,28 +93,36 @@ module Glimmer
91
93
  end
92
94
 
93
95
  def property_observer_hash
94
- @property_observers ||= Hash.new
96
+ @property_observers ||= Concurrent::Hash.new
95
97
  end
96
98
 
97
99
  def property_observer_list(property_name)
98
- property_observer_hash[property_name.to_sym] = Concurrent::Set.new unless property_observer_hash[property_name.to_sym]
99
- property_observer_hash[property_name.to_sym]
100
+ property_key = property_name&.to_sym
101
+ property_observer_hash[property_key] = Concurrent::Set.new unless property_observer_hash[property_key]
102
+ property_observer_hash[property_key]
100
103
  end
104
+ alias key_observer_list property_observer_list
105
+
106
+ def all_property_observer_list
107
+ property_observer_list(nil)
108
+ end
109
+ alias all_key_observer_list all_property_observer_list
101
110
 
102
111
  def notify_observers(property_name)
103
112
  property_observer_list(property_name).to_a.each { |observer| observer.call(send(property_name)) }
104
113
  end
105
-
114
+
106
115
  def add_property_writer_observers(property_name, options)
107
116
  property_writer_name = "#{property_name}="
108
117
  method(property_writer_name)
109
118
  ensure_array_object_observer(property_name, send(property_name), nil, options)
110
- ensure_hash_object_observer(property_name, send(property_name), nil, options)
111
119
  begin
112
120
  method("__original__#{property_writer_name}")
113
121
  rescue
114
122
  define_singleton_method("__original__#{property_writer_name}", property_writer_method(property_writer_name))
115
- define_singleton_method(property_writer_name, &PROPERTY_WRITER_FACTORY.call(property_name))
123
+ # Note the limitation that the first observe call options apply to all subsequent observations meaning even if unobserve was called, options do not change from initial ones
124
+ # It is good enough for now. If there is a need to address this in the future, this is where to start the work
125
+ define_singleton_method(property_writer_name, &PROPERTY_WRITER_FACTORY.call(property_name, options))
116
126
  end
117
127
  rescue => e
118
128
  #ignore writing if no property writer exists
@@ -130,7 +140,7 @@ module Glimmer
130
140
  end
131
141
  alias deregister_dependent_observers unregister_dependent_observers
132
142
 
133
- def ensure_array_object_observer(property_name, object, old_object = nil, options = {})
143
+ def ensure_array_object_observer(property_name, object, old_object = nil, options = nil)
134
144
  options ||= {}
135
145
  return unless object&.is_a?(Array)
136
146
  array_object_observer = array_object_observer_for(property_name)
@@ -147,24 +157,6 @@ module Glimmer
147
157
  @array_object_observers[property_name] = Notifier.new(self, property_name) unless @array_object_observers.has_key?(property_name)
148
158
  @array_object_observers[property_name]
149
159
  end
150
-
151
- def ensure_hash_object_observer(property_name, object, old_object = nil, options)
152
- options ||= {}
153
- return unless object&.is_a?(Hash)
154
- hash_object_observer = hash_object_observer_for(property_name)
155
- hash_observer_registration = hash_object_observer.observe(object, options)
156
- property_observer_list(property_name).each do |observer|
157
- my_registration = observer.registration_for(self, property_name) # TODO eliminate repetition
158
- observer.add_dependent(my_registration => hash_observer_registration)
159
- end
160
- hash_object_observer_for(property_name).unregister(old_object) if old_object.is_a?(ObservableHash)
161
- end
162
-
163
- def hash_object_observer_for(property_name)
164
- @hash_object_observers ||= Concurrent::Hash.new
165
- @hash_object_observers[property_name] = Notifier.new(self, property_name) unless @hash_object_observers.has_key?(property_name)
166
- @hash_object_observers[property_name]
167
- end
168
160
  end
169
161
  end
170
162
  end
@@ -47,11 +47,11 @@ module Glimmer
47
47
  end
48
48
 
49
49
  class Registration < Struct.new(:observer, :observable, :args, keyword_init: true)
50
- def unregister
50
+ def deregister
51
51
  observer.unobserve(observable, *args)
52
52
  end
53
- alias unobserve unregister
54
- alias deregister unregister
53
+ alias unregister deregister
54
+ alias unobserve deregister
55
55
  end
56
56
 
57
57
  class << self
@@ -82,8 +82,10 @@ module Glimmer
82
82
 
83
83
  # registers observer in an observable on args usually containing a property and options (optional)
84
84
  # observer maintains registration list to unregister later
85
- def register(observable, *args)
85
+ def observe(observable, *args)
86
+ options = args.last.is_a?(Hash) ? args.last : {}
86
87
  return if observable.nil?
88
+ return if options[:ignore_frozen] && observable.frozen?
87
89
  unless observable.is_a?(Observable)
88
90
  # TODO refactor code to be more smart/polymorphic/automated and honor open/closed principle (e.g. for SomeClass, search if there is ObservableSomeClass)
89
91
  if observable.is_a?(Array)
@@ -98,9 +100,9 @@ module Glimmer
98
100
  observable.add_observer(self, *args)
99
101
  ensure_registration_for!(observable, *args)
100
102
  end
101
- alias observe register
103
+ alias register observe
102
104
 
103
- def unregister(observable, *args)
105
+ def unobserve(observable, *args)
104
106
  return unless observable.is_a?(Observable)
105
107
  args = compact_args(args)
106
108
  registration = registration_for(observable, *args)
@@ -113,27 +115,27 @@ module Glimmer
113
115
  observable.remove_observer(self, *args)
114
116
  end
115
117
  end
116
- alias unobserve unregister
117
- alias deregister unregister
118
+ alias unregister unobserve
119
+ alias deregister unobserve
118
120
 
119
- def unregister_dependents_with_observable(registration, dependent_observable)
121
+ def unobserve_dependents_with_observable(registration, dependent_observable)
120
122
  thedependents = dependents_for(registration).select do |thedependent|
121
123
  thedependent.observable == dependent_observable
122
124
  end
123
125
  thedependents.each(&:deregister)
124
126
  end
125
- alias unobserve_dependents_with_observable unregister_dependents_with_observable
126
- alias deregister_dependents_with_observable unregister_dependents_with_observable
127
+ alias unregister_dependents_with_observable unobserve_dependents_with_observable
128
+ alias deregister_dependents_with_observable unobserve_dependents_with_observable
127
129
 
128
130
  # cleans up all registrations in observables
129
- def unregister_all_observables
131
+ def unobserve_all_observables
130
132
  registrations.values.dup.each do |registration|
131
133
  registration.deregister
132
134
  registrations.delete([registration.observable.object_id, registration.args])
133
135
  end
134
136
  end
135
- alias unobserve_all_observables unregister_all_observables
136
- alias deregister_all_observables unregister_all_observables
137
+ alias unregister_all_observables unobserve_all_observables
138
+ alias deregister_all_observables unobserve_all_observables
137
139
 
138
140
  # add dependent observer to unregister when unregistering observer
139
141
  def add_dependent(parent_to_dependent_hash)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - AndyMaleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-15 00:00:00.000000000 Z
11
+ date: 2021-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: array_include_methods
@@ -192,23 +192,24 @@ dependencies:
192
192
  name: rake-tui
193
193
  requirement: !ruby/object:Gem::Requirement
194
194
  requirements:
195
- - - ">="
195
+ - - ">"
196
196
  - !ruby/object:Gem::Version
197
197
  version: '0'
198
198
  type: :development
199
199
  prerelease: false
200
200
  version_requirements: !ruby/object:Gem::Requirement
201
201
  requirements:
202
- - - ">="
202
+ - - ">"
203
203
  - !ruby/object:Gem::Version
204
204
  version: '0'
205
205
  description: Glimmer is a Ruby DSL Framework for Ruby GUI and More, consisting of
206
206
  a DSL Engine and an Observable / Observer / Data-Binding Library (including Observable
207
207
  Model, Observable Array, and Observable Hash). Used in Glimmer DSL for SWT (JRuby
208
- Desktop Development GUI Framework), Glimmer DSL for Tk (Ruby Desktop Development
209
- GUI Library), Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development
210
- GUI Library), Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop
211
- Apps), Glimmer DSL for XML (& HTML), and Glimmer DSL for CSS.
208
+ Desktop Development GUI Framework), Glimmer DSL for Opal (Pure Ruby Web GUI and
209
+ Auto-Webifier of Desktop Apps), Glimmer DSL for Tk (Ruby Desktop Development GUI
210
+ Library), Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI
211
+ Library), Glimmer DSL for GTK (Ruby-GNOME Desktop Development GUI Library), Glimmer
212
+ DSL for XML (& HTML), and Glimmer DSL for CSS.
212
213
  email: andy.am@gmail.com
213
214
  executables: []
214
215
  extensions: []
@@ -230,6 +231,7 @@ files:
230
231
  - lib/glimmer/data_binding/observable.rb
231
232
  - lib/glimmer/data_binding/observable_array.rb
232
233
  - lib/glimmer/data_binding/observable_hash.rb
234
+ - lib/glimmer/data_binding/observable_hashable.rb
233
235
  - lib/glimmer/data_binding/observable_model.rb
234
236
  - lib/glimmer/data_binding/observer.rb
235
237
  - lib/glimmer/data_binding/shine.rb