VR-Exchange 2.6 API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Simple Broker Example

The SimpleBroker application is a complete VR-Exchange broker.

It demonstrates how to build a broker class as well as a broker application. The SimpleBroker receives and transmits DIS PDUs as part of the example. It does not do translations in any meaningful way, and is completely non functional as a DIS broker.

Three significant classes are created in this example. DtSimpleBroker, which subclasses DtBroker, connects to the Portal via DtBroker, and registers for callbacks for broker exit. It also processes the configuration file simpleBroker.xml. Two helper classes, DtEntityTranslator and DtFireTranslator, simulate translation of Entity State PDUs and Weapon Fire PDU's. These classes were designed to show how new objects can be created and updates can be processed for both objects and interactions.


simple.cxx

/****************************************************************************
* Copyright (c) 2014 VT MAK
* All rights reserved.
****************************************************************************/
#include <simpleBroker.h>
#include <vlutil/vlExceptions.h>
#include <vlutil/vlMiniDumper.h>
#include <iostream>
using namespace MAKVrExchange;
int main( int argc, char* argv[] )
{
DtINIT_MINIDUMPER( "Simple Broker" );
DtSimpleBroker* sb = 0;
try
{
const std::string version = "1.0";
// Load the configuration options
new DtBrokerInitializer( argc, argv, DtPortalConnection::version().c_str() );
init->parseCmdLine();
// There are no connection options for this simple broker, so just return
// without doing anything.
if ( init->showConnectionInfoDialog() )
{
return 0;
}
// Create a broker instance
sb = DtSimpleBroker::create( init );
// Tick the broker until we get the exit message
while ( ! sb->isTimeToQuit() )
{
DtSleep( sb->pollingInterval() );
}
}
DtCATCH_AND_WARN( std::cout );
DtDELETE( sb );
return 0;
}

simpleBroker.cxx

/****************************************************************************
* Copyright (c) 2016 VT MAK
* All rights reserved.
****************************************************************************/
#include "simpleBroker.h"
#include <vl/exerciseConn.h>
#include <vl/exerciseConnInitializer.h>
using namespace MAKVrExchange;
{
DtSimpleBroker* broker = new DtSimpleBroker();
broker->initialize( init );
return broker;
}
, myDisExConn( 0 )
, myFireTranslator( 0 )
, myEntityTranslator( 0 )
{
}
{
// Create a connection to the DIS Exercise with some default parameters
DtExerciseConnInitializer dInit;
dInit.setPort( 3005 );
dInit.setSiteId( 1 );
dInit.setApplicationNumber( 23 );
myDisExConn = new DtExerciseConn( dInit );
// Create a translator for all Fire Interactions
}
{
// Clean up resources
DtDELETE( myFireTranslator );
DtDELETE( myDisExConn );
}
DtExerciseConn* DtSimpleBroker::disExConn()
{
return myDisExConn;
}
{
try
{
myDisExConn->clock()->setSimTime( simTime() );
myDisExConn->drainInput();
}
DtCATCH_AND_WARN( DtWarn );
}

sFireTrans.cxx

