VR-Forces 5.0.3 Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Getting and Setting User-Created State Property Values

Table of Contents

This section explains how to retrieve state property data from a C++ plugin to the VRF simulation engine.

The state properties that are available to an object are defined in its OPE file in the SMS. The code examples in this section use the following state properties as they might be defined in an OPE file.

(state-data
(DtRwString TestString "testing123" publish)
(DtRwInt TestInt 123 publish)
(DtRwReal TestReal 1.23 publish)
(DtRwStructure TestStruct
(DtRwString Type "some type")
(DtRwInt Count 123)
publish
)
(DtRwList TestList
("item1") ;; This definition adds 3 default items
("item2")
("item3")
publish
)
(DtRwMap TestMapA DtRwInt ;; A simple map type
(DtRwReal ItemValue)
)
(DtRwMap TestMapB DtRwString ;; A more complex map type
(DtRwStructure Item
(DtRwString ItemName)
(DtRwReal ItemAmount)
)
publish
)
(DtRwFixedArray TestFixedArray 3 ;; A fixed array of integers with exactly 3 items
(DtRwInt Val)
(42)
(11)
(26)
Publish
)
)

In the VR-Forces simulation engine, each object stores its properties in its DtStatePropertiesStateComponent. For easier access you can use the DtVrfSimulatedSimObjectFacade on any DtSimObjectReference or DtSimObject*.

\\ create a sim object facade for easier access
DtVrfSimulatedSimObjectFacade simObjFacade(entity);
const DtRwProperties& stateProps = simObjFacade.stateProperties();
const DtRwProperties& paramProps = simObjFacade.parameterProperties();

If you have a DtLocalObject, you can access the current state properties and next frame state properties directly from the local object.

\\ access current state properties for reading
const DtRwProperties& currentStateProperties = localObject->stateProperties();
\\ access next frame state properties for writing
DtRwProperties& nextFrameStateProperties = localObject->nextFrameStateProperties();

In the VR-Forces GUI you can access the state properties from the object state. This is the DtVrfObjectDataState for entities, the DtVrlinkSimulatedAggregateState for aggregates, and DtVrlinkSimulatedEnvironmentProcess for environmental processes and tactical graphics. If you have the DtSimEntry for an entity, you can look up its state properties as follows.

DtVrfObjectDataState* objectState = findStateFor<DtVrfObjectDataState*>(entry);
if (objectState)
{
DtRwProperties& stateProps = objectState->myStateProperties;
}

Simple Properties

Simple properties are those that use basic types like DtRwBoolean, DtRwReal, DtRwInt, or DtRwString. To get the value of a simple property, use the findPropertyValue() function. This is a template function that returns a boost::optional. A boost::optional wraps the value in a data type that allows you to test if a value has been set. If the property could not be found or converted to the specified type, then the boost::optional will have a value of false.

boost::optional<int> testIntVal =
simObjFacade.stateProperties().findPropertyValue<int>(“TestInt”);
if (testIntVal)
{
int val = *testIntVal;
}

To immediately set the value of a simple state property in the next frame, use the findAndSetPropertyValue() template function. It returns true if it is successful.

bool success = localObject->nextFrameStateProperties().findAndSetPropertyValue<int>(
“TestInt”, newValue);

Structure Properties

Properties can be structures consisting of multiple fields. Each field is itself a property, so fields can be simple types, structures, lists, or maps. Property structures are implemented using the DtRwPropertiesStructure class. DtRwProperties also has a function that finds and returns the specific ReaderWriter property class for any property rather than just the value. You can use it to find the DtRwPropertiesStructure object instance for the structure. Then each field in the structure can be accessed using findFieldValue() or findAndSetFieldValue().

To look up current values in a state property structure:

simObjFacade.stateProperties().findProperty<DtRwPropertiesStructure>(
"TestStruct");
if (propStruct)
{
// Lookup current values
boost::optional<DtString> oldType =
propStruct->findFieldValue<DtString>(“Type”);
boost::optional<int> oldCount =
propStruct->findFieldValue<int>("Count");
}

To set values in the next frame of a state property structure:

localObject->nextFrameStateProperties().findProperty<DtRwPropertiesStructure>(
"TestStruct");
if (propStruct)
{
// Set new values
propStruct->findAndSetFieldValue<DtString>(“Type”, newType);
propStruct->findAndSetFieldValue<int>(“Count”, newCount);
}

