#include "munga.h" #pragma hdrstop #include "update.h" #include "app.h" #include "hostmgr.h" #include "interest.h" #include "entity.h" #if defined(TRACE_UPDATE_REPLICANTS) static BitTrace Update_Replicants("Update Replicants"); #define SET_UPDATE_REPLICANTS() Update_Replicants.Set() #define CLEAR_UPDATE_REPLICANTS() Update_Replicants.Clear() #else #define SET_UPDATE_REPLICANTS() #define CLEAR_UPDATE_REPLICANTS() #endif #if defined(TRACE_UPDATE_MASTERS) static BitTrace Update_Masters("Update Masters"); #define SET_UPDATE_MASTERS() Update_Masters.Set() #define CLEAR_UPDATE_MASTERS() Update_Masters.Clear() #else #define SET_UPDATE_MASTERS() #define CLEAR_UPDATE_MASTERS() #endif MemoryBlock *SimulationEncore::GetAllocatedMemory() { static MemoryBlock allocatedMemory(sizeof(SimulationEncore), 10, 10, "Simulation Encores"); return &allocatedMemory; } SimulationEncore::SimulationEncore( Simulation *sim, Simulation::Encore callback ) { encoreSimulation = sim; encoreCallback = callback; runWatchers = True; } SimulationEncore::~SimulationEncore() { } // //############################################################################# //############################################################################# // UpdateManager::UpdateManager(): simulationEncores(NULL) { } // //############################################################################# //############################################################################# // UpdateManager::~UpdateManager() { ChainIteratorOf encores(simulationEncores); SimulationEncore *encore; while ((encore = encores.ReadAndNext()) != NULL) { Unregister_Object(encore); delete encore; } } // //############################################################################# //############################################################################# // Logical UpdateManager::TestInstance() const { Node::TestInstance(); return True; } // //############################################################################# //############################################################################# // void UpdateManager::Execute(Time target_render_time) { Check(this); // //-------------------------------------------------------------------------- // Execute the replicants and masters that are interesting and dynamic //-------------------------------------------------------------------------- // Check(application); Check(application->GetHostManager()); HostManager::DynamicReplicantEntityIterator replicant_entity_iterator(application->GetHostManager()); HostManager::DynamicMasterEntityIterator master_entity_iterator(application->GetHostManager()); // //-------------------------------------------------------------------------- // Execute the replicants //-------------------------------------------------------------------------- // SET_UPDATE_REPLICANTS(); Entity *replicant; while ((replicant = replicant_entity_iterator.ReadAndNext()) != NULL) { Check(replicant); if (replicant->IsReplicantExecutable()) { replicant->Execute(target_render_time); } } CLEAR_UPDATE_REPLICANTS(); // //-------------------------------------------------------------------------- // Execute the master entities, if they need to be updated then send // update messages, and notify the interest manager of moved entities //-------------------------------------------------------------------------- // SET_UPDATE_MASTERS(); Entity *entity; Entity::UpdateMessage *update_message; while ((entity = master_entity_iterator.ReadAndNext()) != NULL) { Check(entity); // //----------------------------------------------------------------------- // If the entity is not interesting then skip it //----------------------------------------------------------------------- // if (!entity->IsInteresting() || !entity->IsNonReplicantExecutable()) { continue; } // //----------------------------------------------------------------------- // Run the execute method //----------------------------------------------------------------------- // update_message = entity->Execute(target_render_time); // //----------------------------------------------------------------------- // Update the interest zone id //----------------------------------------------------------------------- // Check(application); Check(application->GetInterestManager()); application->GetInterestManager()->EntityUpdateInterestZone(entity); // //----------------------------------------------------------------------- // If update message is not null then send the change //----------------------------------------------------------------------- // if (update_message != NULL) { Check(update_message); Check(application); application->GetInterestManager()->EntityUpdateReplicants( entity, update_message ); } } // //-------------------------------------------------------------------------- // Lastly, run through and do any requested encores //-------------------------------------------------------------------------- // ChainIteratorOf encores(simulationEncores); SimulationEncore *encore; while ((encore = encores.ReadAndNext()) != NULL) { Check(encore); Check(encore->encoreSimulation); (encore->encoreSimulation->*encore->encoreCallback)(); if (encore->runWatchers) { encore->encoreSimulation->ExecuteWatchers(); encore->encoreSimulation->ClearWatcherDelay(); } Unregister_Object(encore); delete encore; } CLEAR_UPDATE_MASTERS(); } // //############################################################################# //############################################################################# // void UpdateManager::RequestEncore( Simulation *simulation, Simulation::Encore encore ) { // //---------------------------------------------------------------------- // Make sure that we only run the watcher on a given simulation once per // frame //---------------------------------------------------------------------- // ChainIteratorOf encores(simulationEncores); SimulationEncore *i; while ((i = encores.ReadAndNext()) != NULL) { if (i->encoreSimulation == simulation && i->runWatchers) { i->runWatchers = False; break; } } SimulationEncore *request = new SimulationEncore(simulation, encore); Register_Object(request); simulationEncores.Add(request); }