Using Snapshots API

From SIMboxWiki
Jump to navigation Jump to search

Introduction

The simulation Snapshots Manager lets you save simulation data as a snapshot at a point in time. A saved snapshot can be loaded later. The state of an entity is the sum of the state of its object components. In order to save the state of the entity we must save the state of each object component making up the entity. The object component might have internal data that is not exposed in attributes and might have special logic required for resuming its state. Therefore, each object component must handle the saving and loading of its state if it is to be saved as a snapshot and resumed later.

Same as entities, the global state of the session is the sum of state of the extensions. An extension whose state should be saved in a snapshot must handle the saving and loading its state.

The Snapshots API provides interface for storing the state of a component in specific point in time when the snapshot is being saved and provides interface for retrieving the data stored for a specific snapshot when the snapshot is being loaded.

When a snapshot save is requested, an event is published that notifies the components to save their state and components may use the Snapshots API to save their data. At the end of the saving process the snapshot data is serialized to the file system. The SMG_SnapshotsManager extension is responsible for handling snapshot save/load requests and notifies other components using this event to save or load their state.

When the snapshot load is requested, data from the requested snapshot is loaded. An event is published that notifies components to load their state and components may use the Snapshots API to load stored data and resume their state.

At the end of save/load snapshot process an appropriate event is published to notify that the save/load snapshot is completed.
Snapshot9.png

This document describes how to use the Snapshots API to save and load snapshot data for the developed components.

Supported Scenario

The current snapshot infrastructure may be used with static objects and only to define the default snapshot that will be loaded on session start. Future versions will include a more complete and comprehensive capability.

Development

The following events are used in Snapshots mechanism:

  • SaveSnapshot – Request snapshot save
  • LoadSnapshot – Request snapshot load
  • SaveSnapshotData – Published to notify components to store their state to a snapshot
  • LoadSnapshotData – Published to notify components to resume their state from a snapshot
  • SnapshotSaved - Published to notify that snapshot save is completed
  • SnapshotLoaded - Published to notify that snapshot load is completed


The Snapshots API provides an interface for saving and loading the following:

  • Data types:
    • Integer
    • Float
    • Double
    • Boolean
    • LinearVec
    • AngularVec
    • String
  • Entity attributes – can be saved or loaded by name or by index; attribute2 can be saved or loaded by a specific key\index or for all keys\indexes
  • Global attributes – can be saved or loaded by name or by index; attribute2 can be saved or loaded by a specific key\index or for all keys\indexes


To use the Snapshots API you will need to include the api.Snapshots.h header in your .cpp file.

The Snapshots API is as follows:

bool SaveItem (const LogicComponent * i_Component, const std::string & i_ItemName, const <item_type> & i_ItemValue);
bool LoadItem (const LogicComponent * i_Component, const std::string & i_ItemName, <item_type> & i_ItemValue);
bool SaveItem (const PluginInterface* i_Component, const std::string & i_ItemName, const <item_type> & i_ItemValue);
bool LoadItem (const PluginInterface* i_Component, const std::string & i_ItemName, <item_type> & i_ItemValue);
bool SaveGlobalAttribute(const std::string & i_AttributeName);
bool SaveEntityAttribute (const std::string & i_EntityName, const std::string & i_AttributeName);

All API functions have Unicode and ANSI representation. For example, these are the API functions that save global attribute value:

Static bool SaveGlobalAttributeA(const std::string & i_AttributeName);
Static bool SaveGlobalAttributeW(const std::wstring & i_AttributeName);

You can use each one of them according to your needs. You can also use the SaveGlobalAttribute function and pass strings as parameters using _T() macro. Calling SaveGlobalAttribute will eventually call one of the above functions according of your project settings. See the Unicode WIKI article for more information about strings in SIMbox SDK.
All API functions have a return value; use it when necessary to validate the returned value. If a load-snapshot request fails the return parameter passed will not be assigned and function will return false.

Saving Snapshot

In order to save snapshot you have to register a callback function to the SaveSnapshotData event. Saving snapshot data is done in the event callback.

