The makVrf::DtVrfStateViewCollectionManager is the class that contains a collection of all the state data collected from the network thread and sent to the visualization thread.
All the data in these structures are stored in the makVrv::DtDataBank (referenced from the makVrv:DtDe) in the makVrv::DtSimData simData() member. This data contains a series of makVrv::DtSimEntry classes, one for each object in the simulation. Each makVrv::DtSimEntry class contains a simStates() vector. This vector contains a set of data (for example, makVrv::DtVrlinkSimulatedEntityState) for each kind of data for that object. Rather than each object containing one big class that stores all the possible data, each entry will have one sim state of data for each kind of data defined (IFF Data, Sensor Data, Laser Designator Data, etc). The Add State Component GUI example shows how to add one particular kind of new state entry data to an object. You can access this data in multiple ways:
-
Through the makVrv::DtDe dataBank().simData() member. The makVrv::DtSimData singleton contains all the network represented data in the system. Each makVrv::DtSimEntry contains a vector of all makVrv::DtSimState subclasses available to the specific object.
-
By creating a makVrv::DtStateViewCollection around the type of data you want to find. When you create a state view collection, it will iterate over all sim data and see which sim data has entries of the type of the data you want: The collection will now be populated with any states that can be dynamically casted to DtVrlinkSimulatedEntityState. This will include any subclasses of that class as well.
The third way is the way is the makVrf::DtVrfStateViewCollectionManager. This singleton is a single entry point for all the differnt types of data in the system. You can use this class to find data by marking text, DtUUID or by the objects element id. You can use this class to find a particular makVrv::DtStateView:
DtVrfStateViewCollectionManager::instance(myLogic->de()).
objectDataStateViewCollection()->findStateView(state->id());
if (objDataView)
{
boost::optional<int> numHits =
objDataView->
state().myStateProperties.findPropertyValue<
int>(
"TargetsHit");
if (numHits)
{
return QString::number(*numHits);
}
}
myLasingStateView = const_cast<DtStateView<DtLaserDesignatorState>*>(
DtVrfStateViewCollectionManager::instance(myDe).laserDesignatorStateViewCollection()->findStateView(myState->id()));
Update Rate
It is important to not that data is sent from the network thread to the main thread via a makVrv::DtAgent subclass. Since this is processed by the main thread, data is not updated on every change for every object. This would cause the main thread (especially in large simulations) to do a large amount of processing, stalling out the application. To get around this, data is refreshed in the main thread either at an update rate or by a force of an update. Both operations are performed on the makVrv::DtStateView representation of the object. The following is an example of forcing an update of a state view for a particular object, and, then getting notified when the state view is updated in the main thread from the network:
DtVrfStateViewCollectionManager& svcMgr = DtVrfStateViewCollectionManager::instance( myDe );
DtUniqueID shapeSimEntryId = svcMgr.simIdFromDisplayId(sceneId);
DtSimEntry* shapeSimEntry = myDe.dataBank().simData().findSimEntry(
shapeSimEntryId );
DtVrfStateViewCollectionManager::instance(myDe).environmentStateViewCollection()->findStateView( shapeSimEntryId ) );
svcMgr.setUpdateRate(shapeSimEntry, DtSimEntryUpdater::At4Hz, stateView );
stateView->signal_stateViewUpdated.connect(
boost::bind( &DtVrfObjectManipulationManager::slot_stateReturned,
this, _1, sceneId, processor ) );
const DtUniqueID& sceneId, ProcessEnvStateFunction* processor )
{
DtVrfStateViewCollectionManager& svcMgr = DtVrfStateViewCollectionManager::instance( myDe );
DtUniqueID shapeSimEntryId = svcMgr.simIdFromDisplayId(sceneId);
DtSimEntry* shapeEntry = myDe.dataBank().simData().findSimEntry( shapeSimEntryId );
shapeStateView->signal_stateViewUpdated.disconnect(
boost::bind( &DtVrfObjectManipulationManager::slot_stateReturned,
this, _1, sceneId, processor ) );
svcMgr.setUpdateRate(shapeEntry, DtSimEntryUpdater::NoUpdates, shapeStateView );
This example shows a few things
-
Finding a state view
DtSimEntry* shapeSimEntry = myDe.dataBank().simData().findSimEntry(
shapeSimEntryId );
DtVrfStateViewCollectionManager::instance(myDe).environmentStateViewCollection()->findStateView( shapeSimEntryId ) );
-
Forcing an update on that state view Note that is is also valid to do
stateView->forceUpdate();
-
Setting an update rate on the state view
svcMgr.setUpdateRate(shapeSimEntry, DtSimEntryUpdater::At4Hz, stateView );
Note that is is also valid to do stateView->setUpdateRate(DtSimEntryUpdater::At4Hz);
-
Connecting for notification when the state view is updated
stateView->signal_stateViewUpdated.connect(
boost::bind( &DtVrfObjectManipulationManager::slot_stateReturned,
this, _1, sceneId, processor ) );
- Attention
- When a state view is updated all connections to that state view for update will be triggered. Also, there is only a single update rate kept per state view, so, the last class to set an update rate on a state view will set the update rate for that view. So, if you set an update rate to 1Hz, but are not getting an update rate at 1Hz, this means some other class also set an update rate on that state view to be different.