Maybe this could become some kind of pillar file...

But things are changing a lot these days with SDL2 etc.

Any roadmap of these somewhere?

Phil

On Sat, Oct 8, 2016 at 7:03 PM, stepharo <steph...@free.fr> wrote:

> Thibault
>
> you should talk also with Glenn and Alain to get feedback. They will visit
> us in Nov.
>
>
> Stef
>
>
> Le 7/10/16 à 15:14, Thibault Raffaillac a écrit :
>
>> Thanks for these mails, that's actually very helpful!
>> I am working on a shorter syntax for animations at the moment (than
>> GLMAnimation, Viva, Bloc-Animation), and could not find a proper equivalent
>> to requestAnimationFrame (i.e. that would be independent of any UI yet in
>> sync with display, and as simple as possible).
>> My solution was to repeatedly register to deferredUIMessages,
>> implementing an intermediate block to add a timestamp like
>> requestAnimationFrame (works wonders http://smalltalkhub.com/#!/~Th
>> ibaultRaffaillac/Animation)
>>
>> Cheers,
>> Thibault
>>
>> ps: I'll ask Guille asap for the state of ReactiveExtensions (lacks
>> comments)
>>
>> 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
>>>
>>
>>
>
>
>

Reply via email to