Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
549 lines
14 KiB
C++
549 lines
14 KiB
C++
//===========================================================================//
|
|
// 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<Component*> 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<ComponentWeb*> 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<Component*> 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<Component*> components(&watcherComponents);
|
|
Component *component;
|
|
while ((component = components.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(component);
|
|
component->Execute();
|
|
}
|
|
}
|
|
|
|
//
|
|
//------------------------------------
|
|
// Now, execute any temporary watchers
|
|
//------------------------------------
|
|
//
|
|
if (!temporaryWatchers.IsEmpty())
|
|
{
|
|
SortedChainIteratorOf<Component*, int> 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<Component*> 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));
|
|
}
|