pharo-graphics / Bloc

Low-level UI infrastructure & framework for Pharo
MIT License
81 stars 40 forks source link

Execute inUIProcessDo: when even there is no process #642

Open labordep opened 4 hours ago

labordep commented 4 hours ago

The method BlElement>>inUIProcessDo: aBlock cannot value block when there is no uiProcess (nil). This is the case when I'm writing basic unit tests. I think it should be great to value block in all cases. This can be use to build from the same way a BlElement inside or outside the graphic tree.

A fix can be:

inUIProcessDo: aBlock
    "Run the supplied block in the UI process.
    If the active process is already the UI process, evaluate immediately. 
    Otherwise, queue up for the next frame."

    | uiProcess |
    self isAttachedToSceneGraph ifTrue: [ 
        self space host uiProcessDo: [ :uiProc | uiProcess := uiProc ] ].

    (uiProcess  isNil or:[ uiProcess = Processor activeProcess ])
        ifTrue: [ aBlock value ]
        ifFalse: [ 
            self enqueueTask: (BlTaskAction new
                     action: aBlock;
                     yourself) ]
labordep commented 4 hours ago

@tinchodias @plantec do you have an opinion?

tinchodias commented 1 hour ago

Hello Pierre. I've found the diff! you suggest changing the if receiver from uiProcess = Processor activeProcess by (uiProcess isNil or:[ uiProcess = Processor activeProcess ]). I don't realize on my head what's the effect / why it fixes your test.

I imagine you are testing on a space that's not open, right? I mean, you didn't send show to it (+ wait afterwards so it has effect).

I always considered this API as a patch/workaround to be removed one day (I don't know its origin, it was already there).

I have the impression the API exists because of "low-level" graphics libraries that have global state that is broken if you do the FFI calls from Pharo from different Processes (the C library is not aware of them, it just has a global state). In particular, I think this happens in https://freetype.org/.