Skip to content

Commit c29a54a

Browse files
committed
observable: fixup naming, add gc test
1 parent e79cf57 commit c29a54a

File tree

1 file changed

+81
-48
lines changed

1 file changed

+81
-48
lines changed

gui-easy-lib/gui/easy/private/observable.rkt

Lines changed: 81 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -185,14 +185,14 @@
185185
(define old-v (unbox (obs-value-box o)))
186186
(define updated-v ((obs-update-value-box! o) proc))
187187
(log-change o old-v updated-v)
188-
(define obss (unbox (obs-observers-box o)))
189-
(for ([obs (in-observers obss)])
188+
(define observers (unbox (obs-observers-box o)))
189+
(for ([observer (in-observers observers)])
190190
(with-handlers ([exn:fail?
191191
(lambda (e)
192192
((error-display-handler)
193193
(format "do-obs-update!: ~a" (exn-message e))
194194
e))])
195-
(obs updated-v)))
195+
(observer updated-v)))
196196
updated-v)
197197

198198
(define (obs-update! o f)
@@ -206,80 +206,93 @@
206206
(define (obs-peek o)
207207
(unbox (obs-value-box o)))
208208

209-
(define (obs-map a f)
210-
(define b (make-obs (f (obs-peek a)) #:derived? #t))
211-
(define b-box (make-weak-box b))
212-
(define (g v)
209+
(define (obs-map a proc)
210+
(define b
211+
(make-obs
212+
#:derived? #t
213+
(proc (obs-peek a))))
214+
(define b-box
215+
(make-weak-box b))
216+
(define (observer v)
213217
(define maybe-b (weak-box-value b-box))
214218
(when maybe-b
215-
(define w (f v))
216-
(do-obs-update! maybe-b (λ (_) w))))
217-
(obs-observe! a g)
219+
(define updated-v (proc v))
220+
(do-obs-update! maybe-b (λ (_) updated-v))))
221+
(obs-observe! a observer)
218222
(will-register
219223
executor b
220224
(lambda (_)
221-
(log-gui-easy-debug "obs-map: unobserve ~.s" f)
222-
(obs-unobserve! a g)))
225+
(log-gui-easy-debug "obs-map: unobserve ~.s" proc)
226+
(obs-unobserve! a observer)))
223227
b)
224228

225-
(define (obs-filter a f [d #f])
226-
(obs-filter-map a (λ (v) (and (f v) v)) d))
229+
(define (obs-filter a proc [default #f])
230+
(obs-filter-map a (λ (v) (and (proc v) v)) default))
227231

228-
(define (obs-filter-map a f [d #f])
232+
(define (obs-filter-map a proc [default #f])
229233
(define b
230234
(make-obs
231235
#:derived? #t
232-
(or (f (obs-peek a)) d)))
233-
(define b-box (make-weak-box b))
234-
(define (g v)
235-
(define w (f v))
236-
(when w
236+
(or (proc (obs-peek a)) default)))
237+
(define b-box
238+
(make-weak-box b))
239+
(define (observer v)
240+
(define updated-v (proc v))
241+
(when updated-v
237242
(define maybe-b
238243
(weak-box-value b-box))
239244
(when maybe-b
240-
(do-obs-update! maybe-b (λ (_) w)))))
241-
(obs-observe! a g)
245+
(do-obs-update! maybe-b (λ (_) updated-v)))))
246+
(obs-observe! a observer)
242247
(will-register
243248
executor b
244249
(lambda (_)
245-
(log-gui-easy-debug "obs-filter: unobserved ~.s" f)
246-
(obs-unobserve! a g)))
250+
(log-gui-easy-debug "obs-filter: unobserved ~.s" proc)
251+
(obs-unobserve! a observer)))
247252
b)
248253

249-
(define (obs-combine f . os)
254+
(define (obs-combine proc . os)
250255
(define vals
251256
(for/vector
252257
#:length (length os)
253258
([o (in-list os)])
254259
(obs-peek o)))
255-
(define b (make-obs (apply f (vector->list vals)) #:derived? #t))
256-
(define b-box (make-weak-box b))
257-
(define gs
260+
(define b
261+
(make-obs
262+
#:derived? #t
263+
(apply proc (vector->list vals))))
264+
(define b-box
265+
(make-weak-box b))
266+
(define observers
258267
(for/list ([o (in-list os)]
259268
[i (in-naturals)])
260-
(define (g v)
269+
(define (observer v)
261270
(define maybe-b (weak-box-value b-box))
262271
(when maybe-b
263272
(vector-set! vals i v)
264-
(define w (apply f (vector->list vals)))
265-
(do-obs-update! maybe-b (λ (_) w))))
266-
(obs-observe! o g)
267-
g))
273+
(define updated-v (apply proc (vector->list vals)))
274+
(do-obs-update! maybe-b (λ (_) updated-v))))
275+
(obs-observe! o observer)
276+
observer))
268277
(will-register
269278
executor b
270279
(lambda (_)
271-
(log-gui-easy-debug "obs-combine: unobserve ~.s" f)
280+
(log-gui-easy-debug "obs-combine: unobserve ~.s" proc)
272281
(for ([o (in-list os)]
273-
[g (in-list gs)])
274-
(obs-unobserve! o g))))
282+
[observer (in-list observers)])
283+
(obs-unobserve! o observer))))
275284
b)
276285

277286
(define nothing (gensym "nothing"))
278287
(define stop (gensym "stop"))
279288

280289
(define (obs-debounce a #:duration [duration 200])
281-
(define b (make-obs (obs-peek a) #:derived? #t))
282-
(define b-box (make-weak-box b))
290+
(define b
291+
(make-obs
292+
#:derived? #t
293+
(obs-peek a)))
294+
(define b-box
295+
(make-weak-box b))
283296
(define thd
284297
(thread
285298
(lambda ()
@@ -302,20 +315,24 @@
302315
(when maybe-b
303316
(do-obs-update! maybe-b (λ (_) pending)))
304317
(loop nothing)))))))))
305-
(define (proc v)
318+
(define (observer v)
306319
(thread-send thd v))
307-
(obs-observe! a proc)
320+
(obs-observe! a observer)
308321
(will-register
309322
executor b
310323
(lambda (_)
311-
(log-gui-easy-debug "obs-debounce: unobserve ~.s" proc)
312-
(obs-unobserve! a proc)
324+
(log-gui-easy-debug "obs-debounce: unobserve ~.s" observer)
325+
(obs-unobserve! a observer)
313326
(thread-send thd stop)))
314327
b)
315328

316329
(define (obs-throttle a #:duration [duration 200])
317-
(define b (make-obs (obs-peek a) #:derived? #t))
318-
(define b-box (make-weak-box b))
330+
(define b
331+
(make-obs
332+
#:derived? #t
333+
(obs-peek a)))
334+
(define b-box
335+
(make-weak-box b))
319336
(define thd
320337
(thread
321338
(lambda ()
@@ -340,14 +357,14 @@
340357
(when maybe-b
341358
(do-obs-update! maybe-b (λ (_) pending)))
342359
(loop nothing #f)))))))))
343-
(define (proc v)
360+
(define (observer v)
344361
(thread-send thd v))
345-
(obs-observe! a proc)
362+
(obs-observe! a observer)
346363
(will-register
347364
executor b
348365
(lambda (_)
349-
(log-gui-easy-debug "obs-throttle: unobserve ~.s" proc)
350-
(obs-unobserve! a proc)
366+
(log-gui-easy-debug "obs-throttle: unobserve ~.s" observer)
367+
(obs-unobserve! a observer)
351368
(thread-send thd stop)))
352369
b)
353370

@@ -390,6 +407,22 @@
390407
(check-equal? (obs-peek @odds) 5)
391408
(obs-update! @a add1)
392409

410+
(test-case "obs-map gc"
411+
(define b #f)
412+
(define @a (obs 1)) ;; noqa
413+
(define @b (obs-map @a add1)) ;; noqa
414+
(obs-observe! @b (λ (v) (set! b v)))
415+
(obs-update! @a add1)
416+
(sync (system-idle-evt))
417+
(check-equal? b 3)
418+
(set! @b #f)
419+
(collect-garbage)
420+
(collect-garbage)
421+
(sync (system-idle-evt))
422+
(obs-update! @a add1)
423+
(sync (system-idle-evt))
424+
(check-equal? b 3))
425+
393426
(test-case "observable names"
394427
(define @foo (obs 42 #:name '@foo))
395428
(check-equal? (object-name @foo) '@foo))

0 commit comments

Comments
 (0)