|
185 | 185 | (define old-v (unbox (obs-value-box o))) |
186 | 186 | (define updated-v ((obs-update-value-box! o) proc)) |
187 | 187 | (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)]) |
190 | 190 | (with-handlers ([exn:fail? |
191 | 191 | (lambda (e) |
192 | 192 | ((error-display-handler) |
193 | 193 | (format "do-obs-update!: ~a" (exn-message e)) |
194 | 194 | e))]) |
195 | | - (obs updated-v))) |
| 195 | + (observer updated-v))) |
196 | 196 | updated-v) |
197 | 197 |
|
198 | 198 | (define (obs-update! o f) |
|
206 | 206 | (define (obs-peek o) |
207 | 207 | (unbox (obs-value-box o))) |
208 | 208 |
|
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) |
213 | 217 | (define maybe-b (weak-box-value b-box)) |
214 | 218 | (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) |
218 | 222 | (will-register |
219 | 223 | executor b |
220 | 224 | (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))) |
223 | 227 | b) |
224 | 228 |
|
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)) |
227 | 231 |
|
228 | | -(define (obs-filter-map a f [d #f]) |
| 232 | +(define (obs-filter-map a proc [default #f]) |
229 | 233 | (define b |
230 | 234 | (make-obs |
231 | 235 | #: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 |
237 | 242 | (define maybe-b |
238 | 243 | (weak-box-value b-box)) |
239 | 244 | (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) |
242 | 247 | (will-register |
243 | 248 | executor b |
244 | 249 | (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))) |
247 | 252 | b) |
248 | 253 |
|
249 | | -(define (obs-combine f . os) |
| 254 | +(define (obs-combine proc . os) |
250 | 255 | (define vals |
251 | 256 | (for/vector |
252 | 257 | #:length (length os) |
253 | 258 | ([o (in-list os)]) |
254 | 259 | (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 |
258 | 267 | (for/list ([o (in-list os)] |
259 | 268 | [i (in-naturals)]) |
260 | | - (define (g v) |
| 269 | + (define (observer v) |
261 | 270 | (define maybe-b (weak-box-value b-box)) |
262 | 271 | (when maybe-b |
263 | 272 | (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)) |
268 | 277 | (will-register |
269 | 278 | executor b |
270 | 279 | (lambda (_) |
271 | | - (log-gui-easy-debug "obs-combine: unobserve ~.s" f) |
| 280 | + (log-gui-easy-debug "obs-combine: unobserve ~.s" proc) |
272 | 281 | (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)))) |
275 | 284 | b) |
276 | 285 |
|
277 | 286 | (define nothing (gensym "nothing")) |
278 | 287 | (define stop (gensym "stop")) |
279 | 288 |
|
280 | 289 | (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)) |
283 | 296 | (define thd |
284 | 297 | (thread |
285 | 298 | (lambda () |
|
302 | 315 | (when maybe-b |
303 | 316 | (do-obs-update! maybe-b (λ (_) pending))) |
304 | 317 | (loop nothing))))))))) |
305 | | - (define (proc v) |
| 318 | + (define (observer v) |
306 | 319 | (thread-send thd v)) |
307 | | - (obs-observe! a proc) |
| 320 | + (obs-observe! a observer) |
308 | 321 | (will-register |
309 | 322 | executor b |
310 | 323 | (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) |
313 | 326 | (thread-send thd stop))) |
314 | 327 | b) |
315 | 328 |
|
316 | 329 | (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)) |
319 | 336 | (define thd |
320 | 337 | (thread |
321 | 338 | (lambda () |
|
340 | 357 | (when maybe-b |
341 | 358 | (do-obs-update! maybe-b (λ (_) pending))) |
342 | 359 | (loop nothing #f))))))))) |
343 | | - (define (proc v) |
| 360 | + (define (observer v) |
344 | 361 | (thread-send thd v)) |
345 | | - (obs-observe! a proc) |
| 362 | + (obs-observe! a observer) |
346 | 363 | (will-register |
347 | 364 | executor b |
348 | 365 | (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) |
351 | 368 | (thread-send thd stop))) |
352 | 369 | b) |
353 | 370 |
|
|
390 | 407 | (check-equal? (obs-peek @odds) 5) |
391 | 408 | (obs-update! @a add1) |
392 | 409 |
|
| 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 | + |
393 | 426 | (test-case "observable names" |
394 | 427 | (define @foo (obs 42 #:name '@foo)) |
395 | 428 | (check-equal? (object-name @foo) '@foo)) |
|
0 commit comments