|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectmil.navy.nps.dis.EntityDispatcher
EntityDispatcher is an independent thread that connects all EsdpuTransforms to the BehaviorStreamBuffer. A single EntityDispatcher object handles all routing of PDUs to & from the EspduTransform scripts which connect to individual entities in the VRML scene. The EntityDispatcher is static, meaning that only one copy can exist. EntityDispatcher is instantiated and threaded by the first EspduTransform encountered. In turn, the EntityDispatcher similarly instantiates and threads the static BehaviorStreamBuffer, which independently reads all network PDUs and then hands them over in a list.
The EntityDispatcher contains
EntityDispatcher responsibilities include
The VRML scene interrogates each entity at periodicities approximately equal to the author-provided values readInterval (or writeInterval). Defaults are set in EspduTransformPROTO.wrl
*--------------------------------------------------* / /| *--------------------------------------------------* | Browser | VRML Scene | | [threaded] | | | | | | | | | | geometry geometry | | | : : Radio | | |EspduTransform EspduTransform Communications| | | PROTO PROTO PROTOs | | | : : : | * |(Script node) ... (Script node) (Script node) |/ *-----+----------+----------+----------------------* Entity 1 ... Entity n Radios 1..n | | | | | | | +----------------------+ | | *------+--------* | | ... |EspduTransform | dead reckoning | | *-----+---------------* | updates here | multiple copies, | |EspduTransform | | (PDU posture | one per entity *--+----------------------* | | extrapolation) *-------+--------* |EspduTransform | |---* | Radio | | | | | Communications | | |---* | PduScriptNode | *--+----------------------* *-------+--------* ^ | ^ ^ | | | | Signal, | v | | Receiver, *--+----------+----------+--* | Transmitter singleton | | (separate subscribe loop) | PDUs [threaded] | EntityDispatcher |---------------------------------+ if thread fails | | to start, runs | EntityHashTable | single read per | - Entity 1 | each draw loop | - Entity 2 | | - [...] | single copy | - Entity n | (reads) *-------------+-------------* ^ | | | Entity State, Radio, other PDUs | | *-------------+-------------* V | | (writes) static | | [threaded] | BehaviorStreamBuffer | single copy | | | | *-------------+-------------* | *-------------+-------------* static | | [threadable] | org.web3d.vrtp.net. | browser-specific but not threaded | DatagramStreamBuffer | security single copy | | permissions | | *----------+-----+----------* | | | ... | multicast address(es)/port(s) | | (area of interest management) | | Network 0======+=====+=====0The behaviorStreamBuffer, an instance of a BehaviorStreamBuffer, reads PDUs from the wire. The EntityDispatcher occasionally pulls PDUs from the behaviorStreamBuffer. For each PDU, the simulation manager looks at the type.
If it's an ESPDU, the EntityDispatcher code looks at the EntityID triplet (site, application, ID) that uniquely identifies each entity, uses that aggregated triplet as a hash key to the Hashtable to find the appropriate EspduTransform reference, and then passes the PDU data via that EspduTransform to the correct entity. If the PDU has an unrecognized EntityID, we may optionally instantiate a local entity to reflect it, and insert it into the scene. The EspduTransform object is responsible for communications with the VRML scene. ESPDU culling may be performed either here or at the entity level. Since arrivals of PDUs for a given entity may occur out of order, it seems more logical to put PDU interpretation at the EspduTransform level, where there is a bit more information about update frequency and the like. In some special cases, it might make more sense to cull special PDUs early in to cut down on PDU handling overhead. That's an implementation and optimization detail.
If it's a SimulationManagement PDU, it will be handled by a different block of code. SimulationManagement PDUs include Start Simulation PDU, Stop Simulation PDU, Create Entity PDU, EventReport PDU, Query PDU and Data PDU. Each of these will probably require some special handling, and perhaps some state changes in the EntityDispatcher object. Some of them will require that PDUs be sent in response.
Cardinality: there is one and only one instance of a EntityDispatcher per DIS application. The EntityDispatcher is instantiated and operated through class (static) methods.
More functionality might be integrated into this object as well. Deciding which functionality goes where is the objective of the vrtp streaming stack.
29 Oct 97 | Don McGregor | New |
19 Oct 98 | Don Brutzman & Don McGregor | integrate revised EspduTransform and Javadoc updates for jdk1.2b4, fix threading, remove references to SimulationManager and EntityState classes. |
12 Nov 98 | Don McGregor | Added PduPublisher and PduSubscriber interfaces. |
14 Feb 99 | Don Brutzman | Added Fire and Collision PDU dispatching to EspduTransform. |
20 Feb 99 | Don McGregor | Added MulticastTunnelServer connectivity. |
4 Apr 99 | Don Brutzman | Thread shutdown and various trace fixes. |
10 Sep 99 | Don McGregor & Don Brutzman | Security strategy |
28 Sep 99 | Don Brutzman | Added Comment and CreateEntity PDUs |
3 September 2000 | Don Brutzman | Changed dis.PduTypeEnum to disEnumerations.PduTypeField |
18 September 2000 | Don Brutzman and Dave Laflam | Added, tested RadioCommunicationFamily PDUs |
EspduTransform
,
BehaviorStreamBuffer
,
DatagramStreamBuffer
,
SecurityStrategy
Nested Class Summary | |
protected class |
EntityDispatcher.TunnelManager
|
Field Summary | |
protected static BehaviorStreamBuffer |
behaviorStreamBuffer
Handles communication with the wire, collecting PDUs from the packets received by a DatagramStreamBuffer. |
protected java.lang.Thread |
behaviorStreamBufferThread
Thread for BehaviorStreamBuffer |
protected static boolean |
DEBUG
Flag for debugging/diagnostic output enabled |
protected static java.util.Hashtable |
pduSubscriberScriptNodesHashtable
Contains references to all EspduTransforms, RadioCommunicationsFamily nodes and other Script nodes in the VRML world, using the entity-unique site-ID/applicationID/entityID triplet as the hash key. |
protected SecurityStrategy |
strategy
platform-specific security strategy |
protected static EntityDispatcher.TunnelManager |
tunnelManager
Internal threadable class that handles tunnel communications with a MulticastRelayServer if no native multicast traffic heard on local LAN. |
Method Summary | |
void |
addListener(PduSubscriber pSubscriber,
EntityID pEntityID)
Adds a subscribing Scipt node to the pduSubscriberScriptNodesHashtable being maintained. |
void |
adviseSleepInterval(float anotherReadWriteInterval)
Somewhat careful accessor method that decides how long to let the thread sleep, so that it doesn't steal excessive cycles from the VRML 3D graphics rendering process(es). |
void |
checkForTrafficAndFallBackToTunnel(java.lang.String pTunnelAddress,
int pTunnelPort,
int pLocalPort)
Test for the existence of multicast (or unicast) and, if not found, open up a tunnel to the tunnel server, and replace the original BSB with this new one. |
void |
createMulticastBehaviorStreamBuffer(java.lang.String pMcastAddress,
java.lang.Integer pPortNumber)
Creates multicast BehaviorStreamBuffer. |
void |
createUdpUnicastBehaviorStreamBuffer(java.lang.Integer pPortNumber)
Creates unicast UDP BehaviorStreamBuffer. |
protected void |
debug(java.lang.String pDiagnostic)
Debugging output. |
void |
doRun()
After the behaviorStreamBuffer thread is started, doRun loops endlessly to pull unordered lists of PDUs from the behaviorStreamBuffer, sending the PDUs one-by-one to the appropriate EspduTransform matching the entity. |
boolean |
getDEBUG()
Get debugging flag |
static EntityDispatcher |
getEntityDispatcher(java.lang.String pAddress,
int pPort)
getEntityDispatcher returns the single, shared instance of the EntityDispatcher object. |
float |
getSleepInterval()
Accessor method. |
void |
removeListener(PduSubscriber listenerToRemove,
EntityID pEntityID)
addListener and removeListener are the two methods that implement the PduPublisher interface. |
void |
run()
run() switches on platform-secific security, gets the thread running using doThread (), then calls doRun () which does the actual work of reading from the network. |
void |
sendPdu(ProtocolDataUnit pPdu)
Example of delegation of writing a PDU to the single static behaviorStreamBuffer. |
void |
sendPdu(ProtocolDataUnit pdu,
java.lang.String pDestinationHost,
int pDestinationPort)
Example of delegation of writing a PDU to the single static behaviorStreamBuffer. |
void |
setDEBUG(boolean pDEBUG)
Set debugging flag |
void |
shutdown()
shutdown() is called when VRML scene exits. |
void |
singleReadLoop()
singleRunLoop() is called via doRun when threading, or via the invoking application if not threading (e.g. |
void |
startBehaviorStreamBufferThread()
startBehaviorStreamBufferThread starts the behaviorStreamBuffer thread. |
protected void |
trace(java.lang.String pDiagnostic)
Guaranteed trace output. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
protected static BehaviorStreamBuffer behaviorStreamBuffer
protected java.lang.Thread behaviorStreamBufferThread
protected static EntityDispatcher.TunnelManager tunnelManager
protected static java.util.Hashtable pduSubscriberScriptNodesHashtable
protected SecurityStrategy strategy
protected static boolean DEBUG
Method Detail |
public boolean getDEBUG()
public void setDEBUG(boolean pDEBUG)
public static EntityDispatcher getEntityDispatcher(java.lang.String pAddress, int pPort)
Note that using null for the multicast address will, the first time, return a unicast EntityDispatcher. If, later, the getEntityDispatcher method is called with anything other than the original parameters, the program is stopped and an error message printed.
pAddress
- string format multicast address, usually in dotted decimal format
(eg, 225.7.8.10).pPort
- port in integer format, eg 6025.public void sendPdu(ProtocolDataUnit pPdu)
public void sendPdu(ProtocolDataUnit pdu, java.lang.String pDestinationHost, int pDestinationPort)
protected void debug(java.lang.String pDiagnostic)
protected void trace(java.lang.String pDiagnostic)
public void createUdpUnicastBehaviorStreamBuffer(java.lang.Integer pPortNumber)
public void createMulticastBehaviorStreamBuffer(java.lang.String pMcastAddress, java.lang.Integer pPortNumber)
public void startBehaviorStreamBufferThread()
Called by run(); this is the essential setup portion of the run loop. run() has enabled platform-specific security at this point, so startBehaviorStreamBufferThread doesn't have to worry about network sandboxes.
public void addListener(PduSubscriber pSubscriber, EntityID pEntityID)
This is synchronized to ensure serial access. (This might not actually be neccesary; I think hashtable is synchronized internally, but can't confirm that.) addListener and removeListener are the two methods that implement the PduPublisher interface. Clients subscribe via this mechanism. Note that more than one object may subscribe to an entityID.
addListener
in interface PduPublisher
public void removeListener(PduSubscriber listenerToRemove, EntityID pEntityID)
This process is repeated for each subscribing Scipt node in the VRML scene.
removeListener is synchronized to ensure serial access. If an object has subscribed multiple times, this will remove only one instance of the subscription. This is probably bad.
removeListener
in interface PduPublisher
public void checkForTrafficAndFallBackToTunnel(java.lang.String pTunnelAddress, int pTunnelPort, int pLocalPort)
public float getSleepInterval()
public void adviseSleepInterval(float anotherReadWriteInterval)
public void run()
This is the implementation of the runnable interface. Each method invocation is two-step process -- run calls SecurityStrategy's invokePrivilege(), which in turn calls back to this object -- which is required because some platforms require the security calls to be "above" in the stack. Just switching on the security parameters in strategy, and then returning and attempting to read from a socket, is not enough.
run
in interface java.lang.Runnable
public void doRun()
Called by run(); this is the essential portion of the run loop. run() has enabled platform-specific security at this point, so doRun doesn't have to worry about network sandboxes.
public void singleReadLoop()
public void shutdown()
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |