void ReplicaManager::Construct(Replica *replica, bool isCopy, SystemAddress systemAddress, bool broadcast) { RakAssert(replica); unsigned i; ParticipantStruct *participantStruct; CommandStruct replicaAndCommand; unsigned index; bool objectExists; replicaAndCommand.replica=replica; replicaAndCommand.userFlags=0; ReferencePointer(replica); for (i=0; i < participantList.Size(); i++) { participantStruct=participantList[i]; if ((broadcast==true && systemAddress!=participantStruct->systemAddress) || (broadcast==false && systemAddress==participantStruct->systemAddress)) { if (participantStruct->remoteObjectList.HasData(replica)==false) { index = GetCommandListReplicaIndex(participantStruct->commandList, replica, &objectExists); // index = participantStruct->commandList.GetIndexFromKey(replica, &objectExists); if (objectExists) { #ifdef _DEBUG // Implicit is only used for objects that were not already registered. RakAssert(isCopy==false); #endif participantStruct->commandList[index].command|=REPLICA_EXPLICIT_CONSTRUCTION; // Set this bit participantStruct->commandList[index].command&=0xFF ^ REPLICA_IMPLICIT_CONSTRUCTION; // Unset this bit if (defaultScope==true && (participantStruct->commandList[index].command & REPLICA_SCOPE_FALSE) == 0) participantStruct->commandList[index].command |= REPLICA_SCOPE_TRUE; } else { if (isCopy) replicaAndCommand.command=REPLICA_IMPLICIT_CONSTRUCTION; // Set this bit else replicaAndCommand.command=REPLICA_EXPLICIT_CONSTRUCTION; // Set this bit if (defaultScope==true) replicaAndCommand.command |= REPLICA_SCOPE_TRUE; participantStruct->commandList.Insert(replicaAndCommand, __FILE__, __LINE__); } } } } // Update immediately, otherwise if we take action on this object the first frame, the action packets will arrive before the object is created Update(); }
void ReplicaManager::SignalSerializationFlags(Replica *replica, SystemAddress systemAddress, bool broadcast, bool set, unsigned int flags) { RakAssert(replica); // Autoreference the pointer if necessary. This way the user can call functions on an object without having to worry // About the order of operations. ReferencePointer(replica); CommandStruct replicaAndCommand; replicaAndCommand.replica=replica; replicaAndCommand.userFlags=flags; replicaAndCommand.command=0; bool objectExists; unsigned i, index; ParticipantStruct *participantStruct; for (i=0; i < participantList.Size(); i++) { participantStruct=participantList[i]; if ((broadcast==true && systemAddress!=participantStruct->systemAddress) || (broadcast==false && systemAddress==participantStruct->systemAddress)) { // Set the flags in the object if the object exists index = participantStruct->remoteObjectList.GetIndexFromKey(replica, &objectExists); if (objectExists) { if (set) participantStruct->remoteObjectList[index].userFlags|=flags; // Set these user flags else participantStruct->remoteObjectList[index].userFlags&=~flags; // Unset these user flags } else { // The object is not yet created. Add to the pending command, or create a new command. // index = participantStruct->commandList.GetIndexFromKey(replica, &objectExists); index = GetCommandListReplicaIndex(participantStruct->commandList, replica, &objectExists); if (objectExists) { if (set) participantStruct->commandList[index].userFlags|=flags; // Set these user flags else participantStruct->commandList[index].userFlags&=~flags; // Unset these user flags } else if (set) { // Add a new command, since there are no pending commands for this object participantStruct->commandList.Insert(replicaAndCommand, __FILE__, __LINE__); } } } } }
void ReplicaManager::SetScope(Replica *replica, bool inScope, SystemAddress systemAddress, bool broadcast) { RakAssert(replica); // Autoreference the pointer if necessary. This way the user can call functions on an object without having to worry // About the order of operations. ReferencePointer(replica); // For each player that we want, flag to call SendScopeChange if inScope is different from what they already have unsigned i; ParticipantStruct *participantStruct; bool objectExists; unsigned index; CommandStruct replicaAndCommand; if (inScope) replicaAndCommand.command=REPLICA_SCOPE_TRUE; else replicaAndCommand.command=REPLICA_SCOPE_FALSE; replicaAndCommand.replica=replica; replicaAndCommand.userFlags=0; for (i=0; i < participantList.Size(); i++) { participantStruct=participantList[i]; if ((broadcast==true && systemAddress!=participantStruct->systemAddress) || (broadcast==false && systemAddress==participantStruct->systemAddress)) { // If there is already a pending command for this object, add to it. Otherwise, add a new pending command index = GetCommandListReplicaIndex(participantStruct->commandList, replica, &objectExists); // index = participantStruct->commandList.GetIndexFromKey(replica, &objectExists); if (objectExists) { // Update a pending command if (inScope) { participantStruct->commandList[index].command&=0xFF ^ REPLICA_SCOPE_FALSE; // Unset this bit participantStruct->commandList[index].command|=REPLICA_SCOPE_TRUE; // Set this bit } else { participantStruct->commandList[index].command&=0xFF ^ REPLICA_SCOPE_TRUE; // Unset this bit participantStruct->commandList[index].command|=REPLICA_SCOPE_FALSE; // Set this bit } } else { // Add a new command, since there are no pending commands for this object participantStruct->commandList.Insert(replicaAndCommand, __FILE__, __LINE__); } } } }
void ReplicaManager::DisableReplicaInterfaces(Replica *replica, unsigned char interfaceFlags) { bool objectExists; unsigned replicatedObjectsIndex; replicatedObjectsIndex = replicatedObjects.GetIndexFromKey(replica, &objectExists); if (objectExists==false) { // Autoreference the pointer if necessary. This way the user can call functions on an object without having to worry // About the order of operations. ReferencePointer(replica); replicatedObjectsIndex = replicatedObjects.GetIndexFromKey(replica, &objectExists); } replicatedObjects[replicatedObjectsIndex].allowedInterfaces&= 0xFF ^ interfaceFlags; }
unsigned int* ReplicaManager::AccessSerializationFlags(Replica *replica, SystemAddress systemAddress) { RakAssert(replica); // Autoreference the pointer if necessary. This way the user can call functions on an object without having to worry // About the order of operations. ReferencePointer(replica); unsigned index; bool objectExists; ParticipantStruct *participantStruct; CommandStruct replicaAndCommand; replicaAndCommand.replica=replica; replicaAndCommand.userFlags=0; replicaAndCommand.command=0; participantStruct=GetParticipantBySystemAddress(systemAddress); if (participantStruct) { // Set the flags in the object if the object exists index = participantStruct->remoteObjectList.GetIndexFromKey(replica, &objectExists); if (objectExists) { return &(participantStruct->remoteObjectList[index].userFlags); } else { // index = participantStruct->commandList.GetIndexFromKey(replica, &objectExists); index = GetCommandListReplicaIndex(participantStruct->commandList, replica, &objectExists); if (objectExists) { return &(participantStruct->commandList[index].userFlags); } else { // Add a new command, since there are no pending commands for this object //index = participantStruct->commandList.Insert(replicaAndCommand, __FILE__, __LINE__); // return &(participantStruct->commandList[index].userFlags); return & (participantStruct->commandList[participantStruct->commandList.Size()-1].userFlags); } } } // No such participant return 0; }
void ReplicaManager::Construct(Replica *replica, bool isCopy, PlayerID playerId, bool broadcast) { assert(replica); unsigned i; ParticipantStruct *participantStruct; CommandStruct replicaAndCommand; unsigned index; bool objectExists; replicaAndCommand.replica=replica; ReferencePointer(replica); for (i=0; i < participantList.Size(); i++) { participantStruct=participantList[i]; if ((broadcast==true && playerId!=participantStruct->playerId) || (broadcast==false && playerId==participantStruct->playerId)) { if (participantStruct->remoteObjectList.HasData(replica)==false) { index = participantStruct->commandList.GetIndexFromKey(replica, &objectExists); if (objectExists) { #ifdef _DEBUG // Implicit is only used for objects that were not already registered. assert(isCopy==false); #endif participantStruct->commandList[index].command|=REPLICA_EXPLICIT_CONSTRUCTION; // Set this bit participantStruct->commandList[index].command&=0xFF ^ REPLICA_IMPLICIT_CONSTRUCTION; // Unset this bit } else { if (isCopy) replicaAndCommand.command=REPLICA_IMPLICIT_CONSTRUCTION; // Set this bit else replicaAndCommand.command=REPLICA_EXPLICIT_CONSTRUCTION; // Set this bit participantStruct->commandList.Insert(replicaAndCommand.replica,replicaAndCommand); } } } } }
void ReplicaManager::SignalSerializeNeeded(Replica *replica, SystemAddress systemAddress, bool broadcast) { RakAssert(replica); // Autoreference the pointer if necessary. This way the user can call functions on an object without having to worry // About the order of operations. if (replicatedObjects.HasData(replica)==false) ReferencePointer(replica); // For each player that we want, if this object exists on that system, flag to call Serialize // (this may not necessarily happen - it depends on if the object is inScope when Update actually processes it.) unsigned i; ParticipantStruct *participantStruct; bool objectExists; unsigned index; CommandStruct replicaAndCommand; replicaAndCommand.command=REPLICA_SERIALIZE; replicaAndCommand.replica=replica; replicaAndCommand.userFlags=0; for (i=0; i < participantList.Size(); i++) { participantStruct=participantList[i]; if ((broadcast==true && systemAddress!=participantStruct->systemAddress) || (broadcast==false && systemAddress==participantStruct->systemAddress)) { // If there is already a pending command for this object, add to it. Otherwise, add a new pending command // index = participantStruct->commandList.GetIndexFromKey(replica, &objectExists); index = GetCommandListReplicaIndex(participantStruct->commandList, replica, &objectExists); if (objectExists) { participantStruct->commandList[index].command|=REPLICA_SERIALIZE; // Set this bit } else { // Add a new command, since there are no pending commands for this object participantStruct->commandList.Insert(replicaAndCommand, __FILE__, __LINE__); } } } }