#include <tnlGhostConnection.h>
Inheritance diagram for TNL::GhostConnection:
The GhostConnection is responsible for doing scoping calculations (on the server side) and transmitting most-recent ghost information to the client.
Ghosting is the most complex, and most powerful, part of TNL's capabilities. It allows the information sent to clients to be very precisely matched to what they need, so that no excess bandwidth is wasted. Each GhostConnection has a scope object that is responsible for determining what other NetObject instances are relevant to that connection's client. Each time GhostConnection sends a packet, NetObject::performScopeQuery() is called on the scope object, which calls GhostConnection::objectInScope() for each relevant object.
Each object that is in scope, and in need of update (based on its maskbits) is given a priority ranking by calling that object's getUpdatePriority() method. The packet is then filled with updates, ordered by priority. This way the most important updates get through first, with less important updates being sent as space is available.
There is a cap on the maximum number of ghosts that can be active through a GhostConnection at once. The enum GhostIdBitSize (defaults to 10) determines how many bits will be used to transmit the ID for each ghost, so the maximum number is 2^GhostIdBitSize or 1024. This can be easily raised; see the GhostConstants enum.
Each object ghosted is assigned a ghost ID; the client is only aware of the ghost ID. This acts to enhance simulation security, as it becomes difficult to map objects from one connection to another, or to reliably identify objects from ID alone. IDs are also reassigned based on need, making it hard to track objects that have fallen out of scope (as any object which the player shouldn't see would).
resolveGhost() is used on the client side, and resolveObjectFromGhostIndex() on the server side, to convert ghost IDs to object references.
Public Types | |
enum | GhostConstants { GhostIdBitSize = 10, GhostLookupTableSizeShift = 10, MaxGhostCount = (1 << GhostIdBitSize), GhostCountBitSize = GhostIdBitSize + 1, GhostLookupTableSize = (1 << GhostLookupTableSizeShift), GhostLookupTableMask = (GhostLookupTableSize - 1) } |
Public Member Functions | |
GhostConnection () | |
~GhostConnection () | |
void | setGhostFrom (bool ghostFrom) |
Sets whether ghosts transmit from this side of the connection. | |
void | setGhostTo (bool ghostTo) |
Sets whether ghosts are allowed from the other side of the connection. | |
bool | doesGhostFrom () |
Does this GhostConnection ghost NetObjects to the remote host? | |
bool | doesGhostTo () |
Does this GhostConnection receive ghosts from the remote host? | |
U32 | getGhostingSequence () |
Returns the sequence number of this ghosting session. | |
void | setScopeObject (NetObject *object) |
Sets the object that is queried at each packet to determine what NetObjects should be ghosted on this connection. | |
NetObject * | getScopeObject () |
void | objectInScope (NetObject *object) |
Indicate that the specified object is currently in scope. | |
void | objectLocalScopeAlways (NetObject *object) |
The specified object should be always in scope for this connection. | |
void | objectLocalClearAlways (NetObject *object) |
The specified object should not be always in scope for this connection. | |
NetObject * | resolveGhost (S32 id) |
Given an object's ghost id, returns the ghost of the object (on the client side). | |
NetObject * | resolveGhostParent (S32 id) |
Given an object's ghost id, returns the source object (on the server side). | |
void | ghostPushNonZero (GhostInfo *gi) |
Moves the specified GhostInfo into the range of the ghost array for non-zero updateMasks. | |
void | ghostPushToZero (GhostInfo *gi) |
Moves the specified GhostInfo into the range of the ghost array for zero updateMasks. | |
void | ghostPushZeroToFree (GhostInfo *gi) |
Moves the specified GhostInfo into the range of the ghost array for free (unused) GhostInfos. | |
void | ghostPushFreeToZero (GhostInfo *info) |
Moves the specified GhostInfo from the free area into the range of the ghost array for zero updateMasks. | |
S32 | getGhostIndex (NetObject *object) |
Returns the client-side ghostIndex of the specified server object, or -1 if the object is not available on the client. | |
bool | isGhostAvailable (NetObject *object) |
Returns true if the object is available on the client. | |
void | resetGhosting () |
Stops ghosting objects from this GhostConnection to the remote host, which causes all ghosts to be destroyed on the client. | |
void | activateGhosting () |
Begins ghosting objects from this GhostConnection to the remote host, starting with the GhostAlways objects. | |
bool | isGhosting () |
Returns true if this connection is currently ghosting objects to the remote host. | |
void | detachObject (GhostInfo *info) |
Notifies the GhostConnection that the specified GhostInfo should no longer be scoped to the client. | |
TNL_DECLARE_RPC (rpcStartGhosting,(U32 sequence)) | |
RPC from server to client before the GhostAlwaysObjects are transmitted. | |
TNL_DECLARE_RPC (rpcReadyForNormalGhosts,(U32 sequence)) | |
RPC from client to server sent when the client receives the rpcGhostAlwaysActivated. | |
TNL_DECLARE_RPC (rpcEndGhosting,()) | |
RPC from server to client sent to notify that ghosting should stop. | |
Protected Member Functions | |
PacketNotify * | allocNotify () |
Override of EventConnection's allocNotify, to use the GhostPacketNotify structure. | |
void | packetDropped (PacketNotify *notify) |
Override to properly update the GhostInfo's for all ghosts that had upates in the dropped packet. | |
void | packetReceived (PacketNotify *notify) |
Override to update flags associated with the ghosts updated in this packet. | |
void | prepareWritePacket () |
Performs the scoping query in order to determine if there is data to send from this GhostConnection. | |
void | writePacket (BitStream *bstream, PacketNotify *notify) |
Override to write ghost updates into each packet. | |
void | readPacket (BitStream *bstream) |
Override to read updated ghost information from the packet stream. | |
bool | isDataToTransmit () |
Override to check if there is data pending on this GhostConnection. | |
void | clearGhostInfo () |
void | deleteLocalGhosts () |
bool | validateGhostArray () |
void | freeGhostInfo (GhostInfo *) |
virtual void | onStartGhosting () |
Notifies subclasses that the remote host is about to start ghosting objects. | |
virtual void | onEndGhosting () |
Notifies subclasses that the server has stopped ghosting objects on this connection. | |
Protected Attributes | |
GhostInfo ** | mGhostArray |
Array of GhostInfo structures used to track all the objects ghosted by this side of the connection. | |
S32 | mGhostZeroUpdateIndex |
Index in mGhostArray of first ghost with 0 update mask (ie, with no updates). | |
S32 | mGhostFreeIndex |
index in mGhostArray of first free ghost. | |
bool | mGhosting |
Am I currently ghosting objects over? | |
bool | mScoping |
Am I currently allowing objects to be scoped? | |
U32 | mGhostingSequence |
Sequence number describing this ghosting session. | |
NetObject ** | mLocalGhosts |
Local ghost array for remote objects, or NULL if mGhostTo is false. | |
GhostInfo * | mGhostRefs |
Allocated array of ghostInfos, or NULL if mGhostFrom is false. | |
GhostInfo ** | mGhostLookupTable |
Table indexed by object id->GhostInfo, or NULL if mGhostFrom is false. | |
SafePtr< NetObject > | mScopeObject |
The local NetObject that performs scoping queries to determine what objects to ghost to the client. | |
Private Types | |
typedef EventConnection | Parent |
Friends | |
class | ConnectionMessageEvent |
|
Reimplemented from TNL::EventConnection. Reimplemented in TNLTest::TestConnection. |
|
|
|
|
|
|
Override of EventConnection's allocNotify, to use the GhostPacketNotify structure.
Reimplemented from TNL::EventConnection. |
|
Override to properly update the GhostInfo's for all ghosts that had upates in the dropped packet.
Reimplemented from TNL::EventConnection. |
|
Override to update flags associated with the ghosts updated in this packet.
Reimplemented from TNL::EventConnection. |
|
Performs the scoping query in order to determine if there is data to send from this GhostConnection.
Reimplemented from TNL::NetConnection. |
|
Override to write ghost updates into each packet.
Reimplemented from TNL::EventConnection. |
|
Override to read updated ghost information from the packet stream.
Reimplemented from TNL::EventConnection. |
|
Override to check if there is data pending on this GhostConnection.
Reimplemented from TNL::EventConnection. Reimplemented in TNLTest::TestConnection. |
|
|
|
|
|
|
|
|
|
Notifies subclasses that the remote host is about to start ghosting objects.
|
|
Notifies subclasses that the server has stopped ghosting objects on this connection.
|
|
Sets whether ghosts transmit from this side of the connection.
|
|
Sets whether ghosts are allowed from the other side of the connection.
|
|
Does this GhostConnection ghost NetObjects to the remote host?
|
|
Does this GhostConnection receive ghosts from the remote host?
|
|
Returns the sequence number of this ghosting session.
|
|
Sets the object that is queried at each packet to determine what NetObjects should be ghosted on this connection.
|
|
|
|
Indicate that the specified object is currently in scope. Method called by the scope object to indicate that the specified object is in scope. |
|
The specified object should be always in scope for this connection.
|
|
The specified object should not be always in scope for this connection.
|
|
Given an object's ghost id, returns the ghost of the object (on the client side).
|
|
Given an object's ghost id, returns the source object (on the server side).
|
|
Moves the specified GhostInfo into the range of the ghost array for non-zero updateMasks.
|
|
Moves the specified GhostInfo into the range of the ghost array for zero updateMasks.
|
|
Moves the specified GhostInfo into the range of the ghost array for free (unused) GhostInfos.
|
|
Moves the specified GhostInfo from the free area into the range of the ghost array for zero updateMasks.
|
|
Returns the client-side ghostIndex of the specified server object, or -1 if the object is not available on the client.
|
|
Returns true if the object is available on the client.
|
|
Stops ghosting objects from this GhostConnection to the remote host, which causes all ghosts to be destroyed on the client.
|
|
Begins ghosting objects from this GhostConnection to the remote host, starting with the GhostAlways objects.
|
|
Returns true if this connection is currently ghosting objects to the remote host.
|
|
Notifies the GhostConnection that the specified GhostInfo should no longer be scoped to the client.
|
|
RPC from server to client before the GhostAlwaysObjects are transmitted.
|
|
RPC from client to server sent when the client receives the rpcGhostAlwaysActivated.
|
|
RPC from server to client sent to notify that ghosting should stop.
|
|
|
|
Array of GhostInfo structures used to track all the objects ghosted by this side of the connection. For efficiency, ghosts are stored in three segments - the first segment contains GhostInfos that have pending updates, the second ghostrefs that need no updating, and last, free GhostInfos that may be reused. |
|
Index in mGhostArray of first ghost with 0 update mask (ie, with no updates).
|
|
index in mGhostArray of first free ghost.
|
|
Am I currently ghosting objects over?
|
|
Am I currently allowing objects to be scoped?
|
|
Sequence number describing this ghosting session.
|
|
Local ghost array for remote objects, or NULL if mGhostTo is false.
|
|
Allocated array of ghostInfos, or NULL if mGhostFrom is false.
|
|
Table indexed by object id->GhostInfo, or NULL if mGhostFrom is false.
|
|
The local NetObject that performs scoping queries to determine what objects to ghost to the client.
|