glimmer 2.2.1 → 2.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/README.md +327 -300
- data/VERSION +1 -1
- data/glimmer.gemspec +5 -5
- data/lib/glimmer/data_binding/model_binding.rb +12 -7
- data/lib/glimmer/data_binding/observable_array.rb +83 -7
- data/lib/glimmer/data_binding/observable_hash.rb +36 -10
- data/lib/glimmer/data_binding/observable_model.rb +14 -12
- data/lib/glimmer/data_binding/observer.rb +39 -26
- metadata +9 -8
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.4.1
|
data/glimmer.gemspec
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: glimmer 2.
|
5
|
+
# stub: glimmer 2.4.1 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer".freeze
|
9
|
-
s.version = "2.
|
9
|
+
s.version = "2.4.1"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["AndyMaleh".freeze]
|
14
|
-
s.date = "2021-
|
15
|
-
s.description = "Glimmer is a Ruby DSL Framework for Ruby GUI and More, consisting of a DSL Engine and an Observable/Observer/Data-Binding Library. Used in
|
14
|
+
s.date = "2021-11-01"
|
15
|
+
s.description = "Glimmer is a Ruby DSL Framework for Ruby GUI and More, consisting of a DSL Engine and an Observable / Observer / Data-Binding Library (including Observable Model, Observable Array, and Observable Hash). Used in Glimmer DSL for SWT (JRuby Desktop Development GUI Framework), Glimmer DSL for Tk (Ruby Desktop Development GUI Library), Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI Library), Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps), Glimmer DSL for XML (& HTML), and Glimmer DSL for CSS.".freeze
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
18
18
|
"CHANGELOG.md",
|
@@ -51,7 +51,7 @@ Gem::Specification.new do |s|
|
|
51
51
|
]
|
52
52
|
s.homepage = "http://github.com/AndyObtiva/glimmer".freeze
|
53
53
|
s.licenses = ["MIT".freeze]
|
54
|
-
s.rubygems_version = "3.2.
|
54
|
+
s.rubygems_version = "3.2.22".freeze
|
55
55
|
s.summary = "Glimmer - DSL Engine for Ruby GUI and More".freeze
|
56
56
|
|
57
57
|
if s.respond_to? :specification_version then
|
@@ -101,6 +101,10 @@ module Glimmer
|
|
101
101
|
def computed_by
|
102
102
|
Concurrent::Array.new([@binding_options[:computed_by]].flatten.compact)
|
103
103
|
end
|
104
|
+
|
105
|
+
def observation_options
|
106
|
+
@binding_options.slice(:recursive)
|
107
|
+
end
|
104
108
|
|
105
109
|
def nested_property_observers_for(observer)
|
106
110
|
@nested_property_observers_collection ||= Concurrent::Hash.new
|
@@ -121,7 +125,7 @@ module Glimmer
|
|
121
125
|
@nested_property_observers_collection[observer]
|
122
126
|
end
|
123
127
|
|
124
|
-
def add_observer(observer)
|
128
|
+
def add_observer(observer, extra_options = {})
|
125
129
|
if computed?
|
126
130
|
add_computed_observers(observer)
|
127
131
|
elsif nested_property?
|
@@ -133,19 +137,20 @@ module Glimmer
|
|
133
137
|
apply_processor(@binding_options[:after_read], converted_value)
|
134
138
|
end
|
135
139
|
end
|
136
|
-
observer_registration = model_binding_observer.observe(model, property_name)
|
140
|
+
observer_registration = model_binding_observer.observe(model, property_name, observation_options)
|
137
141
|
my_registration = observer.registration_for(self)
|
138
142
|
observer.add_dependent(my_registration => observer_registration)
|
139
143
|
end
|
140
144
|
end
|
141
145
|
|
142
|
-
def remove_observer(observer)
|
146
|
+
def remove_observer(observer, extra_options = {})
|
143
147
|
if computed?
|
144
148
|
@computed_model_bindings.each do |computed_model_binding|
|
145
149
|
computed_observer_for(observer).unobserve(computed_model_binding)
|
146
150
|
end
|
147
151
|
@computed_observer_collection.delete(observer)
|
148
152
|
elsif nested_property?
|
153
|
+
# No need to call remove_nested_observers(observer) (cleanup happens automatically indirectly when invoked through observer.unobserve(model_binding))
|
149
154
|
nested_property_observers_for(observer).clear
|
150
155
|
else
|
151
156
|
observer.unobserve(model, property_name)
|
@@ -167,7 +172,7 @@ module Glimmer
|
|
167
172
|
|
168
173
|
def add_computed_observers(observer)
|
169
174
|
@computed_model_bindings.each do |computed_model_binding|
|
170
|
-
observer_registration = computed_observer_for(observer).observe(computed_model_binding)
|
175
|
+
observer_registration = computed_observer_for(observer).observe(computed_model_binding, observation_options)
|
171
176
|
my_registration = observer.registration_for(self)
|
172
177
|
observer.add_dependent(my_registration => observer_registration)
|
173
178
|
end
|
@@ -191,13 +196,13 @@ module Glimmer
|
|
191
196
|
parent_property_name = nil if parent_property_name.to_s.start_with?('[')
|
192
197
|
unless model.nil?
|
193
198
|
# TODO figure out a way to deal with this more uniformly
|
194
|
-
observer_registration = property_indexed?(property_name) ? nested_property_observer.observe(model) : nested_property_observer.observe(model, property_name)
|
195
|
-
parent_registration = parent_observer.registration_for(parent_model, parent_property_name)
|
199
|
+
observer_registration = property_indexed?(property_name) ? nested_property_observer.observe(model, observation_options) : nested_property_observer.observe(model, property_name, observation_options)
|
200
|
+
parent_registration = parent_observer.registration_for(parent_model, *[parent_property_name].compact)
|
196
201
|
parent_observer.add_dependent(parent_registration => observer_registration)
|
197
202
|
end
|
198
203
|
end
|
199
204
|
end
|
200
|
-
|
205
|
+
|
201
206
|
def call(value, *extra_args)
|
202
207
|
return if model.nil?
|
203
208
|
converted_value = value
|
@@ -21,6 +21,7 @@
|
|
21
21
|
|
22
22
|
require 'set'
|
23
23
|
require 'glimmer/data_binding/observable'
|
24
|
+
require 'glimmer/data_binding/observer'
|
24
25
|
require 'array_include_methods'
|
25
26
|
|
26
27
|
using ArrayIncludeMethods
|
@@ -29,29 +30,70 @@ module Glimmer
|
|
29
30
|
module DataBinding
|
30
31
|
module ObservableArray
|
31
32
|
include Observable
|
33
|
+
|
34
|
+
class Notifier
|
35
|
+
include Observer
|
36
|
+
|
37
|
+
attr_reader :observable_array
|
38
|
+
|
39
|
+
def initialize(observable_array)
|
40
|
+
@observable_array = observable_array
|
41
|
+
end
|
42
|
+
|
43
|
+
def call(new_value=nil, *extra_args)
|
44
|
+
@observable_array.notify_observers
|
45
|
+
end
|
46
|
+
end
|
32
47
|
|
33
|
-
def add_observer(observer, *
|
48
|
+
def add_observer(observer, *args)
|
49
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
50
|
+
element_properties = args
|
34
51
|
element_properties = element_properties.flatten.compact.uniq
|
35
52
|
return observer if has_observer?(observer) && has_observer_element_properties?(observer, element_properties)
|
36
53
|
property_observer_list << observer
|
37
54
|
observer_element_properties[observer] = element_properties_for(observer) + Concurrent::Set.new(element_properties)
|
38
|
-
|
55
|
+
if !options.empty? && options[:recursive].is_a?(Integer)
|
56
|
+
options = options.clone
|
57
|
+
options[:recursive] = options[:recursive] - 1
|
58
|
+
end
|
59
|
+
each { |element| add_element_observer(element, observer, options) }
|
39
60
|
observer
|
40
61
|
end
|
41
62
|
|
42
|
-
def add_element_observers(element)
|
63
|
+
def add_element_observers(element, options = {})
|
43
64
|
property_observer_list.each do |observer|
|
44
|
-
add_element_observer(element, observer)
|
65
|
+
add_element_observer(element, observer, options)
|
45
66
|
end
|
46
67
|
end
|
47
68
|
|
48
|
-
def add_element_observer(element, observer)
|
69
|
+
def add_element_observer(element, observer, options = {})
|
49
70
|
element_properties_for(observer).each do |property|
|
50
|
-
observer.observe(element, property)
|
71
|
+
observer.observe(element, property, options)
|
72
|
+
end
|
73
|
+
if element.is_a?(Array) && (options[:recursive] == true || (options[:recursive].is_a?(Integer) && options[:recursive] >= 0))
|
74
|
+
ensure_array_object_observer(element, options)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def ensure_array_object_observer(object, options)
|
79
|
+
return unless object&.is_a?(Array)
|
80
|
+
array_object_observer = array_object_observer_for(object)
|
81
|
+
array_observer_registration = array_object_observer.observe(object, options)
|
82
|
+
property_observer_list.each do |observer|
|
83
|
+
my_registration = observer.registration_for(self)
|
84
|
+
observer.add_dependent(my_registration => array_observer_registration)
|
51
85
|
end
|
52
86
|
end
|
87
|
+
|
88
|
+
def array_object_observer_for(object)
|
89
|
+
@array_object_observers ||= Concurrent::Hash.new
|
90
|
+
@array_object_observers[object] = Notifier.new(self) unless @array_object_observers.has_key?(object)
|
91
|
+
@array_object_observers[object]
|
92
|
+
end
|
53
93
|
|
54
|
-
def remove_observer(observer, *
|
94
|
+
def remove_observer(observer, *args)
|
95
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
96
|
+
element_properties = args
|
55
97
|
element_properties = element_properties.flatten.compact.uniq
|
56
98
|
if !element_properties.empty?
|
57
99
|
old_element_properties = element_properties_for(observer)
|
@@ -76,6 +118,13 @@ module Glimmer
|
|
76
118
|
element_properties_for(observer).each do |property|
|
77
119
|
observer.unobserve(element, property)
|
78
120
|
end
|
121
|
+
if element.is_a?(ObservableArray)
|
122
|
+
array_object_observer_for(element).unobserve(element)
|
123
|
+
element.property_observer_list.select {|o| o.respond_to?(:observable_array) && o.observable_array == self}.each do |o|
|
124
|
+
o.deregister_all_observables
|
125
|
+
@array_object_observers.reject! {|k, v| v == o}
|
126
|
+
end
|
127
|
+
end
|
79
128
|
end
|
80
129
|
|
81
130
|
def has_observer?(observer)
|
@@ -204,6 +253,7 @@ module Glimmer
|
|
204
253
|
alias map! collect!
|
205
254
|
|
206
255
|
def compact!
|
256
|
+
# TODO consider checking which exact indices changed and only notifying if there is a change
|
207
257
|
super.tap { notify_observers }
|
208
258
|
end
|
209
259
|
|
@@ -237,6 +287,21 @@ module Glimmer
|
|
237
287
|
end
|
238
288
|
end
|
239
289
|
|
290
|
+
def filter!(&block)
|
291
|
+
if block_given?
|
292
|
+
old_array = Array.new(self)
|
293
|
+
super(&block).tap do
|
294
|
+
(old_array - self).each do |old_value|
|
295
|
+
unregister_dependent_observers(old_value)
|
296
|
+
remove_element_observers(old_value)
|
297
|
+
end
|
298
|
+
notify_observers
|
299
|
+
end
|
300
|
+
else
|
301
|
+
super
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
240
305
|
def shuffle!(hash = nil)
|
241
306
|
(hash.nil? ? super() : super(random: hash[:random])).tap { notify_observers }
|
242
307
|
end
|
@@ -294,6 +359,17 @@ module Glimmer
|
|
294
359
|
end
|
295
360
|
end
|
296
361
|
|
362
|
+
def replace(other_array)
|
363
|
+
old_array = Array.new(self)
|
364
|
+
super(other_array).tap do
|
365
|
+
(old_array - self).each do |old_value|
|
366
|
+
unregister_dependent_observers(old_value)
|
367
|
+
remove_element_observers(old_value)
|
368
|
+
end
|
369
|
+
notify_observers
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
297
373
|
def unregister_dependent_observers(old_value)
|
298
374
|
return unless old_value.is_a?(ObservableModel) || old_value.is_a?(ObservableArray)
|
299
375
|
property_observer_list.each { |observer| observer.unregister_dependents_with_observable(observer.registration_for(self), old_value) }
|
@@ -62,14 +62,19 @@ module Glimmer
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
def add_observer(observer, key = nil)
|
65
|
+
def add_observer(observer, key = nil, options = {})
|
66
|
+
if key.is_a?(Hash)
|
67
|
+
options = key
|
68
|
+
key = nil
|
69
|
+
end
|
66
70
|
return observer if has_observer?(observer, key)
|
67
71
|
key_observer_list(key) << observer
|
68
|
-
add_key_writer_observer(key)
|
72
|
+
add_key_writer_observer(key, options)
|
69
73
|
observer
|
70
74
|
end
|
71
75
|
|
72
|
-
def remove_observer(observer, key = nil)
|
76
|
+
def remove_observer(observer, key = nil, options = {})
|
77
|
+
old_value = self[key]
|
73
78
|
if has_observer?(observer, key)
|
74
79
|
key_observer_list(key).delete(observer)
|
75
80
|
observer.unobserve(self, key)
|
@@ -118,9 +123,9 @@ module Glimmer
|
|
118
123
|
(key_observer_list(key).to_a - all_key_observer_list.to_a).each { |observer| observer.call(self[key], key) }
|
119
124
|
end
|
120
125
|
|
121
|
-
def add_key_writer_observer(key = nil)
|
122
|
-
ensure_array_object_observer(key, self[key])
|
123
|
-
ensure_hash_object_observer(key, self[key])
|
126
|
+
def add_key_writer_observer(key = nil, options)
|
127
|
+
ensure_array_object_observer(key, self[key], nil, options)
|
128
|
+
ensure_hash_object_observer(key, self[key], nil, options)
|
124
129
|
begin
|
125
130
|
method('__original__store')
|
126
131
|
rescue
|
@@ -143,10 +148,11 @@ module Glimmer
|
|
143
148
|
end
|
144
149
|
alias deregister_dependent_observers unregister_dependent_observers
|
145
150
|
|
146
|
-
def ensure_array_object_observer(key, object, old_object = nil)
|
151
|
+
def ensure_array_object_observer(key, object, old_object = nil, options = {})
|
152
|
+
options ||= {}
|
147
153
|
return unless object&.is_a?(Array)
|
148
154
|
array_object_observer = array_object_observer_for(key)
|
149
|
-
array_observer_registration = array_object_observer.observe(object)
|
155
|
+
array_observer_registration = array_object_observer.observe(object, options)
|
150
156
|
key_observer_list(key).each do |observer|
|
151
157
|
my_registration = observer.registration_for(self, key) # TODO eliminate repetition
|
152
158
|
observer.add_dependent(my_registration => array_observer_registration)
|
@@ -160,10 +166,11 @@ module Glimmer
|
|
160
166
|
@array_object_observers[key]
|
161
167
|
end
|
162
168
|
|
163
|
-
def ensure_hash_object_observer(key, object, old_object = nil)
|
169
|
+
def ensure_hash_object_observer(key, object, old_object = nil, options = {})
|
170
|
+
options ||= {}
|
164
171
|
return unless object&.is_a?(Hash)
|
165
172
|
hash_object_observer = hash_object_observer_for(key)
|
166
|
-
hash_observer_registration = hash_object_observer.observe(object)
|
173
|
+
hash_observer_registration = hash_object_observer.observe(object, options)
|
167
174
|
key_observer_list(key).each do |observer|
|
168
175
|
my_registration = observer.registration_for(self, key) # TODO eliminate repetition
|
169
176
|
observer.add_dependent(my_registration => hash_observer_registration)
|
@@ -226,6 +233,25 @@ module Glimmer
|
|
226
233
|
end
|
227
234
|
end
|
228
235
|
|
236
|
+
def filter!(&block)
|
237
|
+
if block_given?
|
238
|
+
old_hash = self.dup
|
239
|
+
super(&block).tap do |new_hash|
|
240
|
+
deleted_keys = old_hash.keys - new_hash.keys
|
241
|
+
deleted_keys.each do |deleted_key|
|
242
|
+
deleted_value = old_hash[deleted_key]
|
243
|
+
unless deleted_value.nil?
|
244
|
+
unregister_dependent_observers(deleted_key, deleted_value)
|
245
|
+
unregister_dependent_observers(nil, deleted_value)
|
246
|
+
notify_observers(deleted_key)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
else
|
251
|
+
super
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
229
255
|
def keep_if(&block)
|
230
256
|
if block_given?
|
231
257
|
old_hash = self.dup
|
@@ -52,14 +52,14 @@ module Glimmer
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
def add_observer(observer, property_name)
|
55
|
+
def add_observer(observer, property_name, options = {})
|
56
56
|
return observer if has_observer?(observer, property_name)
|
57
57
|
property_observer_list(property_name) << observer
|
58
|
-
add_property_writer_observers(property_name)
|
58
|
+
add_property_writer_observers(property_name, options)
|
59
59
|
observer
|
60
60
|
end
|
61
61
|
|
62
|
-
def remove_observer(observer, property_name)
|
62
|
+
def remove_observer(observer, property_name, options = {})
|
63
63
|
if has_observer?(observer, property_name)
|
64
64
|
property_observer_list(property_name).delete(observer)
|
65
65
|
observer.unobserve(self, property_name)
|
@@ -103,11 +103,11 @@ module Glimmer
|
|
103
103
|
property_observer_list(property_name).to_a.each { |observer| observer.call(send(property_name)) }
|
104
104
|
end
|
105
105
|
|
106
|
-
def add_property_writer_observers(property_name)
|
106
|
+
def add_property_writer_observers(property_name, options)
|
107
107
|
property_writer_name = "#{property_name}="
|
108
108
|
method(property_writer_name)
|
109
|
-
ensure_array_object_observer(property_name, send(property_name))
|
110
|
-
ensure_hash_object_observer(property_name, send(property_name))
|
109
|
+
ensure_array_object_observer(property_name, send(property_name), nil, options)
|
110
|
+
ensure_hash_object_observer(property_name, send(property_name), nil, options)
|
111
111
|
begin
|
112
112
|
method("__original__#{property_writer_name}")
|
113
113
|
rescue
|
@@ -130,10 +130,11 @@ module Glimmer
|
|
130
130
|
end
|
131
131
|
alias deregister_dependent_observers unregister_dependent_observers
|
132
132
|
|
133
|
-
def ensure_array_object_observer(property_name, object, old_object = nil)
|
133
|
+
def ensure_array_object_observer(property_name, object, old_object = nil, options = {})
|
134
|
+
options ||= {}
|
134
135
|
return unless object&.is_a?(Array)
|
135
136
|
array_object_observer = array_object_observer_for(property_name)
|
136
|
-
array_observer_registration = array_object_observer.observe(object)
|
137
|
+
array_observer_registration = array_object_observer.observe(object, options)
|
137
138
|
property_observer_list(property_name).each do |observer|
|
138
139
|
my_registration = observer.registration_for(self, property_name) # TODO eliminate repetition
|
139
140
|
observer.add_dependent(my_registration => array_observer_registration)
|
@@ -143,14 +144,15 @@ module Glimmer
|
|
143
144
|
|
144
145
|
def array_object_observer_for(property_name)
|
145
146
|
@array_object_observers ||= Concurrent::Hash.new
|
146
|
-
@array_object_observers[property_name] =
|
147
|
+
@array_object_observers[property_name] = Notifier.new(self, property_name) unless @array_object_observers.has_key?(property_name)
|
147
148
|
@array_object_observers[property_name]
|
148
149
|
end
|
149
150
|
|
150
|
-
def ensure_hash_object_observer(property_name, object, old_object = nil)
|
151
|
+
def ensure_hash_object_observer(property_name, object, old_object = nil, options)
|
152
|
+
options ||= {}
|
151
153
|
return unless object&.is_a?(Hash)
|
152
154
|
hash_object_observer = hash_object_observer_for(property_name)
|
153
|
-
hash_observer_registration = hash_object_observer.observe(object)
|
155
|
+
hash_observer_registration = hash_object_observer.observe(object, options)
|
154
156
|
property_observer_list(property_name).each do |observer|
|
155
157
|
my_registration = observer.registration_for(self, property_name) # TODO eliminate repetition
|
156
158
|
observer.add_dependent(my_registration => hash_observer_registration)
|
@@ -160,7 +162,7 @@ module Glimmer
|
|
160
162
|
|
161
163
|
def hash_object_observer_for(property_name)
|
162
164
|
@hash_object_observers ||= Concurrent::Hash.new
|
163
|
-
@hash_object_observers[property_name] =
|
165
|
+
@hash_object_observers[property_name] = Notifier.new(self, property_name) unless @hash_object_observers.has_key?(property_name)
|
164
166
|
@hash_object_observers[property_name]
|
165
167
|
end
|
166
168
|
end
|
@@ -46,9 +46,9 @@ module Glimmer
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
class Registration < Struct.new(:observer, :observable, :
|
49
|
+
class Registration < Struct.new(:observer, :observable, :args, keyword_init: true)
|
50
50
|
def unregister
|
51
|
-
observer.unobserve(observable,
|
51
|
+
observer.unobserve(observable, *args)
|
52
52
|
end
|
53
53
|
alias unobserve unregister
|
54
54
|
alias deregister unregister
|
@@ -61,29 +61,31 @@ module Glimmer
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def registrations
|
64
|
-
@registrations ||= Concurrent::
|
64
|
+
@registrations ||= Concurrent::Hash.new
|
65
65
|
end
|
66
66
|
|
67
|
-
def registration_for(observable,
|
68
|
-
|
67
|
+
def registration_for(observable, *args)
|
68
|
+
args = compact_args(args)
|
69
|
+
registrations[[observable.object_id, args]] ||= Registration.new(observer: self, observable: observable, args: args)
|
69
70
|
end
|
71
|
+
alias ensure_registration_for! registration_for
|
70
72
|
|
71
73
|
# mapping of registrations to dependents
|
72
74
|
# {[observable, property] => [[dependent, dependent_observable, dependent_property], ...]}
|
73
75
|
def dependents
|
74
|
-
@dependents ||= Hash.new
|
76
|
+
@dependents ||= Concurrent::Hash.new
|
75
77
|
end
|
76
78
|
|
77
79
|
def dependents_for(registration)
|
78
|
-
dependents[registration] ||= Concurrent::Set.new
|
80
|
+
dependents[registration.object_id] ||= Concurrent::Set.new
|
79
81
|
end
|
80
82
|
|
81
|
-
# registers observer in an observable on a property (optional)
|
83
|
+
# registers observer in an observable on args usually containing a property and options (optional)
|
82
84
|
# observer maintains registration list to unregister later
|
83
|
-
def register(observable,
|
85
|
+
def register(observable, *args)
|
84
86
|
return if observable.nil?
|
85
87
|
unless observable.is_a?(Observable)
|
86
|
-
# TODO refactor code to be more smart/polymorphic/automated and honor open/closed principle
|
88
|
+
# TODO refactor code to be more smart/polymorphic/automated and honor open/closed principle (e.g. for SomeClass, search if there is ObservableSomeClass)
|
87
89
|
if observable.is_a?(Array)
|
88
90
|
observable.extend(ObservableArray)
|
89
91
|
elsif observable.is_a?(Hash)
|
@@ -92,23 +94,23 @@ module Glimmer
|
|
92
94
|
observable.extend(ObservableModel)
|
93
95
|
end
|
94
96
|
end
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
end
|
97
|
+
args = compact_args(args)
|
98
|
+
observable.add_observer(self, *args)
|
99
|
+
ensure_registration_for!(observable, *args)
|
99
100
|
end
|
100
101
|
alias observe register
|
101
102
|
|
102
|
-
def unregister(observable,
|
103
|
+
def unregister(observable, *args)
|
103
104
|
return unless observable.is_a?(Observable)
|
104
|
-
|
105
|
-
registration = registration_for(observable,
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
105
|
+
args = compact_args(args)
|
106
|
+
registration = registration_for(observable, *args)
|
107
|
+
registrations.delete([observable.object_id, args])
|
108
|
+
registration.tap do |registration|
|
109
|
+
dependents_for(registration).each do |dependent|
|
110
|
+
remove_dependent(registration => dependent)
|
111
|
+
dependent.deregister if dependent != registration
|
112
|
+
end
|
113
|
+
observable.remove_observer(self, *args)
|
112
114
|
end
|
113
115
|
end
|
114
116
|
alias unobserve unregister
|
@@ -118,14 +120,17 @@ module Glimmer
|
|
118
120
|
thedependents = dependents_for(registration).select do |thedependent|
|
119
121
|
thedependent.observable == dependent_observable
|
120
122
|
end
|
121
|
-
thedependents.each(&:
|
123
|
+
thedependents.each(&:deregister)
|
122
124
|
end
|
123
125
|
alias unobserve_dependents_with_observable unregister_dependents_with_observable
|
124
126
|
alias deregister_dependents_with_observable unregister_dependents_with_observable
|
125
127
|
|
126
128
|
# cleans up all registrations in observables
|
127
129
|
def unregister_all_observables
|
128
|
-
registrations.each
|
130
|
+
registrations.values.dup.each do |registration|
|
131
|
+
registration.deregister
|
132
|
+
registrations.delete([registration.observable.object_id, registration.args])
|
133
|
+
end
|
129
134
|
end
|
130
135
|
alias unobserve_all_observables unregister_all_observables
|
131
136
|
alias deregister_all_observables unregister_all_observables
|
@@ -140,12 +145,20 @@ module Glimmer
|
|
140
145
|
def remove_dependent(parent_to_dependent_hash)
|
141
146
|
registration = parent_to_dependent_hash.keys.first
|
142
147
|
dependent = parent_to_dependent_hash.values.first
|
143
|
-
dependents_for(registration).delete(dependent)
|
148
|
+
dependents_for(registration).delete(dependent).tap do
|
149
|
+
dependents.delete([registration.object_id]) if dependents_for(registration).empty?
|
150
|
+
end
|
144
151
|
end
|
145
152
|
|
146
153
|
def call(new_value = nil, *extra_args)
|
147
154
|
raise Error, 'Not implemented!'
|
148
155
|
end
|
156
|
+
|
157
|
+
def compact_args(args)
|
158
|
+
args = args[0...-1] if args.last == {}
|
159
|
+
args = args[0...-1] if args.last == []
|
160
|
+
args.compact
|
161
|
+
end
|
149
162
|
end
|
150
163
|
end
|
151
164
|
end
|
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.4.1
|
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-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: array_include_methods
|
@@ -203,11 +203,12 @@ dependencies:
|
|
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
|
-
a DSL Engine and an Observable/Observer/Data-Binding Library
|
207
|
-
|
208
|
-
Desktop Development GUI
|
209
|
-
|
210
|
-
DSL for
|
206
|
+
a DSL Engine and an Observable / Observer / Data-Binding Library (including Observable
|
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.
|
211
212
|
email: andy.am@gmail.com
|
212
213
|
executables: []
|
213
214
|
extensions: []
|
@@ -263,7 +264,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
263
264
|
- !ruby/object:Gem::Version
|
264
265
|
version: '0'
|
265
266
|
requirements: []
|
266
|
-
rubygems_version: 3.2.
|
267
|
+
rubygems_version: 3.2.22
|
267
268
|
signing_key:
|
268
269
|
specification_version: 4
|
269
270
|
summary: Glimmer - DSL Engine for Ruby GUI and More
|