15.9. An Example

This section shows an example of an application skeleton for a client node. We will not show a skeleton for a server node here as most of its complexity relates to startup archive creation. For more information see the Massiv Core Reference Guide or the relevant part of the source codes of the Demo.

[Note]Note

To create an initial archive, initialize the Core as usually and download the prerequisite data. Do not connect to the simulation as that would restore the latest saved state (if there is any) or fail otherwise. Create global objects (initial simulation state), save the archive and shutdown the Core. Often only the first server creates the global objects, the remaining servers create empty archives instead.

#include "class_list.h"
...
std::string login;
bool        quit;
...
void create_node_object_callback()
    {
    CreateObject< ClientNode >();  1
    }
...
void next_tick_callback()  2
    {
    switch( System::get_phase() )  3
        {
        case System::PHASE_DATA_DOWNLOADED:
            ...
            /* Handle a login dialog. */
            ...
            if( enter_hit )
              {
              login = ...;
              System::request_quit();
              }
            if( escape_hit )
              {
              quit = true;
              }
            break;
        case System::PHASE_RUNNING:
            ...
            /* Draw world. */
            ...
            if( escape_hit )
              {
              System::request_quit();
              }
            break;
        }
    }
...
int main( int argc, char * argv[] )
    {
    std::istringstream config;
    ...
    System::initialize
        (
        System::StartUpInfo
            (
            NodeId::TYPE_CLIENT,
            "massiv.conf",
            Massiv::Generated::register_classes,
            create_node_object_callback,
            next_tick_callback
            )
        );
    ...
    try
        {
        System::download_data();

        while( !quit )
            {
            System::generic_loop(); 4

            try
                {
                config.str( login );
                System::connect( config );
                System::run();
                System::disconnect();
                }
            catch( Exception & )
                {
                ...
                Handle exceptions here
                ...
                }
            }
        }
    catch( Exception & )
        {
        ...
        Handle exceptions here
        ...
        }
    ...
    System::shutdown();
    }

1

For information about how a node object should be implemented refer to Section 14.2, “Node Object”

2

Note that no cycle is needed in the next tick callback, because it is being called periodically.

3

This is how the current system phase can be determined. It also gives an information about what system loop is running.

4

Entering a generic loop in this state (PHASE_DATA_DOWNLOADED) ensures that a login dialog will be displayed and handled. When a user supplies his credentials, the loop is cancelled and the credentials are passed to System::connect().