RFC: frame callbacks
Posted: Sat Jan 08, 2011 12:39 am
A while back, there were complaints that the limited granularity of JavaScript timers meant they couldn’t be use for detailed animations. At the time, I suggested it would be better to use a completely separate mechanism, since doing something every frame is conceptually distinct from regularly-occuring timers. I’ve now implemented about half of this idea, so it’s time for some feedback-seeking.
The callback timer API will consist of two methods. (I’m not sure where to put them; I don’t want to stick them on
Frame callback will be invoked once per frame, with the time difference since the last frame (in game real time seconds) as a parameter. I haven’t decided whether it will be called (with a delta of 0) while paused; this depends in part on how easy it is to hook it up properly. For minimum overhead, there will be no way to specify the “this” value of the callback (so hey, we have a use for
Frame callbacks will be invoked after all entity updates, but before drawing, which seems the sensible place for custom animation. (For historical reasons, timers and tickle events fire during the player’s updates, which occur before every other entity’s.)
To support one of the obvious cases for custom animation, we’ll provide a way to get a reference to the
As a minor note, since I just had to mess about with it, adding and removing frame callbacks from within a running frame callback will be possible, but somewhat inefficient, and changes will take effect in the next frame. (This last bit shouldn’t matter since order of execution will be undefined anyway.)
The callback timer API will consist of two methods. (I’m not sure where to put them; I don’t want to stick them on
Timer
, as that would confuse the distinction I’m trying to make, and making them global is a bit untidy.) addFrameCallback()
will take a function, and return a tracking ID. removeFrameCallback()
will take a tracking ID and remove the corresponding frame timer. (The nature of tracking IDs is unspecified; it’s just some value that you stash until you want to remove your frame callback.)Frame callback will be invoked once per frame, with the time difference since the last frame (in game real time seconds) as a parameter. I haven’t decided whether it will be called (with a delta of 0) while paused; this depends in part on how easy it is to hook it up properly. For minimum overhead, there will be no way to specify the “this” value of the callback (so hey, we have a use for
Function.prototype.bind()
already), but it will have access to the variables in its declaration scope as usual.Frame callbacks will be invoked after all entity updates, but before drawing, which seems the sensible place for custom animation. (For historical reasons, timers and tickle events fire during the player’s updates, which occur before every other entity’s.)
To support one of the obvious cases for custom animation, we’ll provide a way to get a reference to the
model
on a running mission screen. There are probably ways to mess this up horribly, but hey, Cabal_Common_Library already has a nasty hack to achieve this anyway.As a minor note, since I just had to mess about with it, adding and removing frame callbacks from within a running frame callback will be possible, but somewhat inefficient, and changes will take effect in the next frame. (This last bit shouldn’t matter since order of execution will be undefined anyway.)