Closed benknoble closed 1 year ago
I can reproduce the issue, but when I minimize it, it stops happening. I haven't checked, but is this one of the places where you use multiple eventspaces? If so, that might be the culprit. What's happening is the paint callback is being triggered before the object finishes instantiating, and the only way I could see that happening is if the callback is being triggered on a separate eventspace.
I will double-check, but yes I think the AoE window is in a separate eventspace. Maybe it doesn't need to be…
I need to wrap my head around this a little better: I think you are saying (you suspect) the renderer creates the widget in one eventspace, but the callback is happening in another?
Also, what do you mean by "when I minimize it, it stops happening"?
I need to wrap my head around this a little better: I think you are saying (you suspect) the renderer creates the widget in one eventspace, but the callback is happening in another?
Yes, that would be the only explanation I can think of for why the Cocoa-level callback is ending up being called before the object is fully instantiated.
Also, what do you mean by "when I minimize it, it stops happening"?
I meant that when I make (what ought to be) a minimal example, it stops happening.
I need to wrap my head around this a little better: I think you are saying (you suspect) the renderer creates the widget in one eventspace, but the callback is happening in another?
Yes, that would be the only explanation I can think of for why the Cocoa-level callback is ending up being called before the object is fully instantiated.
Hopefully I have time to take a look next week and let you know. Maybe I'm "holding it wrong" :)
Also, what do you mean by "when I minimize it, it stops happening"?
I meant that when I make (what ought to be) a minimal example, it stops happening.
Ah, I thought you meant "minimize the window" or some such; the overlap with GUI terms there was unfortunate.
I need to wrap my head around this a little better: I think you are saying (you suspect) the renderer creates the widget in one eventspace, but the callback is happening in another? Yes, that would be the only explanation I can think of for why the Cocoa-level callback is ending up being called before the object is fully instantiated.
The code boils down to render/eventspace
, which is like render
but with an eventspace argument (and sets a custom parameter in the eventspace).
Essentially, I have (unimportant details commented or removed; in particular, an eventspace-generating macro expanded and some details removed)
(define (render/eventspace tree #:parent [parent #f] #:eventspace [es (current-eventspace)])
(parameterize ([current-eventspace es])
(define r (render tree parent))
;; set current-renderer in handler-thread of es
#;(queue-callback (thunk (current-renderer r)) 'high-priority)
r))
;; in the other file
(button "AoE" (thunk
(define @pict (@> @base base->pict))
(define cust (make-custodian))
(define es (parameterize ([current-custodian cust]) (make-eventspace)))
(render/eventspace
#:eventspace es
(window
#:title "AoE pattern"
(pict-canvas @pict values)))))
On second glance, the tree
object (which is (window … (pict-canvas …))
is created in the current eventspace because of strict evaluation for functions like render/eventspace
; but, render
is called in the new eventspace es
. Could this be the culprit?
I should be able to quickly adjust render/eventspace
into a macro backed by a version of the current function that delays evaluation of tree
until we are in the correct eventspace. Fingers crossed that breaks nothing else :)
Update: the following diff did not solve my problem (by creating tree
in the separate eventspace):
-(define (render/eventspace tree #:parent [parent #f] #:eventspace [es (current-eventspace)])
+(define (render/eventspace- tree #:parent [parent #f] #:eventspace [es (current-eventspace)])
(parameterize ([current-eventspace es])
- (define r (render tree parent))
+ (define r (render (tree) parent))
;; set current-renderer in handler-thread of es
#;(queue-callback (thunk (current-renderer r)) 'high-priority)
r))
+(define-syntax-parse-rule
+ (render/eventspace {~or* {~optional {~seq #:parent parent:expr}}
+ {~optional {~seq #:eventspace es:expr}}}
+ tree:expr)
+ (render/eventspace- (thunk tree) (~? (~@ #:parent parent)) (~? (~@ #:eventspace es))))
@benknoble please let me know if https://github.com/Bogdanp/racket-gui-easy/commit/8799d4ef7a209a34e71e456b758b15f22b96426b fixes the issue on your end.
Will do. To be honest I'd forgotten about this. I'll have to double-check if I found some workaround.
Ok, I didn't find any commit that suggested I fixed this, but I can't reproduce the original issue. I'll raco pkg update
anyway and let you know if I see this again.
I haven't found a small or deterministic reproduction for this yet, but you should be able to follow a few steps and see the issue.
First, drop the following in
ring1.rkt
:Then, drop the following in
bestiary.rkt
:Now, if you install the Frosthaven Manager and run it connected to a terminal window (to see error messages), you should be able to
I see (for one click)
I can't explain the error, though, nor why it only shows up sometimes. Race condition?
Once you can reproduce the error, I recommend using File > Save Game to save the current game. Then you can reload it anytime with File > Load Game or, when launching the game through the command-line, by passing the save file as the first argument (e.g.,
frosthaven-manager <save-file>
). Even here, sometimes it takes multiple "AoE" clicks to trigger the issue.[Unfortunately the save files are not totally agnostic since they contain user-specific paths. If you wanted to create
/Users/Knoble
and paths under it for testing, I could send you a save file.]