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 <b...@openinworld.com> wrote: > On Mon, Oct 3, 2016 at 6:08 PM, Ben Coman <b...@openinworld.com> wrote: > > On Mon, Oct 3, 2016 at 3:49 PM, CodeDmitry <dimamakh...@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 > > >