[plt-scheme] FrTime implementation

From: Dave Griffiths (dave at pawfal.org)
Date: Sun Dec 9 05:57:21 EST 2007

On Sat, 2007-12-08 at 22:52 -0500, Gregory Cooper wrote:
> Hi Dave,
> 
> It looks like you have the right idea.  :-)
> 
> Are you running a pre-v371 version of DrScheme / FrTime?  (From the
> code and description you give, it sounds like you are...)  I ask
> because around July I changed the way FrTime deals with lists and
> other data structures, and this change makes it a bit more complicated
> to lift over data structures containing behaviors.
> 
> In pre-v371, all data constructors (including "cons") are lifted, so
> any reactivity inside a data structure spreads to the structure
> itself.  When you lift a procedure over a reactive structure, the
> procedure gets called repeatedly with snapshots of the structure
> (computed each time anything inside the structure changes).  This is
> why the second (make-torus ...) gets redrawn every millisecond, even
> though it only changes once a second: draw-list processes the entire
> list whenever anything inside it changes.
> 
> In v371 and later, data constructors are not lifted, so behaviors can
> hide inside structures.  In order to lift over such structures, you'll
> first need to use "raise-reactivity" to make the reactivity spread to
> the top of the structure, or use "compound-lift" (like the new
> animation.ss does), which lets your procedure find the reactivity
> while traversing the structure.  (This avoids the work of constructing
> a deep snapshot each time something changes.)  If you decide to
> upgrade to v371 at some point, let me know and I'll be happy to help
> explain this.

That makes sense. I'm running 370 - time to upgrade :)

> A couple of small comments: I'm surprised that you don't have code to
> clear the buffer before rendering the list of shapes, like
> animation.ss does.

This is the nub of the problem for me really ;)

When running in drscheme, the render loop is running in a different
(plt) thread. 

This is due to the way fluxus works - you don't drive the render loop
yourself, but you can optionally hook into it to get a function called
by the engine every frame to animate/update things. (using frtime even
this wont be needed)

This is a Good Thing - the framerate can be detached from the script
update (you can always interactively move the camera around with the
mouse etc) 

The problem with this naive frtime script is that the primitives strobe
as they are drawing once per millisecond, rather than once per frame.
This is fixed by using retained mode primitives (rather than the
immediate mode (draw-*) ones it uses at the moment), which are
maintained inside the render engine and rendered every frame for you,
optimised for speed. then frtime can just update them whenever it wants
to.

This has implications to how I implement the frtime interface - I'll
need to do some work to make this stateful (for reasons of speed)
situation appear stateless. 

One option is to require the 'user' to name each object, so the frtime
implementation can infer some historical information - first time it
appears build it, other times update it, when it doesn't appear in the
list delete it. 

How does animation.ss cope with this? If a shape only updates once a
second, how does it get redrawn when other things are updating more
quickly?

> Also, I'm not sure why you don't just write:
> 
>   (define clock milliseconds)

Ah, I was just playing with changing it, but left it as * 1 :)

cheers,

dave



Posted on the users mailing list.