#include "api.Snapshots.h"

bool MyComponent::init()
{
 …

 //{{PLUGIN_REGISTER_GLOBALEVENT
 m_EventIdSaveSnapshotData = SimApi::EventHandler::registerListener(_T("SaveSnapshotData"),
 EVENT_CALLBACK(this, & MyComponent::CBFuncGlobalEventSaveSnapshotData, MyComponent));
 //}}PLUGIN_REGISTER_GLOBALEVENT

 return true;
}
void MyComponent::CBFuncGlobalEventSaveSnapshotData( const SimApi::EventParams* i_Param )
{
 //saving internal data
 SimApi::Snapshots::SaveItem(this, _T("Item1"), 5);
 SimApi::Snapshots::SaveItem(this, _T("Item2"), true);
 AngularVec attAngAcceleration = AngularVec(Ang(Deg(100)),Ang(Deg(50)),Ang(Deg(0.5)));
 SimApi::Snapshots::SaveItem(this, _T("Item3"), attAngAcceleration);


 //saving attributes
 //saving entity attribute by name
 SimApi::Snapshots::SaveEntityAttribute(_T("Cessna176 1"), _T("ATT_DISPLAY_NAME"));
 //saving entity attribute by index
 SimApi::Snapshots::SaveEntityAttribute(_T("Cessna176 1"),
 EntityWorld::ATT_UNIQUE_ID);
 //saving attribute2 with integer key
 SimApi::Snapshots::SaveEntityAttribute2(_T("Cessna176 1"),
 _T("GLOBAL_ATT_SNAPSHOT_2_INT_INT"), 0);
 //saving attribute2 for all keys (integer)
 SimApi::Snapshots::SaveEntityAttribute2(_T("Cessna176 1"),
 _T("GLOBAL_ATT_SNAPSHOT_2_INT_INT"), SimApi::Snapshots::SP_ATT2_ALL_KEYS);
 //saving attribute2 for all keys (string)
 SimApi::Snapshots::SaveEntityAttribute2(_T("Cessna176 1"),
 _T("GLOBAL_ATT_SNAPSHOT_2_STRING_INT"), SimApi::Snapshots::SP_ATT2_ALL_KEYS); 
}


Loading Snapshot

In order to load snapshot you have to register a callback function to the LoadSnapshotData event. Loading snapshot data previously saved is done in the event callback.

#include "api.Snapshots.h"

bool MyComponent::init()
{
 …

 //{{PLUGIN_REGISTER_GLOBALEVENT
 m_EventIdSaveSnapshotData = SimApi::EventHandler::registerListener(_T("SaveSnapshotData"),
 EVENT_CALLBACK(this, & MyComponent::CBFuncGlobalEventSaveSnapshotData, MyComponent));
 m_EventIdLoadSnapshotData = SimApi::EventHandler::registerListener(_T("LoadSnapshotData"),
 EVENT_CALLBACK(this, & MyComponent::CBFuncGlobalEventLoadSnapshotData, MyComponent));
 //}}PLUGIN_REGISTER_GLOBALEVENT

 return true;
}

void MyComponent::CBFuncGlobalEventLoadSnapshotData( const SimApi::EventParams* i_Param )
{

 //loading internal data
 int item1 = 0;
 SimApi::Snapshots::LoadItem(this, _T("Item1"), item1);
 bool item2 = false;
 SimApi::Snapshots::LoadItem(this, _T("Item2"), item2);
 AngularVec attAngAcceleration;
 SimApi::Snapshots::LoadItem(this, _T("Item3"), attAngAcceleration);


 //loading attributes
 //Saved attributes are loaded automatically

 
}

 

System Configuration

In order to run session using Snapshots API, you will need to add the snapshot manager extension to the running configuration. You may do so by creating a custom extension collection and adding it in the machine or session level.
In SIMbox Toolkit, create an extension collection called Snapshots and add the SMG_SnapshotsManager extension to Snapshots extension collection.
In the LMS, add the Snapshots extension collection to the Launch Parameters of the following configurations:

  • GO
  • Scenario Editor