Skip to content

Commit

Permalink
core: fix container sequence bracketing
Browse files Browse the repository at this point in the history
Before this change, an error raised during the creation of a child
could leave these containers in a state where they would never update
again because the nesting depth of the sequencing could never reach 0
again.
  • Loading branch information
Bogdanp committed Dec 18, 2023
1 parent d28afb9 commit 2122661
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 65 deletions.
13 changes: 12 additions & 1 deletion gui-easy-lib/gui/easy/private/view/container.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
(require racket/class)

(provide
container%)
container%
with-container-sequence)

(define container%
(class object%
Expand Down Expand Up @@ -42,3 +43,13 @@

(define/private (get-children-to-widgets v)
(send v get-context! 'children-to-widgets make-hasheq))))

(define-syntax-rule (with-container-sequence container body0 body ...)
(dynamic-wind
(lambda ()
(send container begin-container-sequence))
(lambda ()
body0
body ...)
(lambda ()
(send container end-container-sequence))))
19 changes: 9 additions & 10 deletions gui-easy-lib/gui/easy/private/view/if.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,15 @@
[@cond-e
(define this-bool (->bool val))
(unless (eq? (get-last-bool v) this-bool)
(send v begin-container-sequence)
(when (has-then-view? v)
(remove&destroy-then-view v))
(when (has-else-view? v)
(remove&destroy-else-view v))
(if this-bool
(create&add-then-view v)
(create&add-else-view v))
(send v set-context 'last-bool this-bool)
(send v end-container-sequence))]))
(with-container-sequence v
(when (has-then-view? v)
(remove&destroy-then-view v))
(when (has-else-view? v)
(remove&destroy-else-view v))
(if this-bool
(create&add-then-view v)
(create&add-else-view v))
(send v set-context 'last-bool this-bool)))]))

(define/public (destroy v)
(when (has-then-view? v)
Expand Down
80 changes: 39 additions & 41 deletions gui-easy-lib/gui/easy/private/view/list.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -97,51 +97,49 @@
(define keys-to-children
(get-keys-to-children the-panel))
(begin0 the-panel
(send the-panel begin-container-sequence)
(for ([e (in-list (peek @entries))])
(define k (key-proc e))
(define v (make-view k (make-keyed-obs k e)))
(define w (send v create the-panel))
(add-child-handlers! the-panel v)
(add-child the-panel v w)
(hash-set! keys-to-children k v))
(send the-panel end-container-sequence)))
(with-container-sequence the-panel
(for ([e (in-list (peek @entries))])
(define k (key-proc e))
(define v (make-view k (make-keyed-obs k e)))
(define w (send v create the-panel))
(add-child-handlers! the-panel v)
(add-child the-panel v w)
(hash-set! keys-to-children k v)))))

(define/public (update v what val)
(case/dep what
[@entries
(send v begin-container-sequence)
(define keys-to-children
(get-keys-to-children v))
(define new-keys
(for/list ([e (in-list val)])
(define k (key-proc e))
(begin0 k
(unless (hash-has-key? keys-to-children k)
(define child-v (make-view k (make-keyed-obs k e)))
(define child-w (send child-v create v))
(add-child-handlers! v child-v)
(add-child v child-v child-w)
(hash-set! keys-to-children k child-v)))))
(for ([(old-k old-v) (in-hash keys-to-children)])
(unless (member old-k new-keys)
(define old-w (get-child v old-v))
(define focused? (send old-w has-focus?))
(send old-v destroy old-w)
(send v delete-child old-w)
(remove-child-handlers! v old-v)
(remove-child v old-v)
(hash-remove! keys-to-children old-k)
(when focused?
(define children (send v get-children))
(cond
[(null? children) (send v focus)]
[else (send (last children) focus)]))))
(send v change-children
(λ (_)
(for/list ([k (in-list new-keys)])
(get-child v (hash-ref keys-to-children k)))))
(send v end-container-sequence)]
(with-container-sequence v
(define keys-to-children
(get-keys-to-children v))
(define new-keys
(for/list ([e (in-list val)])
(define k (key-proc e))
(begin0 k
(unless (hash-has-key? keys-to-children k)
(define child-v (make-view k (make-keyed-obs k e)))
(define child-w (send child-v create v))
(add-child-handlers! v child-v)
(add-child v child-v child-w)
(hash-set! keys-to-children k child-v)))))
(for ([(old-k old-v) (in-hash keys-to-children)])
(unless (member old-k new-keys)
(define old-w (get-child v old-v))
(define focused? (send old-w has-focus?))
(send old-v destroy old-w)
(send v delete-child old-w)
(remove-child-handlers! v old-v)
(remove-child v old-v)
(hash-remove! keys-to-children old-k)
(when focused?
(define children (send v get-children))
(cond
[(null? children) (send v focus)]
[else (send (last children) focus)]))))
(send v change-children
(λ (_)
(for/list ([k (in-list new-keys)])
(get-child v (hash-ref keys-to-children k))))))]
[@alignment
(send/apply v set-alignment val)]
[@enabled?
Expand Down
8 changes: 4 additions & 4 deletions gui-easy-lib/gui/easy/private/view/observable.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
(prefix-in gui: racket/gui)
"../renderer.rkt"
"common.rkt"
"container.rkt"
"proxy.rkt"
"view.rkt")

Expand All @@ -29,10 +30,9 @@
(case/dep what
[@data
(unless (equal?-proc val (get-data v))
(send v begin-container-sequence)
(remove&destroy-child v)
(create&add-child v val)
(send v end-container-sequence))])
(with-container-sequence v
(remove&destroy-child v)
(create&add-child v val)))])
(define child
(send v get-context 'view #f))
(when child
Expand Down
7 changes: 3 additions & 4 deletions gui-easy-lib/gui/easy/private/view/panel.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,9 @@
(define/public (create parent)
(define the-panel (-make-panel parent))
(begin0 the-panel
(send the-panel begin-container-sequence)
(for ([c (in-list children)])
(add-child the-panel c (send c create the-panel)))
(send the-panel end-container-sequence)))
(with-container-sequence the-panel
(for ([c (in-list children)])
(add-child the-panel c (send c create the-panel))))))

(define/public (update v what val)
(case/dep what
Expand Down
7 changes: 3 additions & 4 deletions gui-easy-lib/gui/easy/private/view/tabs.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,9 @@
(send the-panel set-context 'last-selection selection)
(send the-panel set-context 'last-index index)
(send the-panel set-selection index))
(send the-panel begin-container-sequence)
(for ([c (in-list children)])
(add-child the-panel c (send c create the-panel)))
(send the-panel end-container-sequence)))
(with-container-sequence the-panel
(for ([c (in-list children)])
(add-child the-panel c (send c create the-panel))))))

(define/public (update v what val)
(case/dep what
Expand Down
2 changes: 1 addition & 1 deletion gui-easy-lib/info.rkt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#lang info

(define license 'BSD-3-Clause)
(define version "0.16")
(define version "0.16.1")
(define collection "racket")
(define deps '("base"
"box-extra-lib"
Expand Down

0 comments on commit 2122661

Please sign in to comment.