glimmer 2.4.0 → 2.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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