//===========================================================================// // File: Replicator.cpp // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 11/29/94 JMA Initial coding. // // 08/25/97 JMA Infrastructure changes // // 08/25/97 ECH Infrastructure changes // //---------------------------------------------------------------------------// // Copyright (C) 1994-97, Virtual World Entertainment, Inc. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include "AdeptHeaders.hpp" #include "Replicator.hpp" #include "Connection.hpp" //############################################################################# //########################## Replicator ################################# //############################################################################# ReplicatorID ReplicatorID::Null; Replicator::ClassData *Replicator::DefaultData = NULL; const Receiver::MessageEntry Replicator::MessageEntries[]= { MESSAGE_ENTRY(Replicator, Destroy) }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Replicator::InitializeClass() { Verify(!DefaultData); DefaultData = new ClassData( ReplicatorClassID, "Adept::Replicator", Receiver::DefaultData, ELEMENTS(MessageEntries), MessageEntries, NULL, NULL ); Register_Object(DefaultData); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Replicator::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Replicator::CreateMessage* Replicator::SaveMakeMessage(MemoryStream *stream, ResourceFile *res_file) { Check_Object(this); Check_Object(stream); // //--------------------------------------------------------------------- // Make sure there is enough room for the factory request on the stream //--------------------------------------------------------------------- // stream->AllocateBytes(sizeof(CreateMessage)); CreateMessage *message = Cast_Pointer(CreateMessage*, stream->GetPointer()); message->messageLength = sizeof(*message); // //--------------------------- // Create the factory request //--------------------------- // message->messageID = Connection::ReplicateMessageID; message->messagePriority = DefaultEventPriority; message->messageFlags = CreateMessage::DefaultFlags; message->replicatorFlags = replicatorFlags; message->replicatorID.connectionID = 0; message->replicatorID.localID = 1; message->classID = GetClassID(); return message; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Replicator::Replicator( ClassData *class_data, const CreateMessage *message, ReplicatorID *base_id ): Receiver(class_data) { Check_Pointer(this); Check_Object(message); // //--------------------------------- // Extract our data from the stream //--------------------------------- // Verify(message->classID == GetClassID()); replicatorFlags = message->replicatorFlags; // //--------------------- // Get the replicant ID //--------------------- // replicatorID = *base_id; ++*base_id; owningConnection = Network::GetInstance()->GetConnection(replicatorID.connectionID); Check_Object(owningConnection); if(owningConnection == Connection::Hermit) { Verify(GetReplicatorMode() == HermitMode); } // here we go... // if we are the server than we own everything.. if (owningConnection != Connection::Hermit) { SetReplicatorMode(MasterMode); Verify(GetReplicatorMode() != HermitMode); if (Network::GetInstance()->AmIServer()) { // if we don't own it and it is a master it will be the ServerMasterMode ( the receiver of a ClientMaster ) if ((owningConnection != Connection::Local) && (owningConnection != Connection::Hermit)) { if (GetReplicatorMode() == MasterMode) SetReplicatorMode(ServerMasterMode); } } else { // we are a client so we don't own anything. if ((owningConnection == Connection::Local) && (GetReplicatorMode() == MasterMode)) { SetReplicatorMode(ClientMasterMode); } else if ((owningConnection != Connection::Local) && GetReplicatorMode() == MasterMode) { SetReplicatorMode(ReplicantMode); } } } // //---------------------------- // Hook up to the host manager //---------------------------- // owningConnection->AddReplicator(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Replicator::~Replicator() { DESTRUCTOR("Replicator"); // //-------------------------------------------------------------- // Notify replicator manager, the connection to the host manager // is removed automatically //-------------------------------------------------------------- // if (owningConnection) { Check_Object(owningConnection); owningConnection->ReplicatorDestroyed(this); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Replicator::Reuse( const Replicator::CreateMessage *message, ReplicatorID *base_id ) { Check_Pointer(this); Check_Object(message); // //--------------------------------- // Extract our data from the stream //--------------------------------- // Verify(message->classID == GetClassID()); replicatorFlags = message->replicatorFlags; // //--------------------- // Get the replicant ID //--------------------- // replicatorID = *base_id; ++*base_id; Verify(!owningConnection); owningConnection = Network::GetInstance()->GetConnection(replicatorID.connectionID); Check_Object(owningConnection); if(owningConnection == Connection::Hermit) { Verify(GetReplicatorMode() == HermitMode); } // here we go... // if we are the server than we own everything.. if (owningConnection != Connection::Hermit) { Verify(GetReplicatorMode() != HermitMode); SetReplicatorMode(MasterMode); if (Network::GetInstance()->AmIServer()) { // if we don't own it and it is a master it will be the ServerMasterMode ( the receiver of a ClientMaster ) if ((owningConnection != Connection::Local) && (owningConnection != Connection::Hermit)) { if (GetReplicatorMode() == MasterMode) SetReplicatorMode(ServerMasterMode); } } else { // we are a client so we don't own anything. if ((owningConnection == Connection::Local) && (GetReplicatorMode() == MasterMode)) { SetReplicatorMode(ClientMasterMode); } else if ((owningConnection != Connection::Local) && GetReplicatorMode() == MasterMode) { SetReplicatorMode(ReplicantMode); } } } // //---------------------------- // Hook up to the host manager //---------------------------- // owningConnection->AddReplicator(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Replicator::Respawn( const Replicator::CreateMessage *message ) { Check_Pointer(this); Check_Object(message); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Replicator::Dispatch(const Receiver::Message *incoming) { Check_Object(this); Check_Object(incoming); STOP(("Replicator::Distpatch has been disabled for networking. Please use Receiver::Receive instead!")); #if 0 // //------------------------------------------------------ // Call Receiver if it is not a replicator aware message //------------------------------------------------------ // if (incoming->messageID < Receiver::NextMessageID) Receiver::Dispatch(incoming); // //--------------------------------------------- // Initialize the replicator information fields //--------------------------------------------- // const Message *message = Cast_Pointer(const Message*, incoming); Check_Object(message); // //------------------------------------------------------------------- // If this is a replicant instance, reroute the message to the master //------------------------------------------------------------------- // if (GetReplicatorMode() == ReplicantMode) { Check_Object(owningConnection); owningConnection->SendToMaster(this, message); return; } // //-------------------------------------------- // Otherwise, go ahead and receive the message //-------------------------------------------- // Receiver::Receive(message); #endif } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Replicator::DispatchToReplicants(const Message *message) { Check_Object(this); Check_Object(message); Check_Object(owningConnection); owningConnection->BroadcastToReplicants(this, message); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Replicator::DestroyMessageHandler(const DestroyMessage *message) { Check_Object(this); Check_Object(message); Verify(message->messageID == DestroyMessageID); delete this; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Replicator::TestInstance() { Verify(IsDerivedFrom(DefaultData)); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void Replicator__ClassData::TestInstance() { Verify(IsDerivedFrom(Replicator::DefaultData)); }