/****************************************************************************
* Copyright (c) 2015 VT MAK
* All rights reserved.
****************************************************************************/
#include "sFireTrans.h"
// VR-Link DIS Includes
#include <matrix/vlVector.h>
#include <vl/exerciseConn.h>
#include <vlpi/entityIdentifier.h>
// Portal Includes
using namespace MAKVrExchange;
DtFireTranslator::DtFireTranslator(DtExerciseConn& disConn, DtPortalConnection &pConn):
myDisConn(disConn),
myPortalConn(pConn)
{
DtFireInteraction::addCallback(
&myDisConn, receiveDisInteraction, this);
DtPortalFireInteraction::addCallback(
&myPortalConn, receivePortalInteraction, this);
}
{
DtFireInteraction::removeCallback(
DtPortalFireInteraction::removeCallback(
}
// -------------------------------------------------------------------
// -------- Translation Methods
// -------------------------------------------------------------------
{
DtFireInteraction out;
// In a real broker, some translation would need to happen here.
// The entity ID would need to be mapped from some string value. If there
// was no valid conversion a unique entity Id would need to be created.
out.setAttackerId(DtEntityIdentifier(1,3,4));
out.setTargetId(DtEntityIdentifier(2,4,2));
out.setMunitionId(DtEntityIdentifier(3,4,2));
out.setWarheadType((DtWarheadType)in.warheadType());
myDisConn.send(out);
}
void DtFireTranslator::createPortalInteraction( const DtFireInteraction& in )
{
// The Portal uses Strings for Ids. One translation scheme
// would be to use the DIS ID as a string. The decision regarding
// translation is significantly more complicated.
out.setAttackerId( in.attackerId().string() );
out.setTargetId( in.targetId().string() );
out.setMunitionId( in.munitionId().string() );
out.setWarheadType( (DtWarheadType)in.warheadType() );
}
// -------------------------------------------------------------------
// -------- Static Methods
// -------------------------------------------------------------------
void DtFireTranslator::receiveDisInteraction( DtFireInteraction* fire, void* usr )
{
trans->createPortalInteraction( *fire );
}
{
trans->createInteraction( fire );
}

sEntityTrans.cxx

/****************************************************************************
* Copyright (c) 2016 VT MAK
* All rights reserved.
****************************************************************************/
#include "sEntityTrans.h"
// VR-Link DIS Includes
#include <matrix/vlVector.h>
#include <vl/exerciseConn.h>
#include <vl/entityPublisher.h>
#include <vl/reflectedEntityList.h>
#include <vl/baseEntityStateRepository.h>
// Portal Includes
#include <portal/pEntity.h>
using namespace MAKVrExchange;
: myDisConn( disConn )
, myPortalConn( pConn )
, myDisReflectedList( 0 )
, myPortalReflectedManager( 0 )
, myDisEntityPublisher( 0 )
, myPortalEntityPublisher( 0 )
{
// Create Reflected Lists to handle DIS Updates -- This is VR-Link DIS Code
myDisReflectedList = new DtReflectedEntityList(&disConn);
myDisReflectedList->addEntityRemovalCallback(DtEntityTranslator::disObjectDeletedCb, this);
myDisReflectedList->addEntityAdditionCallback(DtEntityTranslator::disObjectAddedCb, this);
// Create Reflected Manager for Portal Updates -- This is Portal Specific
myPortalReflectedManager = new DtPortalReflectedEntityManager(&pConn);
myPortalReflectedManager->addRemovalCallback(DtEntityTranslator::portalObjectDeletedCb, this);
myPortalReflectedManager->addAdditionCallback(DtEntityTranslator::portalObjectAddedCb, this);
myDisReflectedList->setDiscoveryCondition(disDiscoveryCriteria, this);
myPortalReflectedManager->setDiscoveryCondition(DtEntityTranslator::portalDiscoveryCriteria, this);
}
{
if (myDisEntityPublisher)
{
DtDELETE( myDisEntityPublisher );
}
if (myPortalEntityPublisher)
{
DtDELETE( myPortalEntityPublisher );
}
DtDELETE( myDisReflectedList );
DtDELETE( myPortalReflectedManager );
}
{
}
// -------------------------------------------------------------------
// -------- Translation Methods
// -------------------------------------------------------------------
void DtEntityTranslator::discoverDisObject(const DtReflectedEntity &reflectedObj)
{
if (!myPortalEntityPublisher)
{
myPortalEntityPublisher =
new DtPortalEntityPublisher(&myPortalConn);
// Call to update attributes - In DIS all attributes are available at discovery
receiveDisUpdate(reflectedObj);
}
}
{
// This example only translates the first entity
if (!myDisEntityPublisher)
{
// Create a DIS Publisher for this object. Most of the values for this
// publisher are bogus. Translation of a real object is beyond the scope of
// this example.
myDisEntityPublisher =
new DtEntityPublisher( DtEntityType(1,2,3,4,5,6,7),
&myDisConn,
DtEntityIdentifier(1,2,3));
// Call to update attributes - The Data Exchange makes all attributes
// available at discovery
receivePortalUpdate(reflectedObj);
}
}
void DtEntityTranslator::receiveDisUpdate( const DtReflectedEntity& reflectedObj )
{
if ( myPortalEntityPublisher )
{
DtPortalEntity* newSr = myPortalEntityPublisher->sr();
const DtEntityStateRepository* sr = reflectedObj.esr();
// Copy all values and do any translation required. In this case all DIS
// coords are the same as portal coords (Geocentric)
newSr->setLocation( sr->location() );
newSr->setVelocity( sr->velocity() );
newSr->setAcceleration( sr->acceleration() );
newSr->setOrientation( sr->orientation() );
newSr->setRotationalVelocity( sr->rotationalVelocity() );
newSr->setRelativeLocation( sr->relativeLocation() );
newSr->setRelativeVelocity( sr->relativeVelocity() );
newSr->setRelativeAcceleration( sr->relativeAcceleration() );
newSr->setRelativeOrientation( sr->relativeOrientation() );
newSr->setRelativeRotationalVelocity( sr->relativeRotationalVelocity() );
}
}
{
if (myDisEntityPublisher)
{
const DtPortalEntity *sr = reflectedObj.sr();
DtEntityStateRepository *newSr = myDisEntityPublisher->esr();
// Copy all values and do any translation required. In this case all DIS
// coords are the same as portal coords (Geocentric)
newSr->setLocation(sr->location());
newSr->setVelocity(sr->velocity());
newSr->setAcceleration(sr->acceleration());
newSr->setOrientation(sr->orientation());
newSr->setRotationalVelocity(sr->rotationalVelocity());
newSr->setRelativeLocation(sr->relativeLocation());
newSr->setRelativeVelocity(sr->relativeVelocity());
newSr->setRelativeAcceleration(sr->relativeAcceleration());
newSr->setRelativeOrientation(sr->relativeOrientation());
newSr->setRelativeRotationalVelocity(sr->relativeRotationalVelocity());
}
}
void DtEntityTranslator::processDisRemoval(const DtReflectedEntity &reflectedObj)
{
if (myPortalEntityPublisher)
{
DtDELETE( myPortalEntityPublisher );
}
}
{
// Any object removal will delete this entity publisher. It means this
// example will appear to work only when there is one entity available.
if (myDisEntityPublisher)
{
DtDELETE( myDisEntityPublisher );
}
}
// -------------------------------------------------------------------
// -------- Static Methods
// -------------------------------------------------------------------
DtReflectedEntity *reflectedObj, void *userData)
{
DtEntityTranslator *et = static_cast<DtEntityTranslator*>(userData);
et->discoverDisObject(*reflectedObj);
// Register for updates on this object
reflectedObj->addPostUpdateCallback(DtEntityTranslator::disObjectUpdatedCb, userData);
}
DtReflectedEntity *reflectedObj, void *userData)
{
DtEntityTranslator *et = static_cast<DtEntityTranslator*>(userData);
et->receiveDisUpdate(*reflectedObj);
}
DtReflectedEntity *reflectedObj, void *userData)
{
DtEntityTranslator *et = static_cast<DtEntityTranslator*>(userData);
et->processDisRemoval(*reflectedObj);
}
const DtPortalReflectedEntity& reflectedObj, void *userData)
{
DtEntityTranslator *et = static_cast<DtEntityTranslator*>(userData);
et->discoverPortalObject(reflectedObj);
// Register for updates on this object
}
const DtPortalReflectedEntity& reflectedObj, void *userData)
{
DtEntityTranslator *et = static_cast<DtEntityTranslator*>(userData);
et->receivePortalUpdate(reflectedObj);
}
const DtPortalReflectedEntity& reflectedObj, void *userData)
{
DtEntityTranslator *et = static_cast<DtEntityTranslator*>(userData);
et->processProtalRemoval(reflectedObj);
}
DtReflectedObject* ro, void *object)
{
// HLA Object is always discoverable for this example
return true;
}
const DtPortalReflectedObject *ro, void *object)
{
// Portal Object is always discoverable for this example
return true;
}

Document ID: Generated on Wed Jan 30 18:15:18 EST 2019 from SVN revision 195534
Copyright © 2005-2019 VT MÄK. All Rights Reserved (www.mak.com)