TickableObjectsAndITickable

From TDN

Tickable objects recieve updates based on a fixed tick rate. Every tickable object is assured one update per 32ms (by default). This does not mean that every 32ms an object is assured a tick, as circumstances such as large amounts of processing per frame could cause a situation where an object would get a tick at time T, and not get another one until T + 64, however at T + 64 the object would get two ticks, fufilling the guarantee of one update per 32ms.

Contents

Making an object Tickable

All that is required to make an object tickable is to inherit from ITickable. ITickable is designed to be used in multiple-inheritance situations and is very lightweight. There are other specialized classes which implement ITickable, such as GuiTickCtrl and (ADD TICKABLE SIM GROUP HERE -pw) that serve more specific purposes. For the sake of example, this is how to make a Tickable SimObject:

class FooClass : public SimObject, public virtual ITickable
{
   // You still mark SimObject as Parent
  typedef SimObject Parent;

private:
   ...

protected:
   // These three methods are the interface for ITickable
   virtual void interpolateTick( F32 delta );
   virtual void processTick();
   virtual void advanceTime( F32 timeDelta );

public:
   ...
};
Note the methods that are required to make an object implement the ITickable interface, ITickable is a pure virtual class, and so this means that these methods must have at least a stub. Note also that in a multiple inheritance situation like this, the typedef should *not* be set to ITickable but to the proper base class; ITickable is just an interface. Proper inheretance from ITickable also requires the
public virtual
otherwise proper behavior is not guaranteed.

The ITickable Interface

The ITickable interface consists of three methods

processTick

processTick is the method which is called each tick (on both client and server) if the object's isProcessingTicks returns true. By default, the return value of ITickable::isProcessingTicks is the value of ITickable::mTickable (which is set via the public accessor ITickable::setProcessTick). All processing which you need done at a consistant rate should be done in this method.

interpolateTick

This method is called every frame (on client) if the return value of isProcessingTicks is true it allows the Tickable object to do interpolation between ticks. It has an argument which is a 32-bit floating point value which represents the amount of time until the next tick, expressed as a percentage. This delta time parameter is expressed as:

  delta time = time until next tick / total time per tick

therefore the delta time approaches zero as the simulation moves closer to the next tick.

advanceTime

Every frame an ITickable object will recieve advanceTime methods regardless of the return value of isProcessingTicks. This method has a 32-bit floating point value which is the amount of time, in seconds, since the last call to advanceTime. advanceTime() is called on client for each frame,treat dt = 1/ fps Keep in mind that 'dt' in interpolateTick() and 'dt' in advanceTime() is not the same. advanceTime is used to update client(or server) side animations, particle emissions, etc..

A Case Study

GuiTickCtrl is a subclass of GuiControl which implements the ITickable interface. The purpose of this class was actually to act as a parent class for a test control for the code that became the GuiEffectCanvas control.

Why ITickable

I chose to make this control run on a constant tick rate because I was working with VectorField distortion effects. Normally, in iTunes visualizer or whatever, the effects run as fast as they can IE the framerate. The problem with this is that it is unpredictable how fast the users computer will run this effect. This is not a problem for something like iTunes, however for the application I had in mind, it was critical that the developer know at what rate that the consumer would see the effect distort so that it could determine when the effect was done running to finish the screen transition. In this case, having an effect run at a consistant and reproduceable rate, was critical to the functionality of the GuiControl.

--Pat Wilson 17:41, 17 Jun 2005 (CDT)