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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/README.md +229 -139
- data/VERSION +1 -1
- data/glimmer.gemspec +90 -89
- data/lib/glimmer/data_binding/model_binding.rb +19 -8
- data/lib/glimmer/data_binding/observable_array.rb +21 -15
- data/lib/glimmer/data_binding/observable_hash.rb +3 -61
- data/lib/glimmer/data_binding/observable_hashable.rb +75 -0
- data/lib/glimmer/data_binding/observable_model.rb +27 -35
- data/lib/glimmer/data_binding/observer.rb +16 -14
- metadata +10 -8
@@ -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/
|
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
|
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
|
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
|
-
|
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(
|
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
|
-
|
99
|
-
property_observer_hash[
|
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
|
-
|
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
|
50
|
+
def deregister
|
51
51
|
observer.unobserve(observable, *args)
|
52
52
|
end
|
53
|
-
alias
|
54
|
-
alias deregister
|
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
|
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
|
103
|
+
alias register observe
|
102
104
|
|
103
|
-
def
|
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
|
117
|
-
alias deregister
|
118
|
+
alias unregister unobserve
|
119
|
+
alias deregister unobserve
|
118
120
|
|
119
|
-
def
|
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
|
126
|
-
alias deregister_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
|
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
|
136
|
-
alias deregister_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
|
+
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-
|
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
|
209
|
-
|
210
|
-
|
211
|
-
|
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
|