The Add State Property example demonstrates the following:
- How to add custom state properties to entities that can be used locally and published to the network
- How to add a callback function for the receipt of a interaction message
- How to write a front-end example that works in conjunction with a back-end example
Adding New State Properties
The Add State Property example shows how to add new state properties to entities and how to update them in your code and Lua scripts. To add a new state property, you must first define it in the OPE file used by your entity. This example uses an example SMS called addStateProperty which can be found in data. This SMS includes a new OPE file called HumanWithAccuracyStats.ope. At the bottom of the file is defined the following:
(state-data
(DtRwInt TargetsMissed 0 publish)
(DtRwInt TargetsHit 0 publish)
)
The state-data section defines the state properties which will be added to entities of this type. You can also add a parameter-data section to define parameter properties. The only difference between state and parameter properties is that parameter properties have static values whereas the values of state properties can change dynamically at run time.
There are four parts to the state property definitions:
- The first part is the data type, which must be one of the standard VR-Forces ReaderWriter types. In this example, both properties have a type of DtRwInt.
- The second part is the name of the property.
- The third part is the default value. This could also be a variable reference by using the $ as is done elsewhere in the OPE file.
- The fourth part is optional and indicates if this is a property that should be published. If absent, the property will not be published.
To publish a property in DIS, you must be using the IEEE 1278.1-2012 version of the standard (DIS 7). State properties will be published as special Attribute records attached to the entity.
To publish a property in HLA, there must also be an object class attribute with the same name defined in your FOM. If the attribute is added in a custom subclass, you must also specify this using the hla-fom-class setting in the OPE. This example adds a new subclass called HumanWithAccuracyStats. Please see one of the included VrfStateProperty FDD files for an example of how these attributes are added.
(hla-fom-class "BaseEntity.PhysicalEntity.Lifeform.Human.HumanWithAccuracyStats")
The data type can be anything from a simple integer to a list of complex structures. Below is a list of acceptable data types. For further examples of how to define complex data types, refer to the Aggregate.ope file in the AggregateLevel SMS.
| Data Type | Description | HLA Representation/Encoding |
| DtRwInt | A 32 bit integer | RPRunsignedInteger32BE, HLAinteger32BE |
| DtRwReal | A 64 bit float | HLAfloat64BE |
| DtRwBoolean | A Boolean | RPRboolean |
| DtRwString | An ASCII string | RPRnullTerminatedArray of HLAASCIIchar |
| DtRwStructure | A fixed structure with multiple named fields | HLAfixedRecord with matching fields |
| DtRwList | A variable sized list of items | HLAvariableArray |
| DtRwMap | A variable sized map of items | HLAvariableArray of HLAfixedRecords, where the first field is the key |
The plugin code just consists of a single callback that listens for detonation interactions. When a detonation is received, if the shooter is local, the result of the detonation is checked and the TargetsHit or TargetsMissed property is updated accordingly.
The example scenario also includes a Lua scripted set called Clear Accuracy Stats that sets each of these properties back to 0.
How to Run the Example
-
Copy VrfStateProperty.fed, VrfStateProperty.xml, and VrfStateProperty_evolved.xml from examples to the bin64 directory.
-
Since this example is loaded as a plugin, it can be used in conjunction with the released VR-Forces application
Usage
In the Launcher:
-
In the Launcher, click the Plug-ins button to bring up the Plug-ins Selection dialog. Enable the plugin.
-
Set Federation Name to "VrfStateProperty"
-
Set the FED File Name to VrfStateProperty.fed if using HLA 1.3, VrfStateProperty.xml if using HLA 1516-2000, or VrfStateProperty_evolved.xml if using HLA Evolved. If using DIS, you must use DIS 7.
-
Set the RPR FOM version to 2.0
-
Start VR-Forces
To view the new behavior:
-
Start VR-Forces GUI and SIM.
-
Load the addStateProperty.scnx scenario from the 'developer toolkit examples' directory.
-
Right-click on entity R1 and select Information... to open its information window.
-
Find the Hits and Misses entries on the State Data page.
-
Play the scenario. As the entity shoots at the opposing entities, watch Hits and Misses increase depending on the result of the shot taken.
-
Right-click on entity R1, go to the Set menu, and choose Clear Accuracy Stats. The Hits and Misses counts should return to 0.
After the example run is completed - remove the previously copied FED File Name (e.g. AddStateComponent_evolved.xml) from the bin64 directory.
Restore the previously set FED File Name within the Launcher dialog.
Plugin Code
#include <tbb/atomic.h>
std::map<DtUUID, std::pair<int, int> > theStats;
{
{
std::map<DtUUID, std::pair<int, int> >::iterator iter = theStats.find(inter->
attackerId());
if (iter == theStats.end())
{
theStats[inter->
attackerId()] = std::make_pair(0, 0);
}
{
iter->second.first++;
}
else
{
iter->second.second++;
}
}
}
void processDetonations(void* usr)
{
std::map<DtUUID, std::pair<int, int> >::const_iterator iter = theStats.begin();
std::map<DtUUID, std::pair<int, int> >::const_iterator end = theStats.end();
while (iter != end)
{
{
const DtRwInt* missProperty = vrfSimulatedSimObjectFacade.stateProperties().findProperty<
DtRwInt>(
"TargetsMissed");
const DtRwInt* hitProperty = vrfSimulatedSimObjectFacade.stateProperties().findProperty<
DtRwInt>(
"TargetsHit");
if (missProperty && hitProperty)
{
if ((missProperty->
value() != iter->second.second) || (hitProperty->value() != iter->second.first))
{
newHitProperty->
setValue(iter->second.first);
newMissProperty->
setValue(iter->second.second);
}
}
}
++iter;
}
}
extern "C" {
{
info.
pluginDescription =
"This is an example of how to add an attribute to an entity as a state property and publish that attribute to the network.";
}
{
std::map<DtUUID, std::pair<int, int> >::iterator iter = theStats.find(lo.
uuid());
if (iter != theStats.end())
{
theStats.erase(iter);
}
}
{
return true;
}
}