VR-Link API Documentation for DIS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Object Ownership Example

The following code demonstrates how to transfer ownership between federates in HLA using the simplified ownership handler classes in VR-Link

It creates an entity with the marking text of the owning federate. You can use the keys 'a' and 'd' to aquire or divest the entities and the marking text will change appropriately. This example works best when you run multiple copies of it at the same time, so there are enough entities to move ownership.

//********************************************************************
// Copyright (c) 2007 MaK Technologies, Inc.
// All rights reserved.
//********************************************************************
#include <vl/topoView.h>
#include <vl/fom.h>
#include <iostream>
#include <list>
int keybrdTick();
// Containers for both published and reflected objects.
// Used to manage which objects are currently owned or not
DtReflectedEntityList *entitiesReflected;
DtExerciseConn* myExConn;
DtList deletedPublishers;
// The gainedOwnership and loseOwnership callbacks are the heart
// of what a user needs to do to manipulate objects when ownership transfer occurs.
// They require creating a new publisher and deleting the old reflected object (or in the
// case of loseOwnership, the reverse). If you are running in self reflect mode
// then you do not need to create or delete the reflected object, but you still need to
// manage the publisher.
// There are a number of Ifdefs related to different protocols due to significant
// differences between DIS and HLA object representations, but both protocols do the same thing.
#ifdef DtHLA
void gainedOwnership(DtHlaObject* hlaObject, void* usr)
#else //DtDIS
void gainedOwnership(const DtEntityIdentifier* entityId, void* usr)
#endif
{
DtInfo << "Gained Ownership!" << std::endl;
// Create Publisher Object
#ifdef DtHLA
DtHlaObjectWithStateRep* objWithSR = dynamic_cast<DtHlaObjectWithStateRep*>(hlaObject);
#else //DtDIS
#endif
if (!objWithSR)
{
return; //We are gaining an object that doesn't exist!
}
DtEntityPublisher* entityPublisher = new DtEntityPublisher(objWithSR, myExConn);
// Once we acquire an object we should update it to make sure it gets correctly synced.
entityPublisher->forceUpdate();
// Now change the marking text to signal ownership and add this new publisher
// To our list of publishers. (HLA Only)
#ifdef DtHLA_1516_EVOLVED
entityPublisher->esr()->setMarkingText(objWithSR->exerciseConn()->fedName());
#elif DtHLA
entityPublisher->esr()->setMarkingText(objWithSR->exerciseConn()->fedType());
#endif
entitiesOwned.add(entityPublisher);
// Remove Reflected Objects. You do not need to do this if you have
// selfReflect turned on. Which is highly recommended for simplifying ownership
// Management
#if DtHLA
#if DtHLA_1516
const RTI::ObjectInstanceHandle& objId = hlaObject->objectId();
#else
const RTI::ObjectHandle& objId = hlaObject->objectId();
#endif
DtReflectedObject* refObj = entitiesReflected->lookupObj(objId);
if(refObj)
{
refObj->detachHlaObject();
entitiesReflected->removeObject(objId);
}
#else //DtDIS
DtReflectedObject* refObj = entitiesReflected->lookup(entityPublisher->id());
if (refObj)
{
entitiesReflected->removeAndDelete(refObj);
}
#endif
}
#ifdef DtHLA
void lostOwnership(DtHlaObject* hlaObject, void* usr)
#else //DtDIS
void lostOwnership(const DtEntityIdentifier* entityId, void* usr)
#endif
{
DtInfo << "Lost Ownership!" << std::endl;
// Create Reflected Object. You do not need to do this if you have
// selfReflect turned on. Which is highly recommended for simplifying ownership
// Management
#ifdef DtHLA
DtReflectedEntity* reflectedEntity = new DtReflectedEntity(hlaObject, hlaObject->exerciseConn());
#else //DtDIS
DtStateRepository* objWithSR = myExConn->disObjectManager()->stateRepOfObject(*entityId)->clone();
DtReflectedEntity* reflectedEntity = new DtReflectedEntity((DtEntityStateRepository*)objWithSR, myExConn, *entityId);
#endif
entitiesReflected->addToObjectList(reflectedEntity);
// Remove Publisher Object from the list of Items we are publishing. If you do not
// do this, the object will continue to tick internally.
while(ownedEntityList != entitiesOwned.end())
{
#ifdef DtHLA
if ((*ownedEntityList)->hlaObject() == hlaObject)
#else //DtDIS
if ((*ownedEntityList)->id() == *entityId)
#endif
{
DtEntityPublisher* unownedObject = (*ownedEntityList);
entitiesOwned.remove(unownedObject);
deletedPublishers.add(unownedObject); //Avoid a bad callback by deleting outside of this function.
break;
}
++ownedEntityList;
}
}
// NOTE: This assumes that Self Reflect is NOT on, which requires manual
// removal of reflected objects. If Self Reflect is on, then the lost and gainedOwnership
// callbacks do not need to manage the reflected objects
int objectOwnershipExample(DtExerciseConn *exConn)
{
try
{
DtDefaultOwnershipHandler defaultHandler;
// Accept all requests for ownership transfer.
// Set up callbacks when an entity gets transferred. Note that
// this callback will only trigger if the object is an entity.
// You can make this more specific in HLA by adding a third parameter:
// exConn->fom()->objClassByName("BaseEntity.PhysicalEntity")
defaultHandler.addAcquireOwnershipCallback(&gainedOwnership, 0);
defaultHandler.addDivestOwnershipCallback(&lostOwnership,0);
// Set the default ownership Handler. This will be the
// Ownership handler that will be set in all HLA objects created
// Note that this needs to be done before we create or reflect
// any objects as the default Ownership Handler will only apply to future
// objects.
exConn->setDefaultOwnershipHandler(&defaultHandler);
// Create an entity publisher for the entity we are simulating.
DtEntityPublisher* entityPub = new DtEntityPublisher(f18Type, exConn,
entitiesOwned.add(entityPub);
// Create Reflected Entity List
entitiesReflected = new DtReflectedEntityList(exConn);
// Hold on to the entity's state repository, where we can set data.
#ifdef DtHLA_1516_EVOLVED
esr->setMarkingText(exConn->fedName());
#elif DtHLA
esr->setMarkingText(exConn->fedType());
#endif
// Initialize VR-Link time.
DtClock* clock = exConn->clock();
// Main loop
DtTime dt = 1.0; //Update once a second
DtTime simTime = 0;
while (true)
{
// Check if user hit 'q' to quit.
if (keybrdTick() == -1)
break;
// Tell VR-Link the current value of simulation time.
clock->setSimTime(simTime);
// Tick all entities. Note that in this example
// the entities never change value except for the marking test
// signaling which federate owns what
entitiesOwned.tick();
// Process any incoming messages.
exConn->drainInput();
// Remove any deleted publishers due to ownership management.
// This must be done outside of drainInput to avoid calls
// to missing objects.
while (deletedPublishers.first())
{
DtListItem* item = deletedPublishers.first();
delete((DtEntityPublisher*)item->data());
deletedPublishers.remove(item);
}
simTime += dt;
// Wait till real time equals simulation time of next step.
DtSleep(simTime - clock->elapsedRealTime());
}
}
DtCATCH_AND_WARN(std::cout);
return 0;
}
int keybrdTick()
{
char *keyPtr = DtPollBlockingInputLine();
if(keyPtr) {
switch(*keyPtr) {
case 'q':
case 'Q':
return -1;
break;
case 'a':
case 'A':
DtInfo << "Acquire" << std::endl;
if(entitiesReflected->count())
{
DtReflectedEntity* reflEntity = entitiesReflected->first();
reflEntity->acquireObject();
}
break;
case 'd':
case 'D':
DtInfo << "Divest" << std::endl;
if(!entitiesOwned.empty())
{
DtEntityPublisher* entityPublisher = *(entitiesOwned.begin());
#ifdef DtHLA
entityPublisher->divestObject();
#else //DtDIS
// DIS Requires a target site/application, for simplicity of this example
// we will try to divest to the next application number. In a real example,
// you need to know which application you are divesting to.
entityPublisher->divestObject(myExConn->applicationId().DtSite,
myExConn->applicationId().DtHost + 1);
#endif
}
break;
}
}
return 0;
}

Document ID: Generated on Mon Apr 25 03:39:01 EDT 2022 from SVN revision 242502
Copyright © 2005-2021 MAK Technologies. All Rights Reserved (www.mak.com)