VR-Forces Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Getting and Setting 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 or sysdef files in the SMS. If state properties are defined in the OPE and multiple sysdefs used by the entity, these properties are all merged into a single set.

Note
It is important to ensure that you do not define multiple properties with the same name, as this may cause a conflict. Internal state properties support the concept of a "context" to help avoid name collisions. It is recommended that all sysdefs defining internal state properties use a unique context for their properties. This can be done by defining internal state properties within a DtRwContext block, as shown in the example.

The code examples in this section use the following state properties as they might be defined in an OPE file.

(external-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
)
)
(internal-state-data
(DtRwContext TestContext
(DtRwString TestString "another test")
(DtRwInt TestInt 456)
(DtRwInt TestReal 45.6)
)
)

Accessing State Properties

Accessing State Properties from the Sim Engine

For Other Sim Objects

When accessing state properties for other sim object (i.e. from outside of the local sim object and its own sim components), only the external state properties are accessible.

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

Because DtSimObject is a reference to a sim object that is accessible outside the object, there is no access to internal state properties. This allows you to view the state of external properties set by other entities.

// create a sim object facade for easier access
DtVrfSimulatedSimObjectFacade simObjFacade(simObject);
const DtRwProperties& externalStateProps = simObjFacade.stateProperties(); // all EXTERNAL state properties
const DtRwProperties& parameterProps = simObjFacade.parameterProperties(); // all parameter properties

For This Sim Object

A local sim object can access both internal and external state properties for both reading and writing. The easiest way to access a state property for a local sim object is through the stateProperty() utility functions from the DtLocalObject. These functions simply state property access without having to worry about where the property is stored (more on where state properties are stored below).

// This will return a pointer to either the matching next frame external state property or an internal state property.
DtPropertyInterface* property = localObject->stateProperty(propertyName);
// This will return a pointer to the matching internal state property. Only internal properties have contexts.
DtPropertyInterface* property = localObject->stateProperty(contextName, propertyName);

If you want to control specifically whether you access next frame or current frame data for an external property, or whether you access an external or internal property, then you must access these lists directly. (Please see Current Frame State and Next Frame State for more on next frame and current frame data.)

From a DtLocalObject, you can specifically access each of these property lists:

// Next frame external state properties
DtRwProperties& nextFrameStateProperties = localObject->nextFrameStateProperties();
// Current frame external state properties
DtRwProperties& currentFrameStateProperties = localObject->stateProperties();
// Internal state properties are found within the DtVrfObjectStateRepository (internal properties do not need to be double buffered, so do not have next and current frames)
DtRwProperties& allInternalProps = localObject->internalState()->internalStateProperties(); // all internal properties
DtRwProperties& contextProps = localObject->internalState()->internalStateProperties(contextName); // all internal properties within a specific context
Note
It is recommended that internal state properties always be defined in a context.

Usually state properties are defined in OPE or sysdef files within the SMS, but internal state properties can also be added in code. The easiest way to do this is with the addStateProperty() functions of the DtLocalObject.

// Adds a new state property with the given initial value and returns a pointer to it.
// initialValue can be an int, double, bool, DtString, or DtVector.
DtPropertyInterface* newProperty = localObject->addStateProperty(contextName, propertyName, initialValue);
// Adds an existing property to the list of properties, where property is a pointer to an existing property.
// Note that the local object then takes ownership of this pointer and will clean it up on deletion.
// This form should be used for complex property types like lists, maps, and structures.
bool wasAdded = localObject->addStateProperty(contextName, propertyName, property);

Accessing State Properties from the GUI

In the VR-Forces GUI you can access the external state properties from the DtGuiSimObject or DtSimObjectReference. Internal state properties are not accessible from the GUI (or any other remote applications).

const DtRwProperties& externalStateProps = simObject->stateProperties(); // all EXTERNAL state properties

Getting and Setting Property Values

Once you obtain your list of state or parameter properties as shown above, you can now lookup the values of individual properties. Properties come in many types. This section will show you how to access the values of different property types.

Remember, only a local sim object can access internal state properties or set any state properties. Access outside the local object is only for reading external state and parameter properties.

Simple Properties

Simple properties are those that use basic types like DtRwBoolean, DtRwReal, DtRwInt, or DtRwString. Once you have a DtRwProperties reference, 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 = stateProperties.findPropertyValue<int>(“TestInt”);
if (testIntVal)
{
int val = *testIntVal;
}

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

bool success = stateProperties.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:

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:

stateProperties.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 =
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 =
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 =
stateProperties.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 =
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 =
stateProperties.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.

Accessing Properties Through Lua

State and parameter properties are also accessible from Lua scripts. Please see the VR-Forces 5.1.1 Lua Function Documentation for more details on the available functions.

From SimObjects

All SimObjects support the getParameterProperty() and getStateProperty() functions (as well as additional functions for getting specific items in lists or maps). SimObject functions are accessible from the scripts running on any sim object, so these functions allow you to read the SimObject's external properties. They are not able to read any internal state properties.

From "this" Object

The "this" SimObject (the object on which the script is running) has access to the setStateProperty() function as well. Additionally, it has access to the getInternalStateProperty() and setInternalStateProperty() functions, as internal properties are only accessible from the object being simulated. These functions also support accessing internal state properties with a context, which is recommended to avoid name conflicts.

The getStateProperty() functions work for both internal and external state properties, however internal state properties are only available for the "this" object.


Document ID: Generated on Thu Oct 23 22:29:17 EDT 2025 from SVN revision 280951
Copyright © 2005-2024 MAK Technologies. All Rights Reserved (www.mak.com)