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 >>> >> >> > > >