<- C++ API Dynamic Updates using a Shared Object Callback ->

Dynamic Updates Using the API

In the previous section we discussed setting static values for defining the EphemersModel class behavior. An Ephemeris Model is not of much use unless it can update dynamically. We can effect updates through the API (discussed in this section), a shared object callback (discussed in the next section ), or through shared memory (discussed in the second section following).

In the C++ API, there are three methods for effecting updates, Automatic, Directly, or through a Callback.

Automatic Updates

Automatic updates is the default. In fact, no further action is required after initialization of the EphemerisModel class to put automatic updates into effect. The EphemersModel class will update its own data upon scene graph traversal and set heavenly body positions according to the current time as read from the computer's clock.

Direct Updates

The EphemersModel class has a pointer to a EphemerisData struct. This struct contains the latitude, longitude and altitude of the current eye position as well as the date and time in an internal DateTime struct. Direct updates are put into effect by updating these values in the main loop of the program. Let's say we write a function for updating the date and time from the computer's clock (redundant to simply using AutoDateTime, but provided here as an example.


    static void SetCurrentTime( osgEphemeris::EphemerisModel &ephem )
    {
        time_t seconds = time(0L);
        struct tm *_tm = localtime(&seconds);

        osgEphemeris::EphemerisData *data = ephem.getEphemerisData();

        data->dateTime.setYear( _tm->tm_year + 1900 ); // DateTime uses _actual_ year (not since 1900)
        data->dateTime.setMonth( _tm->tm_mon + 1 );    // DateTime numbers months from 1 to 12, not 0 to 11
        data->dateTime.setDayOfMonth( _tm->tm_mday + 1 ); // DateTime numbers days from 1 to 31, not 0 to 30
        data->dateTime.setHour( _tm->tm_hour );
        data->dateTime.setMinute( _tm->tm_min );
        data->dateTime.setSecond( _tm->tm_sec );
    }
    

And now we simply place a call to this function in the main loop, just after viewer.sync().


    while( !viewer.done() )
    {
        viewer.sync();
        viewer.update();
        viewer.frame();
    }
    

Updates with a Callback

In some cases and by some preferences, we may not have access to the main loop, or we may prefer simply not to clutter up the main loop with extraneous calls for updates. In this case we can use an EphemerisUpdateCallback. This callback is a C++ class, derived from osgEphemeris::EphemerisUpdateCallback.

The above example, which updates the EphemersData to the current time, can be implemented with the following class.


    class EphemerisDataUpdateCallback : public osgEphemeris::EphemerisUpdateCallback
    {
        public:
            EphemerisDataUpdateCallback(): EphemerisUpdateCallback( "EphemerisDataUpdateCallback" )
            {}
    
            void operator()( osgEphemeris::EphemerisData *data )
            {
                time_t seconds = time(0L);
                struct tm *_tm = localtime(&seconds);
    
                 data->dateTime.setYear( _tm->tm_year + 1900 ); // DateTime uses _actual_ year (not since 1900)
                 data->dateTime.setMonth( _tm->tm_mon + 1 ); // DateTime numbers months from 1 to 12, not 0 to 11
                 data->dateTime.setDayOfMonth( _tm->tm_mday + 1 ); // DateTime numbers days from 1 to 31, not 0 to 30
                 data->dateTime.setHour( _tm->tm_hour );
                 data->dateTime.setMinute( _tm->tm_min );
                 data->dateTime.setSecond( _tm->tm_sec );
            }
    };
    

Note that the constructor passes a string to the super class. This has little meaning in this context, but will be better understood upon reading the next section.

We now tell the EphemersModel class about the callback:


    ephemerisModel->setEphemerisUpdateCallback( new EphemerisDataUpdateCallback );
    

Note again, that these examples simply make redundant what the AutoDateTime function does, but you may want to do something different and interesting in your callback. Note that you can also change Latitude, Longitude, and Altitude in the EphemerisData struct.


<- C++ API Dynamic Updates using a Shared Object Callback ->