rm-extensions 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3cf1c7466015bfa9d247a7331ea115b3e2488fe2
4
- data.tar.gz: ab4897b30918931ff43d2f78a753b37f2dcce110
3
+ metadata.gz: 4638058073ecd449cd49a4ae5d0b2c0bcea20304
4
+ data.tar.gz: fda67c1392046c93f1c7de0c6de830cf68cd733b
5
5
  SHA512:
6
- metadata.gz: a1dd632b69fe168f2fa6aea6d46966b4658eae245689037b7b45bb08607266af6eb6bac8fcd0937d6fcd871efc0937cfac74b06758731d23a4a05e1e80c9139c
7
- data.tar.gz: d259f115de70b69418eb5a1b38ff62a33d33600b9613e9223b7e855e7e814dba03a598324aac0c8fc132972f463fe1af26fbe50ef6e1568b092f4f989ff7fc29
6
+ metadata.gz: d78724ff4f31f6014c7dc9732cc3a6a80919f3ccc38c0abc2668f51eb21c822b2eafb3e098488a7c12acbb2d708d6b33fca5662ad253c1034d9f34474052263d
7
+ data.tar.gz: ea9fb77064f3fb6904c8ec56ab0a50fac3f61b23d41dfeeec5d7ee4051442bb869b2c7a53664d0615dbdbe3f2aae6345cea99572b9f8cd4d8de92e16a34f0086
data/lib/motion/util.rb CHANGED
@@ -90,6 +90,124 @@ module RMExtensions
90
90
  true
91
91
  end
92
92
 
93
+ # call the block immediately if called on the main thread,
94
+ # otherwise call it async on the main queue
95
+ def rmext_inline_or_on_main_q(&block)
96
+ if NSThread.currentThread.isMainThread
97
+ block.call
98
+ else
99
+ rmext_on_main_q(&block)
100
+ end
101
+ end
102
+
103
+ # call the block immediately if called on the main thread with the given args,
104
+ # otherwise call it async on the main queue.
105
+ # silently ignores nil blocks to avoid if !block.nil? checks, useful for async callbacks
106
+ # that optionally take a callback
107
+ def rmext_block_on_main_q(block, *args)
108
+ unless block.nil?
109
+ rmext_inline_or_on_main_q do
110
+ block.call(*args)
111
+ end
112
+ end
113
+ end
114
+
115
+ ### EXPERIMENTAL
116
+
117
+ # takes a unique_id, run_immediately bool, and block
118
+ # if run_immediately is true, the block is executed immediately and not counted
119
+ # on the next run loop, the block will be called IF it has been counted at least once.
120
+ # examples:
121
+ #
122
+ # # CALLED will be printed twice. Onces immediately, and once on the next runloop:
123
+ # 10.times do
124
+ # rmext_debounce_on_next_runloop(:my_unique_id, true) do
125
+ # p "CALLED"
126
+ # end
127
+ # end
128
+ #
129
+ # # CALLED will be printed once, on the next runloop:
130
+ # 10.times do
131
+ # rmext_debounce_on_next_runloop(:my_unique_id, false) do
132
+ # p "CALLED"
133
+ # end
134
+ # end
135
+ #
136
+ # useful for queuing up something that should happen on the next runloop,
137
+ # but not every time its called. for example, reloadData. the goal was
138
+ # to get a similar behavior to how setNeedsDisplay/setNeedsLayout scheduled
139
+ # display/layout rendering on the next UI runloop pass
140
+ #
141
+ def rmext_debounce_on_next_runloop(unique_id, run_immediately, &block)
142
+ Thread.current["rmext_debounce_on_next_runloop"] ||= {}
143
+ lookup = Thread.current["rmext_debounce_on_next_runloop"]
144
+ if lookup.key?(unique_id)
145
+ lookup[unique_id][0] += 1
146
+ else
147
+ lookup[unique_id] = [ 0, lambda do
148
+ if (debounced_times = lookup[unique_id][0]) > 0
149
+ # p "we have", debounced_times, "debounced_times queued for unique_id", unique_id
150
+ block.call
151
+ else
152
+ # p "no debounced_times queued for unique_id", unique_id
153
+ end
154
+ lookup.delete(unique_id)
155
+ end ]
156
+ if run_immediately
157
+ block.call
158
+ else
159
+ lookup[unique_id][0] += 1
160
+ end
161
+ # p NSRunLoop.currentRunLoop, NSRunLoop.currentRunLoop.currentMode, lookup[unique_id][1]
162
+ NSRunLoop.currentRunLoop.performSelector('call', target:lookup[unique_id][1], argument:nil, order:0, modes:[NSRunLoop.currentRunLoop.currentMode])
163
+ end
164
+ end
165
+
166
+ def rmext_debounce_selector_on_next_runloop(selector, run_immediately)
167
+ Thread.current["rmext_debounce_selector_on_next_runloop"] ||= {}
168
+ lookup = Thread.current["rmext_debounce_selector_on_next_runloop"]
169
+ if lookup.key?(selector)
170
+ lookup[selector] += 1
171
+ else
172
+ lookup[selector] = 0
173
+ if run_immediately
174
+ send(selector)
175
+ else
176
+ lookup[selector] += 1
177
+ end
178
+ # p NSRunLoop.currentRunLoop, NSRunLoop.currentRunLoop.currentMode, self, selector, lookup[selector]
179
+ block = lambda do
180
+ if (debounced_times = lookup[selector]) > 0
181
+ # p "we have", debounced_times, "debounced_times queued for", self, selector
182
+ send(selector)
183
+ else
184
+ # p "no debounced_times queued for", self, selector
185
+ end
186
+ lookup.delete(selector)
187
+ end
188
+ NSRunLoop.currentRunLoop.performSelector('call', target:block, argument:nil, order:0, modes:[NSRunLoop.currentRunLoop.currentMode])
189
+ end
190
+ end
191
+
192
+ # more typical debouncing behavior
193
+ def rmext_debounced(method_name, seconds, *args)
194
+ new_method_name = "#{method_name}_#{seconds}"
195
+ unless respond_to?(new_method_name)
196
+ self.class.send(:define_method, new_method_name) do |*xargs|
197
+ xargs.unshift(method_name)
198
+ send(*xargs)
199
+ end
200
+ end
201
+ args.unshift(new_method_name)
202
+ NSObject.cancelPreviousPerformRequestsWithTarget(self, selector:"rmext_dispatch__send__", object:args)
203
+ performSelector("rmext_dispatch__send__", withObject:args, afterDelay:seconds)
204
+ end
205
+
206
+ # used internally by `rmext_debounced`
207
+ def rmext_dispatch__send__(*args)
208
+ send(*args)
209
+ end
210
+
93
211
  end
94
212
 
95
213
  end
@@ -1,3 +1,3 @@
1
1
  module RMExtensions
2
- VERSION = "0.3.2"
2
+ VERSION = "0.3.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rm-extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Noon