//===========================================================================// // File: cmpnnt.cc // // Project: MUNGA Brick: Entity // // Contents: // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 12/14/94 ECH Initial coding. // //---------------------------------------------------------------------------// // Copyright (C) 1994-1995, Virtual World Entertainment, Inc. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include "AdeptHeaders.hpp" #include "Entity.hpp" #include "Channel.hpp" ComponentWeb::ClassData* ComponentWeb::DefaultData = NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ComponentWeb::InitializeClass() { Verify(!DefaultData); DefaultData = new ClassData( ComponentWebClassID, "Adept::ComponentWeb", Plug::DefaultData ); Register_Object(DefaultData); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ComponentWeb::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ComponentWeb::ComponentWeb( ClassData *class_data, const ResourceID &script_id, ComponentWeb *parent_web ): Plug(class_data), ownedComponents(NULL), ownedWebs(NULL), watcherComponents(NULL), temporaryWatchers(NULL, false), commandReceivers(NULL) { // //----------------------------- // Initialize the web variables //----------------------------- // parentWeb = parent_web; scriptResourceID = script_id; // //------------------------------------- // If we belong to another web, hook up //------------------------------------- // if (parentWeb) { Check_Object(parentWeb); parentWeb->AddComponentWeb(this); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ComponentWeb::~ComponentWeb() { Check_Object(this); // //---------------------------------- // Delete any components that we own //---------------------------------- // ChainIteratorOf components(&ownedComponents); Component *component; while ((component = components.ReadAndNext()) != NULL) { Unregister_Object(component); delete component; } // //------------------------------------------------------ // Delete any component webs we own if they don't object //------------------------------------------------------ // ChainIteratorOf webs(&ownedWebs); ComponentWeb *web; while ((web = webs.ReadAndNext()) != NULL) { Check_Object(web); if (web->ShouldWebBeKilled()) { Unregister_Object(web); delete web; } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool ComponentWeb::ShouldWebBeKilled() { Check_Object(this); return true; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Component* ComponentWeb::AddComponent(Component *component) { Check_Object(this); Check_Object(component); // //--------------------------------------------------------------- // If the component is a watcher, hook it up to our watcher chain //--------------------------------------------------------------- // if (component->ShouldSimulationExecute()) { Verify(!component->ShouldRendererExecute()); watcherComponents.Add(component); } // //----------------------------------------------------------------------- //If the component can process commands, hook it up the the command chain //----------------------------------------------------------------------- // if (component->DoesReceiveCommands()) commandReceivers.Add(component); ownedComponents.Add(component); return component; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ComponentWeb::AddComponentWeb(ComponentWeb *web) { Check_Object(this); Check_Object(web); ownedWebs.Add(web); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Component* ComponentWeb::FindComponent(const ComponentID &component_id) { Check_Object(this); // //---------------------------- // See if we own the component //---------------------------- // ChainIteratorOf components(&ownedComponents); Component *component; while ((component = components.ReadAndNext()) != NULL) { Check_Object(component); if (component->GetComponentID() == component_id) { break; } } // //---------------------------------- // It can't be found, so return NULL //---------------------------------- // return component; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ComponentWeb::ExecuteWatcherComponents() { Check_Object(this); // //------------------------------- // Execute the permanent watchers //------------------------------- // if (!watcherComponents.IsEmpty()) { ChainIteratorOf components(&watcherComponents); Component *component; while ((component = components.ReadAndNext()) != NULL) { Check_Object(component); component->Execute(); } } // //------------------------------------ // Now, execute any temporary watchers //------------------------------------ // if (!temporaryWatchers.IsEmpty()) { SortedChainIteratorOf temporaries(&temporaryWatchers); Component *component; while ((component = temporaries.GetCurrent()) != NULL) { Check_Object(component); component->Execute(); component->ClearSimulationShouldExecuteOnce(); temporaries.Remove(); temporaries.First(); } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ComponentWeb::AddTemporaryWatcher(Component *component) { Check_Object(this); Check_Object(component); if (!component->ShouldSimulationExecuteOnce()) { temporaryWatchers.AddValue(component, component->GetWatcherPriority()); component->SetSimulationShouldExecuteOnce(); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ComponentWeb::SendCommand(int component_command) { Check_Object(this); Channel command_channel; command_channel.SetCommand(component_command); Component *component; ChainIteratorOf iterator(&commandReceivers); while((component = iterator.ReadAndNext()) != NULL) { Check_Object(component); component->ChannelChanged(&command_channel); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void ComponentWeb::TestInstance() { Verify(IsDerivedFrom(DefaultData)); } EntityComponentWeb::ClassData* EntityComponentWeb::DefaultData = NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EntityComponentWeb::InitializeClass() { Verify(!DefaultData); DefaultData = new ClassData( EntityComponentWebClassID, "Adept::EntityComponentWeb", ComponentWeb::DefaultData ); Register_Object(DefaultData); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EntityComponentWeb::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // EntityComponentWeb::EntityComponentWeb( ClassData *class_data, Entity *entity, const ResourceID &script_id, EntityComponentWeb *parent_web ): ComponentWeb(class_data, script_id, parent_web) { Check_Object(entity); // //----------------------------- // Initialize the web variables //----------------------------- // owningEntity = entity; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // EntityComponentWeb::~EntityComponentWeb() { Check_Object(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void EntityComponentWeb::TestInstance() { Verify(IsDerivedFrom(DefaultData)); } RendererComponentWeb::ClassData* RendererComponentWeb::DefaultData = NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RendererComponentWeb::InitializeClass() { Verify(!DefaultData); DefaultData = new ClassData( RendererComponentWebClassID, "Adept::RendererComponentWeb", EntityComponentWeb::DefaultData ); Register_Object(DefaultData); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RendererComponentWeb::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // RendererComponentWeb::RendererComponentWeb( ClassData *class_data, Entity *entity, Renderer *renderer, const ResourceID &script_id, RendererComponentWeb *parent_web ): EntityComponentWeb(class_data, entity, script_id, parent_web) { Check_Object(renderer); // //----------------------------- // Initialize the web variables //----------------------------- // owningRenderer = renderer; renderer->AddComponentWeb(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // RendererComponentWeb::~RendererComponentWeb() { Check_Object(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RendererComponentWeb::LoadComponentWeb() { Check_Object(this); // //------------------------------- // Now, find the component stream //------------------------------- // if (scriptResourceID == ResourceID::Null) { return; } Resource script(scriptResourceID); // //----------------------------------------- // Create the components, then execute them //----------------------------------------- // LoadFromStream(&script); ExecuteWatcherComponents(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RendererComponentWeb::LoadFromStream(MemoryStream *stream) { Check_Object(this); Check_Object(stream); Check_Object(owningEntity); // //-------------------------------------- // Loop through and build each component //-------------------------------------- // int count; *stream >> count; Warn(count == 0); while (count--) { // //--------------------- // Create the component //--------------------- // int length; #if defined(_ARMOR) char *record_end = Cast_Pointer(char*, stream->GetPointer()); *stream >> length; record_end += length; #else *stream >> length; #endif ClassID class_id; *stream >> class_id; Component *component = owningRenderer->CreateComponent( class_id, stream, this, owningEntity ); // //----------------------------------------------------------------- // Add it to the web, then check to see if we need to add it to the // renderer execution lists //----------------------------------------------------------------- // AddComponent(component); Verify(record_end == Cast_Pointer(char*, stream->GetPointer())); if (component->ShouldRendererExecute()) { Verify(!component->ShouldSimulationExecute()); owningRenderer->AddExecutableComponent(component); } // //---------------------------------------------------------------------- // Any simulation executed components must run in post collision, so set // the entity appropriately //---------------------------------------------------------------------- // if (component->ShouldSimulationExecute()) owningEntity->UsePostCollision(); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Component* RendererComponentWeb::AddComponent(Component *component) { Check_Object(this); Check_Object(component); // //---------------------------------------------------------------------- // If we are marked as unique, have the renderer deal with the component //---------------------------------------------------------------------- // if (component->IsShared()) { Check_Object(owningRenderer); return owningRenderer->AddSharedComponent(component); } return EntityComponentWeb::AddComponent(component); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Component* RendererComponentWeb::FindComponent(const ComponentID &component_id) { Check_Object(this); // //------------------------------------------------ // See if the renderer knows who this component is //------------------------------------------------ // Check_Object(owningRenderer); Component *component = owningRenderer->FindSharedComponent(component_id); if (component) { return component; } return EntityComponentWeb::FindComponent(component_id); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void RendererComponentWeb::TestInstance() { Verify(IsDerivedFrom(DefaultData)); }