A good trick is to use raw Display output.

Display getCanvas��
drawString: 'hello'
from: 1
to: 5
autoBoundAt: 0 @ 0
font: nil
color: Color black.



On Mon, Oct 3, 2016 at 12:25 PM, Ben Coman <btc@openinworld.com> wrote:
On Mon, Oct 3, 2016 at 6:08 PM, Ben Coman <btc@openinworld.com> wrote:
> On Mon, Oct 3, 2016 at 3:49 PM, CodeDmitry <dimamakhnin@gmail.com> wrote:
>> a JavaScript timeout is a function that takes a block and a period of time,
>> and after�� this period of time, puts the block at the end of the event
>> queue, to be executed as soon as the runtime is done performing the tasks in
>> front of it.
>>
>> I am not sure if Pharo has an event queue, so it's a bit harder to do
>> it(since without one you can't ensure only one thing happens at a time, and
>> strange things can happen).
>>
>> That said, in simplest terms, imagine writing a clock app for Pharo, which
>> updates time every second, in JS this would be done by setting an interval
>> that ticks every 1000ms, and each time places the callback function(block)
>> at the end of the event queue.
>>
>> Related: https://www.youtube.com/watch?time_continue=1&v=8aGhZQkoFbQ
>
> Pharo has a single threaded VM, but multiple green threads can run concurrently.
> The closest to the event loop you are thinking of most likely the
> Morphic UI Process
> which you can see using World > Tools > Process Browser.�� When you execute code
> from Playground it runs in that Process (note what Smalltalk
> historically (circa 1970s?) has
> called a Process is today more commonly know as a Green Thread)
>
> If you select Morphic UI Process�� you will see its call stack on the
> right, where an interesting method is WorldState>>doOneCycleFor:
> You can gain some insight by turning on auto-update in the Process
> Browser, then open a Browser on WorldState>>doOneCycleFor:
> and put "self haltOnce" at the top, then enable it via...
> Pharo 5: World > System > Enable halt/inspect once.
> Pharo 6: World > Debugging > Enable all break/inspect once.
>
> You will see in the Process Browser that a new Morphic UI Process is
> spawned, and the original Morphic UI Process call stack now has
> #debugProcess at the top
> and a debug window appears that you can step through.�� Note, since two
> UI loops are executing here, the image may lock up, but usually its
> fine so hey! live on the edge!


I meant to ask the list about a bug I hit doing this....

Putting a "self haltOnce" here...

�� WorldState>>doOneCycleNowFor: aWorld
�� �� DisplayScreen checkForNewScreenSize.
�� �� self haltOnce.
�� �� "process user input events"
�� �� LastCycleTime := Time millisecondClockValue.
�� �� self handsDo: [:h |
�� �� �� �� self activeHand: h.
�� �� �� �� h processEvents.
�� �� �� �� self activeHand: nil.
�� �� ].
�� �� self activeHand: self hands first.
�� �� aWorld runStepMethods. "there are currently some variations here"
�� �� self displayWorldSafely: aWorld.


When stepping over "self activeHand: nil."
another debugger appears MNU: receiver of "releaseKeyboardFocus:" is nil
in GLMPagerPanePreviewMorph(Morph)>>delete

�� self activeHand
�� �� ��releaseKeyboardFocus: self;
�� �� ��releaseMouseFocus: self.


This can obviously be fixed by wrapping "self activeHand" with an #ifNil:
but alternatively I wonder if the "self activeHand: nil" is really needed?
It seems redundant since activeHand is set at the top of the loop and
immediately after exiting the loop.
Eliminating it would reduce the propagation of #ifNil: anti-pattern.

https://pharo.fogbugz.com/default.asp?19169

cheers -ben

>
> In #runStepMethodsIn: you'll see "queue := self class
> deferredUIMessages" for which you enqueue items like this...
> http://forum.world.st/Issue-3562-in-pharo-Deferred-UI-messages-executed-slowly-td3228060.html
>
> After processing the deferred UI messages, each Morph's #step method
> is processed by #runLocalStepMethodsIn:
> refer... http://wiki.squeak.org/squeak/2096
>
> The display is then rendered by #displayWorldSafely: calling...
> --> #displayWorld
> --> #displayWorld:submorphs:
> which then is a lot to trace through, but depending on the graphics
> back end eventually ends up calling...
> Canvas>>fullDrawMorph:�� �� which ultimately invokes one of many #drawOn:
> or...
> AthensCanvas>>fullDrawMorph:�� �� which ultimately invokes one of many
> #drawOnAthensCanvas:
>
>
> So, for a regular timed UI animation, you would define your custom
> morph's #step and #stepTime methods,
> and for lower level stuff you would fork like Dennis suggests.
>
> cheers -ben