It is also possible to directly access fields within a property using findPropertyValue() and findAndSetPropertyValue(). To specify a field within a structure, use the format <PropertyName>.<FieldName> in place of the property name in the function call. This way if you are only interested in a single field, not the entire structure, you don't need to take the additional step of first finding the structure.

boost::optional<int> testStructCount =
simObjFacade.stateProperties().findPropertyValue<int>(“TestStruct.Count”);

List Properties

Properties can be lists. Each item in a list must have the same type. The item type can be a simple property type, a structure, or another list or map. The list maintains a prototype item that identifies the type of its items. It will not allow any new items to be added that do not match this prototype. Property lists are implemented using the DtRwPropertiesList class. This class has additional functions that can help in navigating lists and accessing their items.

Lists have iterators that function in a similar fashion to the iterators used in C++ STL containers. Each iterator allows access to the underlying DtPropertyInterface, which is the interface class from which all property classes are derived. You can extract the value from a DtPropertyInterface using the propertValue() template function.

const DtRwPropertiesList* testList =
simObjFacade.stateProperties().findProperty<DtRwPropertiesList>("TestList");
if(testList)
{
for (; iter != testList->end(); ++iter)
{
boost::optional<DtString> itemVal = iter->propertyValue<DtString>();
if (itemVal)
{
DtWarn << “Item value: “ << *itemVal;
}
}
}

To add a new item to a list you can use the addItem() function. This function comes in two forms. The first takes a DtPropertyInterface*, though the item this pointer points to must be of the same type as the list’s prototype. The second form returns a DtPropertyInterface* that points to a new item of the same type as the prototype.

DtRwPropertiesList* testList =
localObject->nextFrameStateProperties().findProperty<DtRwPropertiesList>("TestList");
if (testList)
{
// Add existing property as an item to the list
DtRwPropertyString* newItemA = new DtRwPropertyString(“newItemA”, “value A”);
bool success = testList->addItem(newItemA);
// Add a new property as an item to the list
DtPropertyInterface* newItemB = testList->addItem();
newItemB->setPropertyValue<DtString>(“value B”);
}

You can also remove properties from the list with the erase() function.

testList->erase(newItemB);

Map Properties

A map property is a specialized type of list property that can be indexed by a key. Map keys must be some type of integer, real, or string. Property maps are implemented using the DtRwPropertiesMap class. This class has iterators just as the list does, but it also adds additional functions that allow you to easily access items by their key value.

If you want to look up a specific item in a map by the key, you can use findItem() or findItemValue().

const DtRwPropertiesMap* testMapA =
simObjFacade.stateProperties().findProperty<DtRwPropertiesMap>("TestMapA");
if (testMapA)
{
const DtPropertyInterface* item = testMapA->findItem(7);
boost::optional<double> itemVal = testMapA->findItemValue<double>(3);
}

You can add new items using either insert() or addItem(). Use insert() to add a previously created item. This item must have the same type as the map prototype item. Use addItem() to have the map create a new item of the same type as its prototype.

DtRwPropertiesList* testMapA =
localObject->nextFrameStateProperties().findProperty<DtRwPropertiesMap>("TestMapA");
if (testMapA)
{
DtRwPropertyReal* newRealItem = new DtRwPropertyReal(“”, 45.6);
testMapA->insert(23, newRealItem);
DtPropertyInterface* newItem = testMapA->addItem(50);
newItem->setPropertyValue<double>(12.34);
}

Maps also allow you to erase items by their key.

testMapA->erase(3);

A map allows you to use the operator[] to access an item by its key. This returns a reference to the item’s DtPropertyInterface. If the item does not exist, a new one is added.

(*testMapA)[8].setPropertyValue<double>(89.1);

Fixed Array Properties

A fixed array property is a specialized type of list property that has a fixed size and cannot be grown or shrunk. Property fixed arrays are implemented using the DtRwPropertiesFixedArray class. This class makes use of the same iterators as the list property.


Document ID: Generated on Thu Jun 1 17:58:13 EDT 2023 from SVN revision 255404
Copyright © 2005-2021 MAK Technologies. All Rights Reserved (www.mak.com)