VR-Exchange 2.2 API Documentation
9 - Extending the Portal Application

The VR-Exchange main executable vrx.exe, is referred to as the Portal application.

The Portal application performs two basic functions: managing inter-broker message transfer, and managing the graphical display and logging translated messages. Although the graphical user interface facilitates management and configuration of connections, it is not required for VR-Exchange to operate.

The Portal application creates brokers and manages the internal message queues used for inter-broker communication. To accomplish this task the main Portal application class DtPortalApp (portalApp.h) creates the helper classes DtQueueManager (queueManager.h) and DtAppBrokerManager (appBrokerManager.h). The DtQueueManager instance creates and manages all internal message queues and maintains the status of all connected brokers. If a broker exits unexpectedly, the DtQueueManager instance sends a message to disconnect the broker. The DtAppBrokerManager also maintains a list of connections, displays the list in the GUI, and sends messages to individual brokers to shut down if their connections are disabled.

The Portal application acts as a read-only broker to display basic information transmitted between other brokers. When run with a GUI, the Portal application creates a DtPortalAppGui (portalAppGui.h) instance, which builds the Qt GUI interface and creates both object and interaction view components. View components are responsible for displaying some aspect of the internal Portal communications. Each view component instance connects via a DtPortalConnection and registers for updates much like a broker would. Instead of translating the updates it receives, the view component displays information about those updates on the screen.

Because message management occurs without knowledge of the message internals or message types, if you write new brokers, or develop new message types, you do not need to modify the Portal application. However, if you want new message types displayed in the GUI, or want to change the way the GUI looks, you must modify and recompile the Portal application.

A minimal example of a VR-Exchange Portal application is as follows:

DtPortalAppInitializer initializer("VR-Exchange.xml", __argc, __argv);
DtPortalApp pApp(initializer);
pApp.run();

The DtPortalAppIntitializer (portalAppInitializer.h) reads the specified configuration file and parses command-line arguments. Then it initializes the DtPortalApp instance, which creates a DtPortalAppGui instance. The example ModifiedPortalApp demonstrates this.

The DtPortalAppGui, when it exists, creates view component classes to display object and interaction updates. The classes are DtInteractionViewComponent (pInteractionViewComponent.h) and DtObjectViewComponent (pObjectViewComponent.h). Each of these classes can be subclassed and registered with the DtPortalAppGui class for later use.

For example, if you want to display a new interaction class, you would subclass the DtInteractionViewComponent and add a callback for that type of interaction class. The ModifiedPortalApp example does this with the DtPortalBoom interaction, as follows:

class DtModInteractionManager : public DtInteractionViewComponent
{
public:
DtModInteractionManager(DtPortalConnection *pconn, Qwidget *parent);
virtual ~DtModInteractionManager();
static DtAppInteractionManager* create(DtPortalConnection *pconn,
Qwidget *parent);
protected:
static void boomCb(const DtPortalBoomInteraction &inter,
void *userData);
};

The static member function boomCb() is called any time a new DtPortalBoom interaction is received. This callback is registered in the constructor as follows:

DtModInteractionManager::DtModInteractionManager(
DtPortalConnection *pconn, Qwidget *parent):
DtInteractionViewComponent(pconn, parent)
{
DtModInteractionManager::boomCb, this);
}

This callback is registered like all callbacks for Portal objects. The callback looks like this:

void DtModInteractionManager::boomCb(
const DtPortalBoomInteraction &inter, void *usrData)
{
DtString description = "Something went boom!";
DtModInteractionManager *p = (DtModInteractionManager*)usrData;
p->processInteraction(inter, description);
}

The callback calls the virtual function processInteraction(), which takes an interaction to display and a string description. The string can explain that someone shot at someone else and provide a short detailed description of the event to be displayed on the GUI. The new class creator member function is then registered in the DtPortalAppGui class as follows:

DtPortalAppGui::setInteractionManagerCreator( DtModInteractionManager::create);

DtPortalAppGui::setInteractionManagerCreator() is a static class that must be called before the DtPortalAppGui instance is created. The same process happens for objects, as follows:

class DtModObjectManager : public DtObjectViewComponent
{
public:
DtModObjectManager(DtPortalConnection *pconn, Qwidget *parent);
virtual ~DtModObjectManager();
static DtAppObjectManager* create(DtPortalConnection *pconn,
QWidget *parent);
protected:
static void discoverFruitCb( const DtPortalReflectedFruit &obj,
void*usrData);
static void updateFruitCb( const DtPortalReflectedFruit &obj,
void*usrData);
static void deleteFruitCb( const DtPortalReflectedFruit &obj,
void *usrData);
protected:
};

This class is similar to the DtInteractionViewComponent class, except that for every object there are three events to register for: discovery, update, and removal. The callbacks look like the following:

void DtModObjectManager::discoverFruitCb(
const DtPortalReflectedFruit &obj, void *usrData)
{
DtInfo << "DtModObjectManager discovered a new fruit. \n";
DtModObjectManager *p = (DtModObjectManager*)usrData;
obj.addUpdateCallback( DtModObjectManager::updateFruitCb, usrData);
p->addObject(obj);
}
void DtModObjectManager::updateFruitCb(
const DtPortalReflectedFruit &obj, void *usrData)
{
DtInfo << "DtModObjectManager updated a fruit. \n";
DtModObjectManager *p = (DtModObjectManager*)usrData;
p->updateObject(obj);
}
void DtModObjectManager::deleteFruitCb(
const DtPortalReflectedFruit &obj, void *usrData)
{
DtInfo << "DtModObjectManager removed a fruit. \n";
DtModObjectManager *p = (DtModObjectManager*)usrData;
p->removeObject(obj);
}

In this case the base class provides three member functions that display the events: addObject(), updateObject(), and removeObject(). These three member functions add the object to the display, update the object, and remove the object from the display. Each of these member functions uses the message kind to keep track of statistics about the object and display the name of the object.

[<< The Broker Plug-in API] [Home] [Top of Page] [Building and Compiling Brokers >>]


Document ID: Generated on Mon Apr 15 17:15:50 EDT 2013 from SVN revision 126154
Copyright © 2005-2012 VT MÄK. All Rights Reserved (www.mak.com)