april  1.0.0
...
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Example 3 - Running a world

At any given time a world may be running or not. The world itself does not advances itself - it needs an external entity to call its advance() method. However, the world will refuse to do anything if it is not started. Various methods are only available in only one of the two states.

To start the world use:

if ( w->start() )

One can always tell if the world is running or not:

cout << "World is running: " << w->isRunning() << "\n";

Now the advance() method is available to use.

for ( int i = 0; i < 3; i++ )
{
w->advance();
cout << "Current time in the world is: " << w->currentTime() << "\n";
}

It updates the time in the world and sends signals to all internal components that they should do a a step. The time in a world is a simple 64-bit unsigned counter. It starts from 0 when the world is created and it ever increases with each step. There is no corespondence between the time defined like so and the real time on the running machine.

We can pause a world with

w->stop();

and start it again with the same start().

Advanced topic - The director

Internally, a World uses a Director to start, stop and advance it. When a World is started, if no director is set the default one is being used. It simply iterates the components of the World and advances them as described in previous section. However, this behaviour may be customised (maybe in a multithreading environment) by inheriting from default Director and reimplementing virtual functions.

First, the definition for the director is included with:

Then, a custom director class needs to be defined that inherits default Director class:

class CustomDirector : public Director {
CustomDirector( World * w ) : Director( w )
{
cout << "Custom director created;\n";
}

There are three methods to be implemented:

virtual bool start ( void )
{
cout << " - custom director starts the world;\n";
return true;
}
virtual void stop ( void )
{
cout << " - custom director stops the world;\n";
}

In this case start() and stop() only inform us about the call. start() may also return false to indicate that it can't start the World right now. Notice that World manages its status so we don't have to change it from Stopped to Running and the other way arround.

virtual void advance ( void )
{
cout << " - custom director advances the world;\n";
stepTime();
/* todo: advance components */
}

At the very minimum the advance() method must update the time. It should also advance other components in the world.

Now to go ahead and test this custom director we can use following code:

CustomDirector * cust_dir = new CustomDirector( w );
w->setDirector( cust_dir );
DEC_REF(cust_dir,cust_dir);
cout << "Custom director informs us about the action it takes:\n";
w->start();
w->advance();
w->stop();
w->setDirector( NULL ); // our director gets destroyed at this time
cout << "Default director does not informs us about the action it takes...\n";
w->start();
w->advance();
w->stop();
cout << "... so no output is shown:\n";

Notice that we release our reference to the custom director pretty early. This is because the World will take its own reference with the call to World::setDirector(). Same call will release the reference for previous director, if any. Passing NULL as the director discards current one and leaves nothing in its place. As previously stated, World::start() will create a new, default one.




Example 2 - Creating a world april-core library Example 4 - IDs