#include <ReplicaManager.h>
Public Member Functions | |
ReplicaManager () | |
Constructor. | |
virtual | ~ReplicaManager () |
Destructor. | |
void | AssertReplicatedObjectsClear (void) |
void | AssertParticipantsClear (void) |
void | SetAutoParticipateNewConnections (bool autoAdd) |
bool | AddParticipant (SystemAddress systemAddress) |
bool | RemoveParticipant (SystemAddress systemAddress) |
void | Construct (Replica *replica, bool isCopy, SystemAddress systemAddress, bool broadcast) |
void | Destruct (Replica *replica, SystemAddress systemAddress, bool broadcast) |
void | ReferencePointer (Replica *replica) |
void | DereferencePointer (Replica *replica) |
void | SetScope (Replica *replica, bool inScope, SystemAddress systemAddress, bool broadcast) |
void | SignalSerializeNeeded (Replica *replica, SystemAddress systemAddress, bool broadcast) |
void | SetReceiveConstructionCB (ReceiveConstructionInterface *receiveConstructionInterface) |
void | SetDownloadCompleteCB (SendDownloadCompleteInterface *sendDownloadComplete, ReceiveDownloadCompleteInterface *receiveDownloadComplete) |
void | SetSendChannel (unsigned char channel) |
void | SetAutoConstructToNewParticipants (bool autoConstruct) |
void | SetDefaultScope (bool scope) |
void | SetAutoSerializeInScope (bool autoSerialize) |
void | Update (RakPeerInterface *peer) |
void | EnableReplicaInterfaces (Replica *replica, unsigned char interfaceFlags) |
void | DisableReplicaInterfaces (Replica *replica, unsigned char interfaceFlags) |
bool | IsConstructed (Replica *replica, SystemAddress systemAddress) |
bool | IsInScope (Replica *replica, SystemAddress systemAddress) |
unsigned | GetReplicaCount (void) const |
Replica * | GetReplicaAtIndex (unsigned index) |
unsigned | GetParticipantCount (void) const |
SystemAddress | GetParticipantAtIndex (unsigned index) |
bool | HasParticipant (SystemAddress systemAddress) |
void | SignalSerializationFlags (Replica *replica, SystemAddress systemAddress, bool broadcast, bool set, unsigned int flags) |
unsigned int * | AccessSerializationFlags (Replica *replica, SystemAddress systemAddress) |
Protected Member Functions | |
void | Clear (void) |
Frees all memory. | |
void | OnAttach (RakPeerInterface *peer) |
PluginReceiveResult | OnReceive (RakPeerInterface *peer, Packet *packet) |
void | OnCloseConnection (RakPeerInterface *peer, SystemAddress systemAddress) |
void | OnShutdown (RakPeerInterface *peer) |
Protected Attributes | |
DataStructures::OrderedList < Replica *, RegisteredReplica, ReplicaManager::RegisteredReplicaComp > | replicatedObjects |
DataStructures::OrderedList < SystemAddress, ParticipantStruct *, ReplicaManager::ParticipantStructComp > | participantList |
void ReplicaManager::AssertReplicatedObjectsClear | ( | void | ) |
If you think all objects should have been removed, call this to assert on any that were not. Useful for debugging shutdown or restarts
void ReplicaManager::AssertParticipantsClear | ( | void | ) |
If you think all participants should have been removed, call this to assert on any that were not. Useful for debugging shutdown or restarts
void ReplicaManager::SetAutoParticipateNewConnections | ( | bool | autoAdd | ) |
Do or don't automatically call AddParticipant when new systems connect to us. Won't add automatically add connections that already exist before this was called Defaults to false
[in] | autoAdd | True or false, to add or not |
bool ReplicaManager::AddParticipant | ( | SystemAddress | systemAddress | ) |
Adds a participant to the ReplicaManager system. Only these participants get packets and we only accept ReplicaManager packets from these participants. This way you can have connections that have nothing to do with your game - for example remote console logins
[in] | systemAddress | Which player you are referring to |
bool ReplicaManager::RemoveParticipant | ( | SystemAddress | systemAddress | ) |
Removes a participant from the data replicator system This is called automatically on ID_DISCONNECTION_NOTIFICATION and ID_CONNECTION_LOST messages, as well as CloseConnection() calls.
[in] | systemAddress | Which player you are referring to |
void ReplicaManager::Construct | ( | Replica * | replica, | |
bool | isCopy, | |||
SystemAddress | systemAddress, | |||
bool | broadcast | |||
) |
Construct the specified object on the specified system Replica::SendConstruction will be called immediately, this is a change from before, because otherwise if you later send other packets that refer to this object, this object won't exist yet. The other system will get Replica::ReceiveConstruction If your system assigns NetworkIDs, do so before calling Replicate as the NetworkID is automatically included in the packet. Replicate packets that are sent to systems that already have this NetworkID are ignored.
To perform scoping and serialize updates on an object already created by another system, call Construct with isCopy true.
Setting isCopy true will consider the object created on that system without actually trying to create it.
If you don't need to send updates to other systems for this object, it is more efficient to use ReferencePointer instead.
In a client / server environment, be sure to call Construct() with isCopy true to let the ReplicaManager know that the server has this object. Otherwise you won't be able to send Scope or Serialize changes to the server.
[in] | replica | A pointer to your object |
[in] | isCopy | True means that this is a copy of an object that already exists on the systems specified by systemAddress and broadcast. If true, we will consider these systems as having the object without sending a datagram to them. SendConstruction will NOT be called for objects which isCopy is true. |
[in] | systemAddress | The participant to send the command to, or the one to exclude if broadcast is true. |
[in] | broadcast | True to send to all. If systemAddress!=UNASSIGNED_SYSTEM_ADDRESS then this means send to all but that participant |
void ReplicaManager::Destruct | ( | Replica * | replica, | |
SystemAddress | systemAddress, | |||
bool | broadcast | |||
) |
Call this with your game objects to have them send Replica::SendDestruction. This will be sent immediately to all participants that have this object. Those participants will get Replica::ReceiveDestruction All pending calls for this object, for this player, are canceled. Nothing is actually deleted - this just signals that the other system called this function. It is up to you to actually delete your object.
For the other system to get the network message, SetNetworkID on that object must have been called with the same value as GetNetworkID for this object.
Calling ( with systemAddress==UNASSIGNED_SYSTEM_ADDRESS and broadcast true is equivalent to calling DereferencePointer except that Destruct also sends the destruct packet.
It is important to call this before deleting your object. Otherwise this system will crash the next Update call.
[in] | replica | A pointer to your object |
[in] | systemAddress | The participant to send the command to, or the one to exclude if broadcast is true. |
[in] | broadcast | True to send to all systems that have the object. If systemAddress!=UNASSIGNED_SYSTEM_ADDRESS then this means send to all but that participant |
void ReplicaManager::ReferencePointer | ( | Replica * | replica | ) |
This makes sure the object is tracked, so you can get calls on it. This will automatically happen if you call Construct, SetScope, or SignalSerializeNeeded with replica Otherwise you need to call this, or for security the system will ignore calls that reference this object, even if given a valid NetworkID Duplicate calls are safe and are simply ignored. Best place to put this is in the SetReceiveConstructionCB callback so that all your objects are registered.
[in] | replica | A pointer to your object |
Try setting the network ID manager if the user forgot
void ReplicaManager::DereferencePointer | ( | Replica * | replica | ) |
Call this before you delete replica. This locally removes all references to this pointer. No messages are sent. Best place to put this is in the destructor of replica
[in] | replica | A pointer to your object |
void ReplicaManager::SetScope | ( | Replica * | replica, | |
bool | inScope, | |||
SystemAddress | systemAddress, | |||
bool | broadcast | |||
) |
Sets the scope of your object in relation to another participant. Objects that are in-scope for that participant will send out Replica::Serialize calls. Otherwise Serialize calls are not sent. Scoping is useful when you want to disable sends to an object temporarily, without deleting that object. Calling this results in Replica::SendScopeChange being called on the local object and Replica::ReceiveScopeChange on the remote object if that object has been created on that remote system. Your game should ensure that objects not in scope are hidden, but not deallocated, on the remote system. Replica::SendScopeChange with inScope as true will automatically perform Replica::Serialize
For the other system to get the network message, that object must have an NetworkID (set by SetNetworkID()) the same as our object's NetworkID (returned from GetNetworkID()).
Individual objects can refuse to perform the SendScopeChange call by not writing to the output bitstream while returning true.
[in] | replica | An object previously registered with Replicate |
[in] | inScope | in scope or not. |
[in] | systemAddress | The participant to send the command to, or the one to exclude if broadcast is true. |
[in] | broadcast | True to send to all. If systemAddress!=UNASSIGNED_SYSTEM_ADDRESS then this means send to all but that participant |
void ReplicaManager::SignalSerializeNeeded | ( | Replica * | replica, | |
SystemAddress | systemAddress, | |||
bool | broadcast | |||
) |
Signal that data has changed and we need to call Serialize() on the replica object. This will happen if the object has been registered, Replica::SendConstruction wrote to outBitStream and returned true, and the object is in scope for this player.
For the other system to get the network message, that object must have an NetworkID (set by SetNetworkID()) the same as our object's NetworkID (returned from GetNetworkID()).
[in] | replica | An object previously registered with Replicate |
[in] | systemAddress | The participant to send the command to, or the one to exclude if broadcast is true. |
[in] | broadcast | True to send to all. If systemAddress!=UNASSIGNED_SYSTEM_ADDRESS then this means send to all but that participant |
void ReplicaManager::SetReceiveConstructionCB | ( | ReceiveConstructionInterface * | receiveConstructionInterface | ) |
Required callback Set your callback to parse requests to create new objects. Specifically, when Replica::SendConstruction is called and the networkID of the object is either unset or can't be found, this callback will get that call. How do you know what object to create? It's up to you, but I suggest in Replica::SendConstruction you encode the class name. The best way to do this is with the StringTable class.
[in] | ReceiveConstructionInterface | An instance of a class that implements ReceiveConstructionInterface |
void ReplicaManager::SetDownloadCompleteCB | ( | SendDownloadCompleteInterface * | sendDownloadComplete, | |
ReceiveDownloadCompleteInterface * | receiveDownloadComplete | |||
) |
Set your callbacks to be called when, after connecting to another system, you get all objects that system is going to send to you when it is done with the first iteration through the object list. Optional if you want to send and receive the download complete notification
[in] | sendDownloadComplete | A class that implements the SendDownloadCompleteInterface interface. |
[in] | receiveDownloadComplete | A class that implements the ReceiveDownloadCompleteInterface interface. |
void ReplicaManager::SetSendChannel | ( | unsigned char | channel | ) |
This channel will be used for all RakPeer::Send calls
[in] | channel | The channel to use for internal RakPeer::Send calls from this system. Defaults to 0. |
void ReplicaManager::SetAutoConstructToNewParticipants | ( | bool | autoConstruct | ) |
This means automatically construct all known objects to all new participants Has no effect on existing participants Useful if your architecture always has all objects constructed on all systems all the time anyway, or if you want them to normally start constructed Defaults to false.
[in] | autoConstruct | true or false, as desired. |
void ReplicaManager::SetDefaultScope | ( | bool | scope | ) |
Set the default scope for new objects to all players. Defaults to false, which means Serialize will not be called for new objects automatically. If you set this to true, then new players will get existing objects, and new objects will be sent to existing players This only applies to players that connect and objects that are replicated after this call. Existing object scopes are not affected. Useful to set to true if you don't use scope, or if all objects normally start in scope
[in] | scope | The default scope to use. |
void ReplicaManager::SetAutoSerializeInScope | ( | bool | autoSerialize | ) |
When an object goes in scope for a system, you normally want to serialize that object to that system. Setting this flag to true will call Serialize for you automatically when SendScopeChange returns REPLICA_PROCESSING_DONE and the scopeTrue parameter is true Defaults to false
[in] | autoSerialize | True or false as needed. |
void ReplicaManager::Update | ( | RakPeerInterface * | peer | ) | [virtual] |
Processes all pending commands and does sends as needed. This is called automatically when RakPeerInterface::Receive is called. Depending on where you call RakPeerInterface::Receive you may also wish to call this manually for better responsiveness. For example, if you call RakPeerInterface::Receive at the start of each game tick, this means you would have to wait a render cycle, causing
[in] | peer | Pointer to a valid instance of RakPeerInterface used to perform sends |
Reimplemented from PluginInterface.
void ReplicaManager::EnableReplicaInterfaces | ( | Replica * | replica, | |
unsigned char | interfaceFlags | |||
) |
Lets you enable calling any or all of the interface functions in an instance of Replica This setting is the same for all participants for this object, so if you want per-participant permissions you will need to handle that inside your implementation All functions enabled by default.
[in] | replica | The object you are referring to |
[in] | interfaceFlags | A bitwise-OR of REPLICA_SEND_CONSTRUCTION ... REPLICA_SET_ALL corresponding to the function of the same name |
void ReplicaManager::DisableReplicaInterfaces | ( | Replica * | replica, | |
unsigned char | interfaceFlags | |||
) |
Lets you disable calling any or all of the interface functions in an instance of Replica This setting is the same for all participants for this object, so if you want per-participant permissions you will need to handle that inside your implementation All functions enabled by default.
For example, on the server you may wish to disable all receive functions so clients cannot change server objects.
[in] | replica | The object you are referring to |
[in] | interfaceFlags | A bitwise-OR of REPLICA_SEND_CONSTRUCTION ... REPLICA_SET_ALL corresponding to the function of the same name |
bool ReplicaManager::IsConstructed | ( | Replica * | replica, | |
SystemAddress | systemAddress | |||
) |
Tells us if a particular system got a SendConstruction() message from this object. e.g. does this object exist on this remote system? This is set by the user when calling Replicate and sending (any) data to outBitStream in Replica::SendConstruction
[in] | replica | The object we are checking |
[in] | systemAddress | The system we are checking |
bool ReplicaManager::IsInScope | ( | Replica * | replica, | |
SystemAddress | systemAddress | |||
) |
Tells us if a particular object is in scope for a particular system This is set by the user when calling SetScope and sending (any) data to outBitstream in Replica::SendScopeChange
[in] | replica | The object we are checking |
[in] | systemAddress | The system we are checking |
unsigned ReplicaManager::GetReplicaCount | ( | void | ) | const |
Returns how many Replica instances are registered. This number goes up with each non-duplicate call to Replicate and down with each non-duplicate call to Dereplicate Used for GetReplicaAtIndex if you want to perform some object on all registered Replica objects.
Replica * ReplicaManager::GetReplicaAtIndex | ( | unsigned | index | ) |
Returns a previously registered Replica *, from index 0 to GetReplicaCount()-1. The order that Replica * objects are returned in is arbitrary (it currently happens to be ordered by pointer address). Calling Dereplicate immediately deletes the Replica * passed to it, so if you call Dereplicate while using this function the array will be shifted over and the current index will now reference the next object in the array, if there was one.
[in] | index | An index, from 0 to GetReplicaCount()-1. |
unsigned ReplicaManager::GetParticipantCount | ( | void | ) | const |
Returns the number of unique participants added with AddParticipant As these systems disconnect, they are no longer participants, so this accurately returns how many participants are using the system
SystemAddress ReplicaManager::GetParticipantAtIndex | ( | unsigned | index | ) |
Returns a SystemAddress previously added with AddParticipant
[in] | index | An index, from 0 to GetParticipantCount()-1. |
bool ReplicaManager::HasParticipant | ( | SystemAddress | systemAddress | ) |
Returns if a participant has been added
void ReplicaManager::SignalSerializationFlags | ( | Replica * | replica, | |
SystemAddress | systemAddress, | |||
bool | broadcast, | |||
bool | set, | |||
unsigned int | flags | |||
) |
Each participant has a per-remote object bitfield passed to the Replica::Serialize call. This function can set or unset these flags for one or more participants at the same time. Flags are NOT automatically cleared on serialize. You must clear them when you want to do so.
[in] | replica | An object previously registered with Replicate |
[in] | systemAddress | The participant to set the flags for |
[in] | broadcast | True to apply to all participants. If systemAddress!=UNASSIGNED_SYSTEM_ADDRESS then this means send to all but that participant |
[in] | set | True set the bits set in flags with the per-object per-system serialization flags. False to unset these bits. |
[in] | flags | Modifier to the Per-object per-system flags sent to Replica::Serialize. See the parameter /a set |
unsigned int * ReplicaManager::AccessSerializationFlags | ( | Replica * | replica, | |
SystemAddress | systemAddress | |||
) |
Each participant has a per-remote object bitfield passed to the Replica::Serialize call. This function is used to read and change these flags directly for a single participant. It gives more control than SignalSerializationFlags but only works for a single participant at a time.
[in] | replica | An object previously registered with Replicate |
[in] | systemAddress | The participant to read/write the flags for |
void ReplicaManager::OnAttach | ( | RakPeerInterface * | peer | ) | [protected, virtual] |
Called when the interface is attached
[in] | peer | the instance of RakPeer that is calling Receive |
Reimplemented from PluginInterface.
PluginReceiveResult ReplicaManager::OnReceive | ( | RakPeerInterface * | peer, | |
Packet * | packet | |||
) | [protected, virtual] |
OnReceive is called for every packet.
[in] | peer | the instance of RakPeer that is calling Receive |
[in] | packet | the packet that is being returned to the user |
Reimplemented from PluginInterface.
void ReplicaManager::OnCloseConnection | ( | RakPeerInterface * | peer, | |
SystemAddress | systemAddress | |||
) | [protected, virtual] |
Called when a connection is dropped because the user called RakPeer::CloseConnection() for a particular system
[in] | peer | the instance of RakPeer that is calling Receive |
[in] | systemAddress | The system whose connection was closed |
Reimplemented from PluginInterface.
void ReplicaManager::OnShutdown | ( | RakPeerInterface * | peer | ) | [protected, virtual] |
Called when RakPeer is shutdown
[in] | peer | the instance of RakPeer that is calling Receive |
Reimplemented from PluginInterface.
DataStructures::OrderedList<Replica *, RegisteredReplica, ReplicaManager::RegisteredReplicaComp> ReplicaManager::replicatedObjects [protected] |
List of objects replicated in the Replicate function. Used to make sure queued actions happen on valid pointers, since objects are removed from the list in Dereplicate Sorted by raw pointer address using the default sort
DataStructures::OrderedList<SystemAddress, ParticipantStruct *, ReplicaManager::ParticipantStructComp> ReplicaManager::participantList [protected] |
List of participants Each participant has several queues of pending commands Sorted by systemAddress The only complexity is that each participant also needs a list of objects that mirror the variable replicatedObjects so we know per-player if that object is in scope