glimmer 2.4.0 → 2.5.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|