//===========================================================================// // File: interest.cc // // Project: MUNGA Brick: Interest Manager // // Contents: Interface specification Interest Manager // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 10/28/94 ECH Initial coding. // // 11/03/94 ECH Develop to munga spec // // 11/29/94 JMA Changed Identities to IDs // // 02/10/95 CPB Added GaugeInterestType // //---------------------------------------------------------------------------// // Copyright (C) 1994-1995, Virtual World Entertainment, Inc. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include #pragma hdrstop #if !defined(INTEREST_HPP) # include #endif #if !defined(REGISTRY_HPP) # include #endif #if !defined(MISSION_HPP) # include #endif #if !defined(BOXTREE_HPP) # include #endif #if !defined(RENDERER_HPP) # include #endif #if !defined(CULTURAL_HPP) # include #endif #if !defined(APP_HPP) #include #endif #if !defined(HOSTMGR_HPP) #include #endif //############################################################################# //####################### InterestManager ############################### //############################################################################# // //-------------------------------------------------------------------- // InterestManager data //-------------------------------------------------------------------- // unsigned char InterestManager::messageBuildBuffer[INTERESTMANAGER_MESSAGE_BUFFER_SIZE]; InterestManager::SharedData InterestManager::DefaultData( InterestManager::ClassDerivations, InterestManager::MessageHandlers ); Derivation InterestManager::ClassDerivations( NetworkClient::ClassDerivations, "InterestManager" ); const Receiver::HandlerEntry InterestManager::MessageHandlerEntries[]= { // // NewDynamicEntityMessageID // { InterestManager::NewDynamicEntityMessageID, "NewDynamicEntity", (InterestManager::Handler)&InterestManager::NewDynamicEntityHandler }, // // DestroyDynamicEntityMessageID // { InterestManager::DestroyDynamicEntityMessageID, "DestroyDynamicEntity", (InterestManager::Handler)&InterestManager::DestroyDynamicEntityHandler }, // // EntitySubscribeToUpdatesMessageID // { InterestManager::EntitySubscribeToUpdatesMessageID, "EntitySubscribeToUpdates", (InterestManager::Handler)&InterestManager::EntitySubscribeToUpdatesHandler }, // // EntityUpdateReplicantsMessageID // { InterestManager::EntityUpdateReplicantsMessageID, "EntityUpdateReplicants", (InterestManager::Handler)&InterestManager::EntityUpdateReplicantsHandler }, // // EntityBroadcastToReplicantsMessageID // { InterestManager::EntityBroadcastToReplicantsMessageID, "EntityBroadcastToReplicants", (InterestManager::Handler)&InterestManager::EntityBroadcastToReplicantsHandler }, // // EntityNewInterestZoneMessageID // { InterestManager::EntityNewInterestZoneMessageID, "EntityNewInterestZone", (InterestManager::Handler)&InterestManager::EntityNewInterestZoneHandler }, // // HostInterestArenaChangedMessageID // { InterestManager::HostInterestArenaChangedMessageID, "HostInterestArenaChanged", (InterestManager::Handler)&InterestManager::HostInterestArenaChangedHandler }, // // InterestZoneDeltaMessageID // { InterestManager::InterestZoneDeltaMessageID, "InterestZoneDelta", (InterestManager::Handler)&InterestManager::InterestZoneDeltaHandler }, // // LoadResourceFinishedMessageID // { Receiver::LoadResourceFinishedMessageID, "LoadResourceFinished", (InterestManager::Handler)&InterestManager::LoadResourceFinishedHandler } }; Receiver::MessageHandlerSet InterestManager::MessageHandlers( ELEMENTS(InterestManager::MessageHandlerEntries), InterestManager::MessageHandlerEntries, NetworkClient::MessageHandlers ); // //############################################################################# // InterestManager //############################################################################# // InterestManager::InterestManager(): NetworkClient(InterestManagerClassID, DefaultData, InterestManagerClientID), interestOriginSocket(NULL) { interestArena = NULL; } // //############################################################################# // ~InterestManager //############################################################################# // InterestManager::~InterestManager() { if (interestArena != NULL) { Unregister_Object(interestArena); delete interestArena; } } // //############################################################################# // TestInstance //############################################################################# // Logical InterestManager::TestInstance() const { if (!IsDerivedFrom(ClassDerivations)) { return False; } Check(&interestLatticeManager); return True; } // //############################################################################# // LoadMission //############################################################################# // void InterestManager::LoadInterestArenas(Mission*) { Check(this); #if 0 // HACK - Partial Implementation // //-------------------------------------------------------------------------- // Load the interest zones that are accessed by the pilot's drop zone //-------------------------------------------------------------------------- // #else // //-------------------------------------------------------------------------- // Make one interest arena manually //-------------------------------------------------------------------------- // #if DEBUG_LEVEL>0 { Check(&interestOriginSocket); SChainIteratorOf iterator(&interestOriginSocket); Check(&iterator); Verify(iterator.GetSize() == 0); } #endif Verify(interestArena == NULL); interestArena = interestLatticeManager.MakeInterestArena( (InterestZoneID)0, (InterestType)0, (InterestDepth)0 ); Register_Object(interestArena); #endif } // //############################################################################# // LoadMission //############################################################################# // void InterestManager::LoadMission(Mission *mission) { Check(this); Check(mission); // //-------------------------------------------------------------------------- // Return if the map ID is not valid //-------------------------------------------------------------------------- // if (mission->GetMapID() == ResourceDescription::NullResourceID) return; // //-------------------------------------------------------------------------- // Get the resource description //-------------------------------------------------------------------------- // ResourceFile *resource_file; ResourceDescription *resource_description; Check(application); resource_file = application->GetResourceFile(); Check(resource_file); resource_description = resource_file->FindResourceDescription(mission->GetMapID()); Check(resource_description); resource_description->Lock(); // //-------------------------------------------------------------------------- // Create the map stream and load //-------------------------------------------------------------------------- // MemoryStream map_stream( resource_description->resourceAddress, resource_description->resourceSize ); Check(&map_stream); EntityID last_entity_id(MapHostID); int landmark_id=0; LoadMapStream(&map_stream, Origin::Identity, last_entity_id, landmark_id); resource_description->Unlock(); // //-------------------------------------------------------------------------- // HACK - load in the collision resources into the tree pointed to by // this resource //-------------------------------------------------------------------------- // resource_description = resource_file->FindResourceDescription(mission->GetExistanceMapID()); if (resource_description) { Check(resource_description); resource_description->Lock(); InterestZone *zone = GetInterestZone(interestArena->GetInterestZoneID()); Check(zone); BoundingBoxTree* tree = zone->GetExistanceRoot(); Check(tree); ExtentBox* zones = (ExtentBox*)resource_description->resourceAddress; int size = resource_description->resourceSize / sizeof(ExtentBox); while (size--) { BoundingBox *box; box = new BoundingBox(*zones); Register_Object(box); tree->Add(box, *box); ++zones; } resource_description->Unlock(); } resource_file->ReleaseUnlockedResources(); } // //############################################################################# // LoadMapStream //############################################################################# // void InterestManager::LoadMapStream( MemoryStream *map_stream, const Origin &root, EntityID &last_entity_id, int &landmark_id ) { Check(this); Check(map_stream); // //-------------------------------------------------------------------------- // Read the map stream and post creation messages //-------------------------------------------------------------------------- // int map_count; *map_stream >> map_count; for (int i=0; iGetPointer()); Check(message); // //----------------------------------------------------------- // If this is an include message, recurse into a new map load //----------------------------------------------------------- // if (message->messageFlags & Entity::MakeMessage::MapStreamMarkerFlag) { if (message->messageID == Entity::MakeMessageID) { Verify(message->messageLength == sizeof(Entity::MakeMapMessage)); Entity::MakeMapMessage *map_message = Cast_Object(Entity::MakeMapMessage*, message); Check(map_message); // // //----------------------------- // Get the resource description //----------------------------- // Check(application); ResourceFile *resource_file = application->GetResourceFile(); Check(resource_file); ResourceDescription *resource_description = resource_file->FindResourceDescription( map_message->resourceID ); Check(resource_description); resource_description->Lock(); // //-------------------------------------------------- // Figure out the origin to use for this map include // HACK - map rotation is not supported //-------------------------------------------------- // Origin local = map_message->localOrigin; local.linearPosition += root.linearPosition; // //------------------------------- // Create the map stream and load //------------------------------- // MemoryStream map_stream( resource_description->resourceAddress, resource_description->resourceSize ); Check(&map_stream); LoadMapStream(&map_stream, local, last_entity_id, landmark_id); resource_description->Unlock(); } else { Fail("Unknown message marker in map stream!\n"); } map_stream->AdvancePointer((message->messageLength+3)&~3); continue; } // //------------------- // Verify the message //------------------- // #if DEBUG_LEVEL>0 // //---------------------------------------------------------- // These classes should be stored in the map as map entities //---------------------------------------------------------- // switch (message->classToCreate) { case DropZoneClassID: case ScoreZoneClassID: case DoorFrameClassID: case CulturalIconClassID: case LandmarkClassID: if ((message->instanceFlags & Entity::MapFlag) == 0) { Fail("InterestManager::LoadMapStream - MapFlag disabled"); } break; default: break; } #endif // //--------------------------------------------------------------------- // If the message id is for a map entity, only make the thing if we are // supposed to //--------------------------------------------------------------------- // Logical post_make_message = True; if (Entity::EntityFlagsIsMap(message->instanceFlags)) { Check(application); HostManager *host_manager = application->GetHostManager(); Check(host_manager); if ( host_manager->GetLocalHostID() != host_manager->IdentifyNewMapEntityHost(message->entityID) ) { post_make_message = False; } } // //----------------------------------------------------- // Make a MakeEntityMessage and post it to the registry //----------------------------------------------------- // if (post_make_message) { // //-------------------------------------------------------------- // Make a copy of the message for modification by the map origin // HACK - map rotation is not supported //-------------------------------------------------------------- // Entity::MakeMessage *local_msg = (Entity::MakeMessage*)new char[message->messageLength]; Register_Pointer(local_msg); Mem_Copy( local_msg, message, message->messageLength, message->messageLength ); local_msg->localOrigin.linearPosition += root.linearPosition; // //--------------------------------------------------- // If this is a landmark, assign the next landmark ID //--------------------------------------------------- // if (local_msg->classToCreate == LandmarkClassID) { Landmark::MakeMessage *land_msg = (Landmark::MakeMessage*)local_msg; land_msg->landmarkID = landmark_id++; } // //-------------------------------------------------------- // If this is not a dynamic object, assign it an entity ID //-------------------------------------------------------- // if (!(local_msg->instanceFlags & Entity::DynamicFlag)) { last_entity_id += 1; local_msg->entityID = last_entity_id; } Registry::MakeEntityMessage *make_entity_message = Registry::MakeEntityMessage::Make(local_msg); Register_Object(make_entity_message); Check(application); // ECH 1/28/96 - application->PostCreationEvent(make_entity_message); PostCreationEvent(make_entity_message); #if 0 Tell( "InterestManager::LoadMapStream - Posted creation event: " << "class=" << message->classToCreate << "; " << "entityID=" << message->entityID << "\n" ); #endif Unregister_Object(make_entity_message); delete make_entity_message; Unregister_Pointer(local_msg); delete (char*)local_msg; } // //----------------------------------------------------------------------- // Advance to the next message //----------------------------------------------------------------------- // map_stream->AdvancePointer((message->messageLength+3)&~3); } Check_Fpu(); } // //############################################################################# // Shutdown //############################################################################# // void InterestManager::Shutdown() { Check(this); #if 0 // HACK - Partial Implementation // //-------------------------------------------------------------------------- // Delete interest zones //-------------------------------------------------------------------------- // #else // // Delete the one interest arena // if (interestArena) { Unregister_Object(interestArena); delete interestArena; interestArena = NULL; } #endif } // //############################################################################# // Execute //############################################################################# // void InterestManager::Execute() { #if 0 // // If (the changed origin list is empty) // // // return // // // Update the net interest arena with the changes from the // changed interest origin list // // // Calculate which interest zones should be released and which // interest zones should be loaded // // // For (the interest zones which should be released) // // // For (the static entities in the interest zones to be released) // // // Send a becoming uninteresting event to the entity // // // For (the dynamic master entities in the interest zones to be released) // // // Send a becoming uninteresting event to the entity // // // For (the dynamic map entities in the interest zones to be released) // // // Send a becoming uninteresting event to the entity // // // For (the replicants in the interest zones to be released) // // // Unsubscribe the replicants from changes // // // Send a becoming uninteresting event to the entity // // // Call the resource manager releasing the interest zone // // // For (the interest zones which should be loaded) // // // Call the resource manager, requesting the interest zones // // // Broadcast the interest arena change // { HostInterestArenaChangedMessage message; // // Send at the end of the current frame // Check(application); application->BroadcastEvent( DefaultEventPriority, InterestManagerID, &message ); } #endif } // //############################################################################# // AdoptInterestOrigin //############################################################################# // void InterestManager::AdoptInterestOrigin(InterestOrigin *interest_origin) { Check(this); Check(interest_origin); // //-------------------------------------------------------------------------- // Add the interest origin to managers socket //-------------------------------------------------------------------------- // Check(&interestOriginSocket); interestOriginSocket.Add(interest_origin); #if 0 // HACK - Partial Implementation // //-------------------------------------------------------------------------- // Add to net interest arena... //-------------------------------------------------------------------------- // #else // //-------------------------------------------------------------------------- // HACK - add interesting entities to the interest origin manually //-------------------------------------------------------------------------- // interest_origin->Update(interest_origin->GetInterestZoneID()); AddInterestingEntitiesToInterestOrigin(interest_origin); #endif } // //############################################################################# // OrphanInterestOrigin //############################################################################# // void InterestManager::OrphanInterestOrigin(InterestOrigin *interest_origin) { Check(this); Check(interest_origin); #if 0 // HACK - Partial Implementation // //-------------------------------------------------------------------------- // Remove from net interest arena //-------------------------------------------------------------------------- // #else // //-------------------------------------------------------------------------- // HACK - remove interesting entities manually //-------------------------------------------------------------------------- // RemoveUninterestingEntitiesFromInterestOrigin(interest_origin); #endif } // //############################################################################# // NotifyOfEntityCreation //############################################################################# // void InterestManager::NotifyOfEntityCreation( Entity *entity, Entity::MakeMessage *creation_message ) { Check(this); Check(entity); Check(creation_message); #if 0 Tell( "InterestManager::NotifyOfEntityCreation - " << "class=" << entity->GetClassID() << "; " << "entityID=" << entity->GetEntityID() << "\n" ); #endif // //-------------------------------------------------------------------------- // Call appropriate service routine //-------------------------------------------------------------------------- // switch (entity->GetInstance()) { case Entity::IndependantInstance: { Check(application); Check(application->GetHostManager()); if ( entity->GetOwnerID() == application->GetHostManager()->GetLocalHostID() ) { DynamicEntityCreation(entity, creation_message); } else { ReplicantEntityCreation(entity, creation_message); } } break; case Entity::MasterInstance: DynamicEntityCreation(entity, creation_message); break; case Entity::HermitInstance: if (entity->IsDynamic()) { DynamicEntityCreation(entity, creation_message); } else { StaticEntityCreation(entity, creation_message); } break; case Entity::ReplicantInstance: ReplicantEntityCreation(entity, creation_message); break; default: Fail("InterestManager::NotifyOfEntityCreation - should never reach here"); break; } } // //############################################################################# // StaticEntityCreation //############################################################################# // void InterestManager::StaticEntityCreation( #if DEBUG_LEVEL>0 Entity *entity, Entity::MakeMessage *creation_message #else Entity *entity, Entity::MakeMessage * #endif ) { Check(this); Check(entity); Check(creation_message); // //-------------------------------------------------------------------------- // Verify entityID, instance, and flags //-------------------------------------------------------------------------- // Verify(entity->GetEntityID() != EntityID::Null); Verify( entity->GetInstance() == Entity::MasterInstance || entity->GetInstance() == Entity::HermitInstance ); // Verify(entity->IsStatic()); // HACK - Partial Implementation // Verify(!entity->IsMap()); // HACK - Partial Implementation allows map entities #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------------- // The interest zone of the static entity should already be calculated // correctly //-------------------------------------------------------------------------- // #else // //-------------------------------------------------------------------------- // Find the interest zone for the static entity and set the interest zone //-------------------------------------------------------------------------- // InterestZoneID interest_zone_ID; interest_zone_ID = interestLatticeManager.SearchForEntityInterestZone( (InterestZoneID)0, entity->GetEntityID() ); entity->SetInterestZoneID(interest_zone_ID); #endif #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------------- // If within any existing interest arenas, then add to the interest origin //-------------------------------------------------------------------------- // #else // //-------------------------------------------------------------------------- // HACK - Manually add to all interest origins //-------------------------------------------------------------------------- // AddInterestingEntityToInterestOrigins(entity); #endif } // //############################################################################# // DynamicEntityCreation //############################################################################# // void InterestManager::DynamicEntityCreation( Entity *entity, Entity::MakeMessage *creation_message ) { Check(this); Check(entity); Check(creation_message); // //-------------------------------------------------------------------------- // Verify entityID, instance, and flags //-------------------------------------------------------------------------- // #if DEBUG_LEVEL>0 Verify(entity->GetEntityID() != EntityID::Null); Verify( entity->GetInstance() == Entity::MasterInstance || entity->GetInstance() == Entity::IndependantInstance || entity->GetInstance() == Entity::HermitInstance ); // Verify(entity->IsDynamic()); // HACK - Partial Implementation // Verify(!entity->IsMap()); // HACK - Partial Implementation allows map entities if (entity->GetInstance() == Entity::IndependantInstance) { Check(application); Check(application->GetHostManager()); Verify( entity->GetOwnerID() == application->GetHostManager()->GetLocalHostID() ); } #endif #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------------- // Set the interest zone id of the entity. Use the spatializer to locate // the interest zone that the entity is located in //-------------------------------------------------------------------------- // #else // //-------------------------------------------------------------------------- // Find the interest zone for the static entity and set the interest zone //-------------------------------------------------------------------------- // InterestZoneID interest_zone_ID; interest_zone_ID = interestLatticeManager.SearchForEntityInterestZone( (InterestZoneID)0, entity->GetEntityID() ); entity->SetInterestZoneID(interest_zone_ID); #endif // //-------------------------------------------------------------------------- // Send new dynamic entity message //-------------------------------------------------------------------------- // // // Setup and verify network fields in creation message // entity->SetupNetworkMessage(creation_message); #if DEBUG_LEVEL>0 Check(&creation_message->entityID); Verify(creation_message->entityID != EntityID::Null); Verify(creation_message->interestZoneID != NullInterestZoneID); Check(application); Check(application->GetHostManager()); Verify( creation_message->ownerID == application->GetHostManager()->GetLocalHostID() ); #endif // // HACK - Spoof the make entity message into a NewDynamicEntityMessageID // for the purposes of sending to interest managers // Verify(creation_message->messageID == Entity::MakeMessageID); creation_message->messageID = NewDynamicEntityMessageID; // //-------------------------------------------------------------------------- // If the entity is replicated //-------------------------------------------------------------------------- // if ( entity->GetInstance() == Entity::MasterInstance || entity->GetInstance() == Entity::IndependantInstance ) { // // Broadcast the message // Check(application); application->BroadcastMessage(InterestManagerClientID, creation_message); } // //-------------------------------------------------------------------------- // Else (the entity is not replicated) //-------------------------------------------------------------------------- // else { Verify(entity->GetInstance() == Entity::HermitInstance); // // Post the message to ourselves // Check(application); // ECH 1/28/96 - application->Post(DefaultEventPriority, this, creation_message); Dispatch(creation_message); } } // //############################################################################# // NewDynamicEntityHandler //############################################################################# // void InterestManager::NewDynamicEntityHandler( NewDynamicEntityMessage *creation_message ) { Check(this); Check(creation_message); // // Verify the creation message // Check(&creation_message->entityID); Verify(creation_message->entityID != EntityID::Null); Verify(creation_message->interestZoneID != NullInterestZoneID); Verify(creation_message->ownerID >= FirstLegalHostID); #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------------- // If (the new entity is not in any of the interest arenas) //-------------------------------------------------------------------------- // // // return // #endif // //-------------------------------------------------------------------------- // Get the local host id //-------------------------------------------------------------------------- // HostID local_host_ID; Check(application); Check(application->GetHostManager()); local_host_ID = application->GetHostManager()->GetLocalHostID(); // //-------------------------------------------------------------------------- // If (this host is not the owner host) //-------------------------------------------------------------------------- // if (local_host_ID != creation_message->ownerID) { // //----------------------------------------------------------------------- // Make the replicant //----------------------------------------------------------------------- // // // HACK - Message was spoofed as NewDynamicEntityMessageID, now // turn back to make entity message ID // Verify(creation_message->messageID == NewDynamicEntityMessageID); creation_message->messageID = Entity::MakeMessageID; // // Turn on the replicant flag if this is a master instance, // otherwise, the instance should be an independant // if ( Entity::EntityFlagsGetInstance(creation_message->instanceFlags) == Entity::MasterInstance ) { creation_message->instanceFlags = Entity::EntityFlagsSetInstance( creation_message->instanceFlags, Entity::ReplicantInstance ); } else { Verify( Entity::EntityFlagsGetInstance(creation_message->instanceFlags) == Entity::IndependantInstance ); } // //----------------------------------------------------------------------- // Make a MakeEntityMessage and post it to the registry //----------------------------------------------------------------------- // Registry::MakeEntityMessage *make_entity_message; make_entity_message = Registry::MakeEntityMessage::Make(creation_message); Register_Object(make_entity_message); Check(application); // // Implicit assumption that this will be a higher // priority and/or earlier sequence than any update message // Check(application->GetRegistry()); application->GetRegistry()->Dispatch(make_entity_message); Unregister_Object(make_entity_message); delete make_entity_message; } // //-------------------------------------------------------------------------- // If (this host is the owner host) //-------------------------------------------------------------------------- // else { // //----------------------------------------------------------------------- // Get the entity pointer //----------------------------------------------------------------------- // Entity *entity; Check(application); Check(application->GetHostManager()); entity = application->GetHostManager()->GetEntityPointer( creation_message->entityID ); Check(entity); // //----------------------------------------------------------------------- // Tell the master that it is interesting // Should this wait until next interest frame? //----------------------------------------------------------------------- // entity->BecomeInteresting(); // //----------------------------------------------------------------------- // HACK - Manually add to all interest origins //----------------------------------------------------------------------- // AddInterestingEntityToInterestOrigins(entity); } } #if 0 // HACK - Partial Implementation // //############################################################################# // NotifyOfMapEntityCreation //############################################################################# // void InterestManager::NotifyOfMapEntityCreation( Entity *entity, Entity::MakeMessage *creation_message, Time ) { Check(this); Check(entity); Check(creation_message); Verify(creation_message->entityID != EntityID::Null); Verify(creation_message->interestZoneID != NullInterestZoneID); // // Verify instance type, and interest characterisitics // Verify(entity->GetInstance() == Entity::MasterInstance); Verify(entity->IsDynamic()); Verify(entity->IsMap()); #if 0 // // Call the resource manager, storing the interest zone delta // // // Broadcast the interest zone delta // { InterestZoneDeltaMessage message; Check(application); application->SendMessage( DefaultEventPriority, InterestManagerID, &message ); } // // Broadcast the new map entity message // { Verify(creation_message->messageID == Entity::MakeMessageID); creation_message->messageID = NewMapEntityMessageID; Check(application); application->SendMessage( DefaultEventPriority, InterestManagerID, creation_message ); } #else Fail("InterestManager::NotifyOfMapEntityCreation - under construction"); #endif } #endif #if 0 // HACK - Partial Implementation // //############################################################################# // NewMapEntityHandler //############################################################################# // void InterestManager::NewMapEntityHandler( NewMapEntityMessage *message ) { Check(this); Check(message); #if 0 // // If (the entity is outside of the interest arena) // // // Return // // // If (this is the owner host) // // // Tell the entity that it is interesting // // // If (this host is not the owner host) // // // Find the replicant or local master entity // // // If (the entity does not exist) // // // Make the replicant // // // Tell the replicant that it is interesting // // // Subscribe the replicant to updates from the master // // // If (the entity does exist) // // // If (the entity is a replicant) // // // Point it at the new owner // // // If (the entity is a master) // // // If (creation time of new master > creation time of local master) // // // Morph the local master into a replicant pointing at new master // // // Tell the replicant that it is interesting // // // Subscribe the replicant to updates from the master // #else Fail("InterestManager::NewMapEntityHandler - under construction"); #endif } #endif // //############################################################################# // ReplicantEntityCreation //############################################################################# // void InterestManager::ReplicantEntityCreation( #if DEBUG_LEVEL>0 Entity *entity, Entity::MakeMessage *creation_message #else Entity *entity, Entity::MakeMessage * #endif ) { Check(this); Check(entity); Check(creation_message); // //-------------------------------------------------------------------------- // Verify entityID, instance, and flags //-------------------------------------------------------------------------- // #if DEBUG_LEVEL>0 Verify(entity->GetEntityID() != EntityID::Null); Verify( entity->GetInstance() == Entity::ReplicantInstance || entity->GetInstance() == Entity::IndependantInstance ); // Verify(entity->IsDynamic()); // HACK - Partial Implementation // Verify(!entity->IsMap()); // HACK - Partial Implementation allows map entities if (entity->GetInstance() == Entity::IndependantInstance) { Check(application); Check(application->GetHostManager()); Verify( entity->GetOwnerID() != application->GetHostManager()->GetLocalHostID() ); } #endif #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------------- // The interest zone of the static entity should already be calculated // correctly //-------------------------------------------------------------------------- // #endif // //-------------------------------------------------------------------------- // Get the local host id //-------------------------------------------------------------------------- // HostID local_host_ID; Check(application); Check(application->GetHostManager()); local_host_ID = application->GetHostManager()->GetLocalHostID(); // //-------------------------------------------------------------------------- // Subscribe the replicant to updates from the master //-------------------------------------------------------------------------- // EntitySubscribeToUpdates( entity->GetEntityID(), entity->GetOwnerID(), local_host_ID ); // //-------------------------------------------------------------------------- // Tell the replicant that it is interesting //-------------------------------------------------------------------------- // entity->BecomeInteresting(); // //-------------------------------------------------------------------------- // HACK - Manually add to all interest origins //-------------------------------------------------------------------------- // AddInterestingEntityToInterestOrigins(entity); } // //############################################################################# // NotifyOfEntityDestruction //############################################################################# // void InterestManager::NotifyOfEntityDestruction(Entity *entity) { Check(this); Check(entity); #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------------- // If (this is a map entity) //-------------------------------------------------------------------------- // // // Store an interest zone delta with the owner set to MapHostID // // // Broadcast an interest zone delta // #endif // //-------------------------------------------------------------------------- // HACK - Manually remove from all interest origins //-------------------------------------------------------------------------- // RemoveUninterestingEntityFromInterestOrigins(entity); // //-------------------------------------------------------------------------- // Broadcast delete entity message for master entities that have replicants //-------------------------------------------------------------------------- // if ( entity->GetInstance() == Entity::MasterInstance // && // HACK - Partial Implementation // entity->IsDynamic() // HACK - Partial Implementation ) { // // Create destruction message // DestroyDynamicEntityMessage destroy_message( DestroyDynamicEntityMessageID, sizeof(DestroyDynamicEntityMessage) ); Check(&destroy_message); // // Setup and verify network fields in destruction message // entity->SetupNetworkMessage(&destroy_message); #if DEBUG_LEVEL>0 Check(&destroy_message.entityID); Verify(destroy_message.entityID == entity->entityID); Verify(destroy_message.interestZoneID == entity->interestZoneID); Check(application); Check(application->GetHostManager()); Verify( destroy_message.ownerID == application->GetHostManager()->GetLocalHostID() ); #endif // // Broadcast destruction message // Check(application); application->ExclusiveBroadcastMessage( InterestManagerClientID, &destroy_message ); } } // //############################################################################# // DestroyDynamicEntityHandler //############################################################################# // void InterestManager::DestroyDynamicEntityHandler( DestroyDynamicEntityMessage *destroy_message ) { Check(this); Check(destroy_message); // // Verify destruction message // Check(&destroy_message->entityID); Verify(destroy_message->entityID != EntityID::Null); Verify(destroy_message->interestZoneID != NullInterestZoneID); Verify(destroy_message->ownerID >= FirstLegalHostID); #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------------- // If entity is not within interest zone //-------------------------------------------------------------------------- // // // return // #endif // //-------------------------------------------------------------------------- // Verify the local host id //-------------------------------------------------------------------------- // #if DEBUG_LEVEL>0 HostID local_host_ID; Check(application); Check(application->GetHostManager()); local_host_ID = application->GetHostManager()->GetLocalHostID(); Verify(destroy_message->ownerID != local_host_ID); #endif // //-------------------------------------------------------------------------- // Find the replicant to destroy //-------------------------------------------------------------------------- // Entity *replicant; Check(application); Check(application->GetHostManager()); replicant = application->GetHostManager()->GetEntityPointer( destroy_message->entityID ); // //-------------------------------------------------------------------------- // If (the replicant exists) //-------------------------------------------------------------------------- // if (replicant != NULL) { Check(replicant); Verify(replicant->GetInstance() == Entity::ReplicantInstance); // // HACK - Message was spoofed as DestroyDynamicEntityMessage, now // turn back to DestroyEntityMessage // Verify(destroy_message->messageID == DestroyDynamicEntityMessageID); destroy_message->messageID = Entity::DestroyEntityMessageID; Check(application); // ECH 1/28/96 - application->Post(DefaultEventPriority, replicant, destroy_message); PostDestructionEvent(replicant, destroy_message); } } // //############################################################################# // EntityUpdateInterestZone //############################################################################# // void InterestManager::EntityUpdateInterestZone( #if DEBUG_LEVEL>0 Entity *entity #else Entity * #endif ) { Check(this); Check(entity); Verify(entity->IsDynamic()); #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------- // Update the interest zone id if the entity is not trapped //-------------------------------------------------------------------- // if (entity->IsTrapped()) return; // //-------------------------------------------------------------------- // Find the entities new interest zone //-------------------------------------------------------------------- // InterestZoneID old_interest_zone_ID, new_interest_zone_ID; old_interest_zone_ID = entity->GetInterestZoneID(); new_interest_zone_ID = interestLatticeManager.SearchForEntityInterestZone( old_interest_zone_ID, entity->GetEntityID() ); // //-------------------------------------------------------------------- // If the interest zone has changed, then update the entity // and broadcast the change //-------------------------------------------------------------------- // if (old_interest_zone_ID != new_interest_zone_ID) { entity->SetInterestZoneID(new_interest_zone_ID); // // HACK - a way is needed to get from the entity the information // required for another host to create the replicant // EntityNewInterestZoneMessage message(entity->GetEntityID(),new_interest_zone_ID); // // This message should be handled locally before the end of // the current render frame? // #if 0 Check(application); application->SendEvent( DefaultEventPriority, InterestManagerID, &message ); #else Check(application); application->BroadcastMessage( InterestManagerClientID, &message ); #endif } #endif } // //############################################################################# // EntityNewInterestZoneHandler //############################################################################# // void InterestManager::EntityNewInterestZoneHandler( EntityNewInterestZoneMessage* ) { #if 0 // // If (the master entity is on this host) // // // Determine if the entity is interesting given its new // interest zone // // // If (the entity was and still is interesting) // then (do nothing) // // // If (the entity was not interesting and still is not interesting) // then (do nothing) // // // If (the entity was interesting and now is not interesting) // // // Send BecomeUninteresting message to the entity // // // If (the entity was not interesting and now is interesting) // // // Send BecomeInteresting message to the entity // // // If (the master entity is not on this host) // // // Determine if the entity is interesting given its new // interest zone // // // If (the entity was and still is interesting) // then (do nothing) // // // If (the entity was not interesting and still is not interesting) // then (do nothing) // // // If (the entity was interesting and now is not interesting) // // // Unsubscribe the replicant entity from updates // // // Send BecomeUninteresting message to the entity // // // If (the entity was not interesting and now is interesting) // // // If (the replicant does not exist) // // // Create the replicant // // // Send BecomeInteresting message to the entity // // // Subscribe the replicant to updates // #else Fail("InterestManager::EntityNewInterestZoneHandler - under construction"); #endif } // //############################################################################# // LoadResourceFinishedHandler //############################################################################# // void InterestManager::LoadResourceFinishedHandler(Receiver::Message*) { #if 0 // // If (an interest origin request for interest zone finished) // // // For (the static entities in the interest zone) // // // If (the static entity does not exist) // // // Make the static entity // // // For (the map entities in the interest zone) // // // If (the owner of the map entity is MapHostID) // // // This entity has not been created by any other hosts, // so create it with this host as owner // // // Need to somehow put in a small random delay for map // entity creation resolution between two hosts? // // // Make the map entity // #if 0 { Entity entity_ID; // From the interest zone ClassID class_ID; // From the interest zone HostID owner_ID; // From this host application->registry->MakeEntity(entity_ID, class_ID); } #endif #else Fail("InterestManager::LoadResourceFinishedHandler - under construction"); #endif } // //############################################################################# // EntitySubscribeToUpdates //############################################################################# // void InterestManager::EntitySubscribeToUpdates( EntityID, HostID, HostID ) { // HACK - Partial implementation } // //############################################################################# // EntitySubscribeToUpdatesHandler //############################################################################# // void InterestManager::EntitySubscribeToUpdatesHandler( EntitySubscribeToUpdatesMessage* ) { // HACK - Partial implementation } // //############################################################################# // EntityUpdateReplicants //############################################################################# // void InterestManager::EntityUpdateReplicants( Entity *entity, Entity::UpdateMessage *update_message ) { Check(this); Check(entity); Check(update_message); // //-------------------------------------------------------------------------- // Verify entityID, instance, and flags //-------------------------------------------------------------------------- // Verify(entity->GetEntityID() != EntityID::Null); Verify(entity->GetInstance() == Entity::MasterInstance); Verify(entity->IsDynamic()); // Verify(!entity->IsMap()); // HACK - Partial Implementation allows map entities #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------------- // If (no replicants are subscribed to this entity) //-------------------------------------------------------------------------- // // // return // #endif #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------------- // Send it to the subscribed replicants // // LAN Solution: // If (subscriber list is not empty) // Broadcast the update // // WAN Solution: // If (subscriber list is not empty) // Send the update via point-to-point messages // // A way is needed to get from the entity the information // required for another host to create the replicant //-------------------------------------------------------------------------- // #else // // Setup and verify network fields in message // entity->SetupNetworkMessage(update_message); #if DEBUG_LEVEL>0 Check(&update_message->entityID); Verify(update_message->entityID != EntityID::Null); Verify(update_message->interestZoneID != NullInterestZoneID); Check(application); Check(application->GetHostManager()); Verify( update_message->ownerID == application->GetHostManager()->GetLocalHostID() ); #endif // // HACK - Spoof the update message into EntityUpdateReplicantsMessageID // Verify(update_message->messageID == Entity::UpdateMessageID); update_message->messageID = EntityUpdateReplicantsMessageID; // // Broadcast update message // Check(application); application->ExclusiveBroadcastMessage( InterestManagerClientID, update_message ); #endif } // //############################################################################# // EntityUpdateReplicantsHandler //############################################################################# // void InterestManager::EntityUpdateReplicantsHandler( EntityUpdateReplicantsMessage *update_message ) { Check(this); Check(update_message); // // Verify update message // Check(&update_message->entityID); Verify(update_message->entityID != EntityID::Null); Verify(update_message->interestZoneID != NullInterestZoneID); Verify(update_message->ownerID >= FirstLegalHostID); #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------------- // If (interest zone id is outside of our interest arenas) //-------------------------------------------------------------------------- // // // return // #endif // //-------------------------------------------------------------------------- // Verify the local host id //-------------------------------------------------------------------------- // #if DEBUG_LEVEL>0 HostID local_host_ID; Check(application); Check(application->GetHostManager()); local_host_ID = application->GetHostManager()->GetLocalHostID(); Verify(update_message->ownerID != local_host_ID); #endif // //-------------------------------------------------------------------------- // Find the replicant to update //-------------------------------------------------------------------------- // Entity *replicant; Check(application); Check(application->GetHostManager()); replicant = application->GetHostManager()->GetEntityPointer( update_message->entityID ); // //-------------------------------------------------------------------------- // If (the replicant exists) //-------------------------------------------------------------------------- // if (replicant) { // // Update the replicant // Check(replicant); Verify(replicant->GetInstance() == Entity::ReplicantInstance); Verify(replicant->IsDynamic()); // // HACK - Message was spoofed as EntityUpdateReplicantsMessageID, now // turn back to update entity message ID // Verify(update_message->messageID == EntityUpdateReplicantsMessageID); update_message->messageID = Entity::UpdateMessageID; Check(application); // ECH 1/28/96 - application->Post(DefaultEventPriority, replicant, update_message); PostUpdateEvent(replicant, update_message); } #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------------- // If (the replicant does not exist) //-------------------------------------------------------------------------- // // // Create the replicant // // // Send BecomeInteresting message to the entity // // // Subscribe the replicant to updates // #endif } // //############################################################################# // EntityBroadcastToReplicants //############################################################################# // void InterestManager::EntityBroadcastToReplicants( Entity *entity, Entity::Message *broadcast_message ) { Check(this); Check(entity); Check(broadcast_message); // //-------------------------------------------------------------------------- // Verify entityID, instance, and flags //-------------------------------------------------------------------------- // Verify(entity->GetEntityID() != EntityID::Null); Verify(entity->GetInstance() == Entity::MasterInstance); // Verify(entity->IsDynamic()); // HACK - Partial Implementation // Verify(!entity->IsMap()); // HACK - Partial Implementation allows map entities #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------------- // If (no replicants are subscribed to this entity) //-------------------------------------------------------------------------- // // // return // #endif #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------------- // Send it to the subscribed replicants // // LAN Solution: // If (subscriber list is not empty) // Broadcast the update // // WAN Solution: // If (subscriber list is not empty) // Send the update via point-to-point messages // // A way is needed to get from the entity the information // required for another host to create the replicant // //-------------------------------------------------------------------------- // #else // //-------------------------------------------------------------------------- // Setup and verify network fields in message //-------------------------------------------------------------------------- // entity->SetupNetworkMessage(broadcast_message); #if DEBUG_LEVEL>0 Check(&broadcast_message->entityID); Verify(broadcast_message->entityID != EntityID::Null); Verify(broadcast_message->interestZoneID != NullInterestZoneID); Check(application); Check(application->GetHostManager()); Verify( broadcast_message->ownerID == application->GetHostManager()->GetLocalHostID() ); #endif // //-------------------------------------------------------------------------- // Build the interest manager message //-------------------------------------------------------------------------- // MemoryStream memory_stream(messageBuildBuffer, INTERESTMANAGER_MESSAGE_BUFFER_SIZE); EntityBroadcastToReplicantsMessage *interest_manager_message; size_t total_length; total_length = sizeof (EntityBroadcastToReplicantsMessage) + broadcast_message->messageLength; Verify(total_length < memory_stream.GetBytesRemaining()); Check_Pointer(memory_stream.GetPointer()); interest_manager_message = new (memory_stream.GetPointer()) EntityBroadcastToReplicantsMessage( total_length ); Check(interest_manager_message); memory_stream.AdvancePointer(sizeof(EntityBroadcastToReplicantsMessage)); Mem_Copy( memory_stream.GetPointer(), broadcast_message, broadcast_message->messageLength, memory_stream.GetBytesRemaining() ); // //-------------------------------------------------------------------------- // Broadcast update message //-------------------------------------------------------------------------- // #if 0 Tell( "InterestManager::EntityBroadcastToReplicants - Send entity message ID " << broadcast_message->messageID << "\n" ); #endif Check(application); application->ExclusiveBroadcastMessage( InterestManagerClientID, interest_manager_message ); #endif } // //############################################################################# // EntityBroadcastToReplicantsHandler //############################################################################# // void InterestManager::EntityBroadcastToReplicantsHandler( EntityBroadcastToReplicantsMessage *interest_manager_message ) { Check(this); Check(interest_manager_message); #if 0 // HACK - Partial Implementation // //-------------------------------------------------------------------------- // If (interest zone id is outside of our interest arenas) //-------------------------------------------------------------------------- // // // return // #endif // //-------------------------------------------------------------------------- // Parse broadcast message //-------------------------------------------------------------------------- // MemoryStream memory_stream( interest_manager_message, interest_manager_message->messageLength ); Entity::Message *broadcast_message; memory_stream.AdvancePointer(sizeof(EntityBroadcastToReplicantsMessage)); broadcast_message = Cast_Object(Entity::Message*, memory_stream.GetPointer()); Check(broadcast_message); Check(&broadcast_message->entityID); Verify(broadcast_message->entityID != EntityID::Null); Verify(broadcast_message->interestZoneID != NullInterestZoneID); Verify(broadcast_message->ownerID >= FirstLegalHostID); #if 0 Tell( "InterestManager::EntityBroadcastToReplicantsHandler - Receive entity message ID " << broadcast_message->messageID << "\n" ); #endif // //-------------------------------------------------------------------------- // Verify the local host id //-------------------------------------------------------------------------- // #if DEBUG_LEVEL>0 HostID local_host_ID; Check(application); Check(application->GetHostManager()); local_host_ID = application->GetHostManager()->GetLocalHostID(); Verify(broadcast_message->ownerID != local_host_ID); #endif // //-------------------------------------------------------------------------- // Find the replicant to update //-------------------------------------------------------------------------- // Entity *replicant; Check(application); Check(application->GetHostManager()); replicant = application->GetHostManager()->GetEntityPointer( broadcast_message->entityID ); #if 0 Tell( "InterestManager::EntityBroadcastToReplicantsHandler - Replicant=" << (long)replicant << "\n" ); #endif // //-------------------------------------------------------------------------- // If the replicant exists, update it //-------------------------------------------------------------------------- // if (replicant) { Check(replicant); Verify(replicant->GetInstance() == Entity::ReplicantInstance); Check(application); // ECH 1/28/96 - application->Post(DefaultEventPriority, replicant, broadcast_message); PostUpdateEvent(replicant, broadcast_message); } #if 0 // HACK - Partial implementation // //-------------------------------------------------------------------------- // If (the replicant does not exist) //-------------------------------------------------------------------------- // else { // // Create the replicant // // // Send BecomeInteresting message to the entity // // // Subscribe the replicant to updates // #if 0 Tell("Unknown replicant " << broadcast_message->entityID << endl); #endif } #endif } // //############################################################################# // HostInterestArenaChangedHandler //############################################################################# // void InterestManager::HostInterestArenaChangedHandler( HostInterestArenaChangedMessage* ) { #if 0 // // Get all hosted dynamic entities // // // For (each entity within the given interest arena) // { // // HACK - need someway of doing the following point-to-point, // potentially to ourselves // Entity::UpdateMessage *update_message = NULL; Check(update_message); Check(application); application->interestManager.EntityUpdateReplicants( entity, update_message ); } #else Fail("InterestManager::HostInterestArenaChangedHandler - under construction"); #endif } // //############################################################################# // InterestZoneDeltaHandler //############################################################################# // void InterestManager::InterestZoneDeltaHandler( InterestZoneDeltaMessage* ) { #if 0 // // If (a delta already exists for this interest zone) // // // Get the timestamp of the existing delta // // // If (the timestamp of the incoming delta is > then current delta) // // // Store the incoming delta // // // If (a delta does not exist for this interest zone) // // // Store the incoming data // #else Fail("InterestManager::InterestZoneDeltaHandler - under construction"); #endif } // //############################################################################# //############################################################################# // void InterestManager::AddInterestingEntityToInterestOrigins(Entity *new_entity) { Check(this); Check(new_entity); Check(&interestOriginSocket); InterestOrigin *interest_origin; SChainIteratorOf iterator(&interestOriginSocket); Check(&iterator); while((interest_origin = iterator.ReadAndNext()) != NULL) { Check(interest_origin); interest_origin->AddInterestingEntity(new_entity); } } // //############################################################################# //############################################################################# // void InterestManager::RemoveUninterestingEntityFromInterestOrigins(Entity *entity) { Check(this); Check(entity); Check(&interestOriginSocket); InterestOrigin *interest_origin; SChainIteratorOf iterator(&interestOriginSocket); Check(&iterator); while((interest_origin = iterator.ReadAndNext()) != NULL) { Check(interest_origin); interest_origin->RemoveUninterestingEntity(entity); } } // //############################################################################# //############################################################################# // void InterestManager::AddInterestingEntitiesToInterestOrigin( InterestOrigin *interest_origin ) { Check(this); Check(interest_origin); // // Get an iterator for all the entities on this host // Check(application); Check(application->GetHostManager()); HostManager::AllEntityIterator iterator(application->GetHostManager()); Entity *entity; Check(&iterator); while((entity = iterator.ReadAndNext()) != NULL) { Check(entity); interest_origin->AddInterestingEntity(entity); } } // //############################################################################# // PostCreationEvent //############################################################################# // void InterestManager::PostCreationEvent(Receiver::Message *make_entity_message) { Check(this); Check(make_entity_message); Check(application); #if 0 // ECH 1/28/96 EventPriorities priority = (application->GetApplicationState() != Application::RunningMission) ? LowEventPriority : DefaultEventPriority; #else EventPriorities priority = (application->GetApplicationState() != Application::RunningMission) ? LowEventPriority : CreationEventPriority; #endif Check(application); Registry *registry = application->GetRegistry(); Check(registry); application->Post(priority, registry, make_entity_message); } // //############################################################################# // PostRendererEvent //############################################################################# // void InterestManager::PostRendererEvent( Entity *entity, Renderer *renderer, Receiver::Message *message ) { Check(this); Check(entity); Check(renderer); #if 0 // ECH 1/26/96 EventPriorities priority = (applicationState.GetState() != Application::RunningMission) ? MinEventPriority : DefaultEventPriority; #endif EventPriorities priority; switch (entity->GetInterestPriority(renderer->GetLinkedEntity())) { case LowInterestPriority: priority = (application->GetApplicationState() != Application::RunningMission) ? MinEventPriority : LowInterestEventPriority; break; case HighInterestPriority: priority = (application->GetApplicationState() != Application::RunningMission) ? MinEventPriority : HighInterestEventPriority; break; default: Fail("Application::PostInterestEvent - Should never reach here"); break; } application->Post(priority, renderer, message); } // //############################################################################# // PostUpdateEvent //############################################################################# // void InterestManager::PostUpdateEvent( Entity *entity, Receiver::Message *message ) { Check(this); Check(entity); Check(message); // // Note that the priority of the update can be greater than the // creation priority since the replicants are created via dispatch // in the interest manager. // EventPriorities priority = (application->GetApplicationState() != Application::RunningMission) ? DefaultEventPriority : UpdateEventPriority; Check(application); application->Post(priority, entity, message); } // //############################################################################# // PostDestructionEvent //############################################################################# // void InterestManager::PostDestructionEvent( Entity *entity, Receiver::Message *message ) { Check(this); Check(entity); Check(message); EventPriorities priority = DestructionEventPriority; #if 0 switch (entity->GetInterestPriority(renderer->GetLinkedEntity())) { case LowInterestPriority: priority = LowEventPriority; break; case HighInterestPriority: priority = DefaultEventPriority; break; default: Fail("Application::PostInterestEvent - Should never reach here"); break; } #endif Check(application); application->Post(priority, entity, message); } // //############################################################################# //############################################################################# // void InterestManager::RemoveUninterestingEntitiesFromInterestOrigin( InterestOrigin *interest_origin ) { Check(this); Check(interest_origin); interest_origin->RemoveUninterestingEntities(); } //~~~~~~~~~~~~~~~~~ InterestManager__EntitySubscribeToUpdatesMessage ~~~~~~~~~~ InterestManager__EntitySubscribeToUpdatesMessage:: InterestManager__EntitySubscribeToUpdatesMessage(): NetworkClient::Message( InterestManager::EntitySubscribeToUpdatesMessageID, sizeof(InterestManager__EntitySubscribeToUpdatesMessage) ) { } //~~~~~~~~~~~~~~ InterestManager__EntityBroadcastToReplicantsMessage ~~~~~~~~~~ InterestManager__EntityBroadcastToReplicantsMessage:: InterestManager__EntityBroadcastToReplicantsMessage(size_t message_length): NetworkClient::Message( InterestManager::EntityBroadcastToReplicantsMessageID, message_length ) { } //~~~~~~~~~~~~~~~~~ InterestManager__EntityNewInterestZoneMessage ~~~~~~~~~~~~~ InterestManager__EntityNewInterestZoneMessage:: InterestManager__EntityNewInterestZoneMessage( const EntityID &entity_ID, InterestZoneID interest_zone_ID ): NetworkClient::Message( InterestManager::EntityNewInterestZoneMessageID, sizeof(InterestManager__EntityNewInterestZoneMessage) ) { entityID = entity_ID; interestZoneID = interest_zone_ID; } //~~~~~~~~~~~~~~~~~ InterestManager__HostInterestArenaChangedMessage ~~~~~~~~~~ InterestManager__HostInterestArenaChangedMessage:: InterestManager__HostInterestArenaChangedMessage(): NetworkClient::Message( InterestManager::HostInterestArenaChangedMessageID, sizeof(InterestManager__HostInterestArenaChangedMessage) ) { } //~~~~~~~~~~~~~~~~~ InterestManager__InterestZoneDeltaMessage ~~~~~~~~~~~~~~~~~ InterestManager__InterestZoneDeltaMessage:: InterestManager__InterestZoneDeltaMessage(): NetworkClient::Message( InterestManager::InterestZoneDeltaMessageID, sizeof(InterestManager__InterestZoneDeltaMessage) ) { }