of course Pharo has an event queue, we call them announcements. That implies however that you want the code to execute as soon as something else happens. If you don't , fork and delay should be enough. With fork you dont need to wait for othet tasks to finish to execute your code, it will just put it to a thread and execute it concurently. If you want the code to run as soon as other tasks finish then of course you dont use fork. On Mon, Oct 3, 2016 at 10:56 AM CodeDmitry <[hidden email]> wrote: a JavaScript timeout is a function that takes a block and a period of time, |
In reply to this post by CodeDmitry
Hi. 2016-10-03 9:49 GMT+02:00 CodeDmitry <[hidden email]>:
Also look at project TaskIt https://github.com/sbragagnolo/taskit. It provides many high level scheduling capabilities. |
This post was updated on .
In reply to this post by kilon.alios
CONTENTS DELETED
The author has deleted this message.
|
In reply to this post by Denis Kudriashov
And if this just for a graphical clock, a morph with step should be doing the trick. stepTime can be set as well. Phil On Mon, Oct 3, 2016 at 10:09 AM, Denis Kudriashov <[hidden email]> wrote:
|
In reply to this post by CodeDmitry
On Mon, Oct 3, 2016 at 3:49 PM, CodeDmitry <[hidden email]> 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! 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 |
On Mon, Oct 3, 2016 at 6:08 PM, Ben Coman <[hidden email]> wrote:
> On Mon, Oct 3, 2016 at 3:49 PM, CodeDmitry <[hidden email]> 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 |
On Mon, Oct 3, 2016 at 6:25 PM, Ben Coman <[hidden email]> wrote:
> On Mon, Oct 3, 2016 at 6:08 PM, Ben Coman <[hidden email]> wrote: >> On Mon, Oct 3, 2016 at 3:49 PM, CodeDmitry <[hidden email]> 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. A further curiousity occurs to me. With this being executed 20 times a second or more, how can the active hand ever be anything other than the primary hand? Why isn't the active hand stored, all hands cycled through processing events, then the active hand restored?? cheers -ben > 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 |
Hi Ben. 2016-10-03 12:37 GMT+02:00 Ben Coman <[hidden email]>:
self handsDo: [:h | ActiveHand := h. h processEvents. ActiveHand := nil ]. Could you try your test on previous version of Pharo? |
In reply to this post by Ben Coman
UIManager>>#defer: aBlock can be useful too.
defer: aBlock " Evaluate the given Block in the UI thread as soon as there is nothing scheduled. Evaluate immediately when there is no UI" aBlock value For some fun, check also GrowlMorph 10 timesRepeat: [ (GrowlMorph openWithLabel: 'The time' contents: DateAndTime now) " vanishDelay: 1000; resetVanishTimer". World doOneCycle ]. inspect how vanishDelay: works, so that you can get the same kind of thing as a JS setTimeout(function(){ alert("Hello"); }, 3000); Phil On Mon, Oct 3, 2016 at 12:08 PM, Ben Coman <[hidden email]> wrote: > > On Mon, Oct 3, 2016 at 3:49 PM, CodeDmitry <[hidden email]> 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! > > 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 > > |
In reply to this post by Denis Kudriashov
There has been some serious refactoring occuring in these specific bowels of the beast. Phil On Mon, Oct 3, 2016 at 1:08 PM, Denis Kudriashov <[hidden email]> wrote:
|
In reply to this post by Ben Coman
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 <[hidden email]> wrote: On Mon, Oct 3, 2016 at 6:08 PM, Ben Coman <[hidden email]> wrote: |
In reply to this post by Ben Coman
Here is some interesting event loop stuff from Tcl. I wish we had some easy Tk UI building things in Pharo. Spec is okay but not intuitive. As it is the only thing that exposes the myriad of various Morphs we have and shields us (somewhat) from the underlying details, we have to use it, but its explorability is really detrimental to the livecoding side of Pharo. Phil On Mon, Oct 3, 2016 at 12:25 PM, Ben Coman <[hidden email]> wrote: On Mon, Oct 3, 2016 at 6:08 PM, Ben Coman <[hidden email]> wrote: |
In reply to this post by CodeDmitry
I am not very fond of event loops in general, because they imply "many inputs, one output" (process all pending events, then update screen).
For Morphic this is fine, because it displays on one screen, refreshing at/around its frequency. But there might be other screens, or network-output, file-output, which have different refresh frequencies. Then you would want to process input events as they trigger rather than storing them in a queue, such that whichever output destination sees the most up-to-date state of the program. Javascript has this cool function, requestAnimationFrame, which sets a one-time callback right before the next redraw. In essence it is an output event, allowing some form of reactive programming (no loop, only callbacks on input and output). In Pharo we have InputEventFetcher>>registerHandler: which is great for getting input callbacks, but nothing for output :/ WorldState>>addDeferredUIMessage: is probably a closest match, yet it is bound to Morphic, preventing experiments on UI/video games. Any alternatives? Thibault > Here is some interesting event loop stuff from Tcl. > > http://wiki.tcl.tk/2567 > > I wish we had some easy Tk UI building things in Pharo. > > Spec is okay but not intuitive. As it is the only thing that exposes the > myriad of various Morphs we have and shields us (somewhat) from the > underlying details, we have to use it, but its explorability is really > detrimental to the livecoding side of Pharo. > > Phil |
In reply to this post by philippeback
Hi,
On 02/10/16 17:13, [hidden email] wrote: [...] > Use it whenever you can, it will force you to understand how to do > real stuff with it properly. > > I do hackathons with it. > https://hackernoon.com/hackapost-how-hackathons-can-be-the-best-learning-tool-under-the-sun-9c97e567e0a5 > As complementary to the infrastructure, code standards, libraries and so on, a needed contribution, from the social dynamics perspective, are hachathons and workshops. We're making them regularly here (link at [1], in Spanish), with a critical data/code literacy approach. Last week we have our 5th edition and this week we're going to make an agile 6th edition. [1] http://mutabit.com/dataweek/ I found the Pharo community very open to contribution. The fast feedback loop [2] is experienced here in a very visible way and most of the time the community is welcoming (with notable few exceptions, "ad hominen" attacks and poor argumentation, but also with a good self-correcting feedback from the broader community). [2] http://www.slideshare.net/MarcusDenker/perfection-feedback-loops-or-why-worse-is-better-65540840 So is not a perfect place, as any other, but you'll find a way of contributing that is considered worthy and encouraged and even supported with economical resources from Pharo Association / Consorcium from time to time. Welcome here, you and your contribution ;-), Offray |
In reply to this post by Thibault Raffaillac
On Mon, Oct 3, 2016 at 3:00 PM, Thibault Raffaillac <[hidden email]> wrote: I am not very fond of event loops in general, because they imply "many inputs, one output" (process all pending events, then update screen). For Morphic this is fine, because it displays on one screen, refreshing at/around its frequency. But there might be other screens, or network-output, file-output, which have different refresh frequencies. Then you would want to process input events as they trigger rather than storing them in a queue, such that whichever output destination sees the most up-to-date state of the program. One upfront queue with several workers is the way to do this fast and in a scalable way. Nothing new under the sun, Tuxedo has been doing this for eons, as is any decent TP framework. https://en.wikipedia.org/wiki/Tuxedo_(software) Most of this has been rehashed a lot of times bringing nothing new to the table. Best closest thing for free would be RabbitMQ. Works fine. Even has an MQTT component, which makes it great for IoT.
Yes, this is a nice one. This guy uses it a lot to super good effect: https://www.livecoding.tv/killroy/ - e.g. https://www.livecoding.tv/killroy/videos/xy8P1-prototypes-and-experiments-javascript-webgl-7 In Pharo we have InputEventFetcher>> Any alternatives? This? Maybe this (but not the same thing really) For video games, well, the ususal update/render with framerate adjustment is the typical loop. If the render is too slow vs the expected one things are skipped, several updates for a render. And user input is picked at one point during the update bit. Not really the same as a windowed GUI. Note that Windows has a queue per app these days (in 3.x days, it was a single queue for all of Windows, which is why things froze a lot. Same as current Pharo). Note also that in Pharo, the InputEventFetcher etc is just the default way and one can have an image doing things otherwise. Display is the raw thing, primitives can do whatever, so if you feel like it, you can reinvent something fully different on the platform.
|
In reply to this post by Offray Vladimir Luna Cárdenas-2
Case in point, I am submitting a proposal here: https://devfest.be/blog/posts/cfp/ That's Google tech event here. I proposed to showcase MDL in Pharo along with workshop. Let's see how it goes... Phil On Mon, Oct 3, 2016 at 4:43 PM, Offray Vladimir Luna Cárdenas <[hidden email]> wrote: Hi, |
This post was updated on .
In reply to this post by philippeback
CONTENTS DELETED
The author has deleted this message.
|
On Mon, Oct 3, 2016 at 6:47 PM, CodeDmitry <[hidden email]> wrote: LOL (in GrowlMorph): There are interesting things in there indeed. "Intention revealing" enough?
Actually this works for any Morph in 5.0 Morph>>#defer: aValuable "aValuable will be executed in the next UI rendering cycle" self owner ifNotNil: [ self owner defer: aValuable] ifNil: [ UIManager default defer: aValuable ] UIManager (MorphicUIManager) will do this at one point (track implementers 'til class side in WorldState) defer: aValuable "aValuable will be executed in the next UI rendering cycle" self addDeferredUIMessage: aValuable. This will stick it in a queue: deferredUIMessages ^DeferredUIMessages ifNil: [DeferredUIMessages := WaitfreeQueue new]. and then, there is interesting black magic going on runStepMethodsIn: aWorld "Perform periodic activity inbetween event cycles" | queue nextInQueue| "If available dispatch some deferred UI Message" queue := self class deferredUIMessages. [(nextInQueue := queue nextOrNil) isNil] "<<---------------- here all is happening -------" whileFalse: [ nextInQueue value]. self runLocalStepMethodsIn: aWorld. "<<------------ step methods -----------------" "The multi-threaded global Transcript needs to be updated periodically and synchronously with the UI." Transcript stepGlobal. "<<------------ and *this* is some black magic for Transcript ----" Fun thing: stepGlobal " The superclass method Model>>step indicates a convention that might be used to interoperate synchronously with the UI-thread. However when multiple Transcript windows are open, their PluggableTextMorphs share a single instance, from the global Transcript. To avoid potential trouble, this method should not be named #step. As well, we need this method to execute even when no Transcript windows are open, so the stream continues to be reset periodically, otherwise it would grow indefinitely. So this method is invoked from WorldState>>runStepMethodsIn:. " "Next three lines required temporarily to initialize instance variables added to existing instance" deferredClear ifNil: [ deferredClear := false ]. deferredEndEntry ifNil: [ deferredEndEntry := false ]. stepContents ifNil: [ stepContents := '' ]. deferredClear ifTrue: [ deferredClear := false. stepContents := ''. self changed: #clearText. ]. deferredEndEntry ifTrue: [ deferredEndEntry := false. self critical: [ stepContents := stream contents. stream resetContents. ]. self changed: #appendEntry. ]. Just in case one was wondering how Transcript clear actually works, check this: clear " Clear all characters by resetting the stream and voiding any previously flagged deferredEndEntry. Redisplays the view by signalling for #step to send #changed: . " self critical: [ deferredClear := true. "<------- magic! -------" deferredEndEntry := false. "<------- more magic!--------" stream reset ] Good luck to infer that from scratch. 2. "[Block] fork" is called immediatly, but on a new thread. Yeah, use forkNamed: aString if you actually want to track the thing easily in the Process Browser. 3. "<number> <time unit> wait" blocks the current thread for specific time Right.
I guess that all of this shows that there is some flexibility in Pharo async. Check the Generator class for some brain twisting with fork. Run Generator examplePrimes. for a start. Phil
|
Also, check MorphicUIManager>>#spawnNewProcess UIProcess := [ [World doOneCycle. Processor yield. false] whileFalse: []. ] newProcess priority: Processor userSchedulingPriority. UIProcess name: 'Morphic UI Process'. UIProcess resume digging into doOneCycle, you'll find: #doOneCycleFor: aWorld "Do one cycle of the interaction loop. This method is called repeatedly when the world is running. This is a moderately private method; a better alternative is usually either to wait for events or to check the state of things from #step methods." self interCyclePause: MinCycleLapse. self doOneCycleNowFor: aWorld. The interCyclePause is what make the UI timing alignment proper (notice serverMode) [and some Squeak remnant mention]: interCyclePause: milliSecs "delay enough that the previous cycle plus the amount of delay will equal milliSecs. If the cycle is already expensive, then no delay occurs. However, if the system is idly waiting for interaction from the user, the method will delay for a proportionally long time and cause the overall CPU usage of Squeak to be low. If self serverMode returns true then, always do a complete delay of 50ms, independant of my argument. This prevents the freezing problem described in Mantis #6581" | wait wait2 | "a very long assignment" wait := self serverMode ifTrue: [ 50 ] ifFalse: [ wait2 := (lastCycleTime notNil and: [CanSurrenderToOS ~~ false]) ifFalse: [ 0 ] ifTrue: [ lastCycleTime + milliSecs - Time millisecondClockValue ]. self flag: 'Issue 14754 - wait2>millisecs is only True for clock rollover. Remove it once DelayScheduler based on microsecondClock - Ben Coman 19.01.2015'. "<---- maybe we want this #flag: not to be called all the time " wait2 > milliSecs ifTrue: [ 0 ] ifFalse: [ wait2 ]. ]. wait > 0 ifTrue: [ (Delay forMilliseconds: wait) wait ]. "<------- wait is not #>>wait" lastCycleTime := Time millisecondClockValue. CanSurrenderToOS := true. Now, yeah, how do get stuff to be painted on the screen? Like this: displayWorld: aWorld submorphs: submorphs "Update this world's display." | deferredUpdateMode handsToDraw allDamage | submorphs do: [:m | m fullBounds]. "force re-layout if needed" self checkIfUpdateNeeded ifFalse: [^ self]. "display is already up-to-date" deferredUpdateMode := self doDeferredUpdatingFor: aWorld. deferredUpdateMode ifFalse: [self assuredCanvas]. canvas roundCornersOf: aWorld during:[ | worldDamageRects handDamageRects | worldDamageRects := self drawWorld: aWorld submorphs: submorphs invalidAreasOn: canvas. "repair world's damage on canvas" "self handsDo:[:h| h noticeDamageRects: worldDamageRects]." handsToDraw := self selectHandsToDrawForDamage: worldDamageRects. handDamageRects := handsToDraw collect: [:h | h savePatchFrom: canvas]. allDamage := worldDamageRects, handDamageRects. handsToDraw reverseDo: [:h | canvas fullDrawMorph: h]. "draw hands onto world canvas" ]. "*make this true to flash damaged areas for testing*" self class debugShowDamage ifTrue: [aWorld flashRects: allDamage color: Color black]. canvas finish. "quickly copy altered rects of canvas to Display:" deferredUpdateMode ifTrue: [self forceDamageToScreen: allDamage] ifFalse: [canvas showAt: aWorld viewBox origin invalidRects: allDamage]. handsToDraw do: [:h | h restoreSavedPatchOn: canvas]. "restore world canvas under hands" Display deferUpdates: false; forceDisplayUpdate. The VM will take care of throwing the bits to the display in various ways. Interesting to look how it is done for Windows, OSX, and Linux. So you have about a full view now. Timing wise, there is also some interaction with the VM occuring elsewhere. Pharo is still polling deep inside. epoll etc isn't there yet, hence the little idle CPU usage when doing nothing. Good luck doing this UI trip with other platforms, not to mention change or instrument it the way you like. Pharo is really cool for this as it helps in learning about a lot of things. Want to do sockets? Do the high level stuff in Pharo and dig in the VM to see how it is done down under for a set of platforms. Enjoy. Phil On Mon, Oct 3, 2016 at 8:02 PM, [hidden email] <[hidden email]> wrote:
|
This post was updated on .
In reply to this post by philippeback
CONTENTS DELETED
The author has deleted this message.
|
Free forum by Nabble | Edit this page |