[size="5"]Intent
[bquote]Provide each Controller with a chance to execute once per game frame.[/bquote]
[size="5"]Problem
[bquote]Without a mini-kernel, Model objects are typically updated by a set of hard-wired controller functions called from the main loop. For example:
An operating-system-like method is needed where controllers can be created and removed dynamically as needed.[/bquote]
[size="5"]Solutionvoid updateWorld()
{
for( int i=0; i < numTanks; i++ )
{
if( tanks )
{
updateTankPhysics( tanks );
updateTankAI( tanks );
}
}
for( i=0; i < numSoldiers; i++ )
{
... etc ...
}
This style of updating requires that any new controller be hardwired into the update calls, which reduces encapsulation and increases maintenance.An operating-system-like method is needed where controllers can be created and removed dynamically as needed.[/bquote]
[bquote]A base controller class is created which is the super-class of all controllers. A list of controller pointers is maintained. Each game frame, the mini-kernel (called from the main loop) gives each controller a chance to execute by calling a virtual "update" method. This is a cooperative multi-tasking system. For example:
It is often necessary to ensure that some controllers always run before others. For example, user interface may need to run before animation or physics to ensure that mouse clicks are interpreted with respect to the correct frame of reference. This can implemented with a priority number for each controller; the mini-kernel either sorts the controller pointers once per frame by priority or ensures that the list remains in sorted order.
The mini-kernel may be implemented to handle some common controller bookkeeping. For example, the kernel might update a counter in each controller so that the controller can determine its age quickly. Or, the kernel might monitor per controller sleep fields to simplify timing much like the sleep() function in Unix or Win32.
Controllers are frequently "attached" to Model objects though some sort of dependency system. This dependency ensures that the controller is garbage collected along with the associated model when it dies. This may involve some cooperation on the part of the mini-kernel.[/bquote]
[size="5"]Structureclass BaseController {
virtual void update() = 0;
}
class MissileController : BaseController {
Model &missle, ?
virtual void update() {
missile.pos += missile.vel;
missile.vel += (target.pos - missile.pos).norm() * missAcc;
}
}
void miniKernelDoAllControllers() {
foreach controller in list { controller.update(); }
}
Note that all controllers update calls are non-blocking; they are expected to do some actions quickly and return control back to the mini-kernel.It is often necessary to ensure that some controllers always run before others. For example, user interface may need to run before animation or physics to ensure that mouse clicks are interpreted with respect to the correct frame of reference. This can implemented with a priority number for each controller; the mini-kernel either sorts the controller pointers once per frame by priority or ensures that the list remains in sorted order.
The mini-kernel may be implemented to handle some common controller bookkeeping. For example, the kernel might update a counter in each controller so that the controller can determine its age quickly. Or, the kernel might monitor per controller sleep fields to simplify timing much like the sleep() function in Unix or Win32.
Controllers are frequently "attached" to Model objects though some sort of dependency system. This dependency ensures that the controller is garbage collected along with the associated model when it dies. This may involve some cooperation on the part of the mini-kernel.[/bquote]
[bquote]Not available at this time.[/bquote]
[size="5"]Examples
[bquote]None at this time.[/bquote]
[size="5"]Issues and Risks
[bquote]None at this time.[/bquote]
[size="5"]Related Patterns
[bquote]Mini-kernels are aggregations of Controllers.[/bquote]
[size="5"]Uses and References
[bquote]Thanks to Tony Zurovec.[/bquote]