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.
388 lines
9.5 KiB
C++
388 lines
9.5 KiB
C++
//===========================================================================//
|
|
// File: m_chain.cc //
|
|
// Project: MUNGA Brick: Connection Engine //
|
|
// Contents: Implementation details of chains and their iterators //
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
// 09/29/94 ECH Initial coding. //
|
|
// 10/20/94 JMA Fixed style stuff. Merged with CHNITR.HPP, and added //
|
|
// operator functions to iterator //
|
|
// 10/23/94 ECH Added greater deletion safety //
|
|
// 10/28/94 JMA Made compatible with SGI CC //
|
|
// 11/03/94 ECH Made compatible with BC4.0 //
|
|
// 12/12/94 ECH Changed release handling //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
|
|
// PROPRIETARY AND CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
#include "StuffHeaders.hpp"
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainLink ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
MemoryBlock*
|
|
ChainLink::s_AllocatedMemory = NULL;
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
ChainLink::InitializeClass(size_t block_count)
|
|
{
|
|
Verify(!s_AllocatedMemory);
|
|
s_AllocatedMemory =
|
|
new MemoryBlock(
|
|
sizeof(ChainLink),
|
|
block_count,
|
|
block_count>>2,
|
|
"Stuff::ChainLink",
|
|
g_ConnectionEngineHeap
|
|
);
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
ChainLink::TerminateClass()
|
|
{
|
|
delete s_AllocatedMemory;
|
|
s_AllocatedMemory = NULL;
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
// ~ChainLink
|
|
//#############################################################################
|
|
//
|
|
ChainLink::~ChainLink()
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(m_chain);
|
|
|
|
//
|
|
//------------------------
|
|
// Unlink the forward link
|
|
//------------------------
|
|
//
|
|
if (m_nextChainLink)
|
|
{
|
|
Check_Object(m_nextChainLink);
|
|
m_nextChainLink->m_prevChainLink = m_prevChainLink;
|
|
}
|
|
else
|
|
{
|
|
Verify(m_chain->m_tail == this);
|
|
m_chain->m_tail = m_prevChainLink;
|
|
}
|
|
|
|
//
|
|
//-------------------------
|
|
// Unlink the backward link
|
|
//-------------------------
|
|
//
|
|
if (m_prevChainLink)
|
|
{
|
|
Check_Object(m_prevChainLink);
|
|
m_prevChainLink->m_nextChainLink = m_nextChainLink;
|
|
}
|
|
else
|
|
{
|
|
Verify(m_chain->m_head == this);
|
|
m_chain->m_head = m_nextChainLink;
|
|
}
|
|
|
|
//
|
|
//------------------------------------------
|
|
// Remove this link from any plug references
|
|
//------------------------------------------
|
|
//
|
|
m_nextChainLink = NULL;
|
|
m_prevChainLink = NULL;
|
|
ReleaseFromPlug();
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
// ChainLink
|
|
//#############################################################################
|
|
//
|
|
ChainLink::ChainLink(
|
|
Chain *m_chain,
|
|
Plug *plug,
|
|
ChainLink *next_link,
|
|
ChainLink *prev_link
|
|
):
|
|
m_chain(m_chain),
|
|
m_plug(plug)
|
|
{
|
|
//
|
|
//-------------------------
|
|
// ChainLink into existing m_chain
|
|
//-------------------------
|
|
//
|
|
AddToPlug(plug);
|
|
m_nextChainLink = next_link;
|
|
m_prevChainLink = prev_link;
|
|
if (prev_link)
|
|
{
|
|
Check_Object(prev_link);
|
|
prev_link->m_nextChainLink = this;
|
|
}
|
|
if (next_link)
|
|
{
|
|
Check_Object(next_link);
|
|
next_link->m_prevChainLink = this;
|
|
}
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
// ReleaseFromPlug
|
|
//#############################################################################
|
|
//
|
|
void
|
|
ChainLink::ReleaseFromPlug()
|
|
{
|
|
Check_Object(this);
|
|
|
|
//
|
|
//-----------------------------------------------------
|
|
// Remove this link from the plugs current set of links
|
|
//-----------------------------------------------------
|
|
//
|
|
Check_Object(m_plug);
|
|
ChainLink *link = m_plug->m_chainLinkHead;
|
|
Check_Object(link);
|
|
if (link == this)
|
|
{
|
|
if (m_nextPlugLink != this)
|
|
m_plug->m_chainLinkHead = m_nextPlugLink;
|
|
else
|
|
{
|
|
m_nextPlugLink = m_plug->m_chainLinkHead = NULL;
|
|
return;
|
|
}
|
|
}
|
|
while (link->m_nextPlugLink != this)
|
|
{
|
|
Check_Object(this);
|
|
link = link->m_nextPlugLink;
|
|
}
|
|
link->m_nextPlugLink = m_nextPlugLink;
|
|
m_nextPlugLink = NULL;
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
// AddToPlug
|
|
//#############################################################################
|
|
//
|
|
void
|
|
ChainLink::AddToPlug(Plug *plug)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(plug);
|
|
|
|
if (!plug->m_chainLinkHead)
|
|
m_nextPlugLink = this;
|
|
else
|
|
{
|
|
Check_Object(plug->m_chainLinkHead);
|
|
m_nextPlugLink = plug->m_chainLinkHead->m_nextPlugLink;
|
|
plug->m_chainLinkHead->m_nextPlugLink = this;
|
|
}
|
|
plug->m_chainLinkHead = this;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Chain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
//
|
|
//#############################################################################
|
|
// ~Chain
|
|
//#############################################################################
|
|
//
|
|
Chain::~Chain()
|
|
{
|
|
Check_Object(this);
|
|
ChainLink *link = m_head;
|
|
while (link)
|
|
{
|
|
Check_Object(link);
|
|
ChainLink *next = link->m_nextChainLink;
|
|
Check_Object(link);
|
|
delete link;
|
|
link = next;
|
|
}
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
// AddImplementation
|
|
//#############################################################################
|
|
//
|
|
void
|
|
Chain::AddPlug(Plug *plug)
|
|
{
|
|
Check_Object(this);
|
|
|
|
m_tail = new ChainLink(this, plug, NULL, m_tail);
|
|
if (!m_head)
|
|
m_head = m_tail;
|
|
}
|
|
|
|
//
|
|
//###########################################################################
|
|
// IsPlugMember
|
|
//###########################################################################
|
|
//
|
|
void
|
|
Chain::DeletePlugs()
|
|
{
|
|
ChainLink *link = m_head;
|
|
while (link)
|
|
{
|
|
Check_Object(link);
|
|
ChainLink *next = link->m_nextChainLink;
|
|
Check_Object(link);
|
|
Check_Object(link->GetPlug());
|
|
delete link->GetPlug();
|
|
link = next;
|
|
}
|
|
}
|
|
|
|
//
|
|
//###########################################################################
|
|
// GetNthImplementation
|
|
//###########################################################################
|
|
//
|
|
void*
|
|
Chain::GetNthItem(unsigned index)
|
|
{
|
|
Check_Object(this);
|
|
|
|
unsigned count = 0;
|
|
for (ChainLink *link = m_head; link != NULL; link = link->m_nextChainLink)
|
|
{
|
|
Check_Object(link);
|
|
if (count == index)
|
|
return link->m_plug;
|
|
count++;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
//###########################################################################
|
|
// GetSize
|
|
//###########################################################################
|
|
//
|
|
unsigned
|
|
Chain::GetSize()
|
|
{
|
|
Check_Object(this);
|
|
|
|
unsigned count=0;
|
|
for (ChainLink *link = m_head; link != NULL; link = link->m_nextChainLink)
|
|
{
|
|
Check_Object(link);
|
|
count++;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
// InsertChainLink
|
|
//#############################################################################
|
|
//
|
|
ChainLink*
|
|
Chain::InsertChainLink(
|
|
Plug *plug,
|
|
ChainLink *current_link
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(plug);
|
|
Check_Object(current_link);
|
|
|
|
ChainLink *new_link =
|
|
new ChainLink(
|
|
this,
|
|
plug,
|
|
current_link,
|
|
current_link->m_prevChainLink
|
|
);
|
|
Register_Object(new_link);
|
|
if (!new_link->m_prevChainLink)
|
|
{
|
|
Verify(m_head == current_link);
|
|
m_head = new_link;
|
|
}
|
|
return new_link;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainIterator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
//
|
|
//###########################################################################
|
|
// GetNthImplementation
|
|
//###########################################################################
|
|
//
|
|
void*
|
|
ChainIterator::GetNthItem(unsigned index)
|
|
{
|
|
Check_Object(this);
|
|
unsigned count = 0;
|
|
for (
|
|
ChainLink *link = m_chain->m_head;
|
|
link != NULL;
|
|
link = link->m_nextChainLink
|
|
)
|
|
{
|
|
Check_Object(link);
|
|
if (count == index)
|
|
{
|
|
m_currentLink = link;
|
|
return m_currentLink->m_plug;
|
|
}
|
|
count++;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
//###########################################################################
|
|
// Remove
|
|
//###########################################################################
|
|
//
|
|
void
|
|
ChainIterator::Remove()
|
|
{
|
|
Check_Object(this);
|
|
ChainLink *oldLink = m_currentLink;
|
|
|
|
Check_Object(m_currentLink);
|
|
m_currentLink = m_currentLink->m_nextChainLink;
|
|
|
|
Check_Object(oldLink);
|
|
delete oldLink;
|
|
}
|
|
|
|
//
|
|
//###########################################################################
|
|
// InsertImplementation
|
|
//###########################################################################
|
|
//
|
|
void
|
|
ChainIterator::InsertPlug(Plug *plug)
|
|
{
|
|
Check_Object(this);
|
|
m_currentLink =
|
|
m_chain->InsertChainLink(plug, m_currentLink);
|
|
Check_Object(m_currentLink);
|
|
}
|