Files
RP412/MUNGA/CHAIN.cpp
T
CydandClaude Opus 4.8 4abbf8879f Initial import of Red Planet v4.10 Win32 source
Imports the current Win32 source for the pod-racing game 'Red Planet',
built on the MUNGA engine and its L4 (Win32/DirectX) platform layer:

- MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend
- RP / RP_L4: Red Planet game logic and Win32 application
- DivLoader, Setup1: asset loader and installer project
- lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies

Removed stale Subversion metadata and added .gitignore/.gitattributes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 07:59:51 -05:00

452 lines
9.2 KiB
C++

#include "munga.h"
#pragma hdrstop
#include "chain.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainLink ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MemoryBlock *ChainLink::GetAllocatedMemory()
{
static MemoryBlock allocatedMemory(sizeof(ChainLink), CHAINLINK_MEMORYBLOCK_ALLOCATION, CHAINLINK_MEMORYBLOCK_ALLOCATION, "ChainLink");
return &allocatedMemory;
}
//
//#############################################################################
// ChainLink
//#############################################################################
//
ChainLink::ChainLink(
Chain *chain,
Plug *plug,
ChainLink *next_link,
ChainLink *prev_link
):
Link(chain, plug)
{
//
//-------------------------
// Link into existing chain
//-------------------------
//
if ((nextChainLink = next_link) != NULL)
{
Check(nextChainLink);
nextChainLink->prevChainLink = this;
}
if ((prevChainLink = prev_link) != NULL)
{
Check(prevChainLink);
prevChainLink->nextChainLink = this;
}
}
//
//#############################################################################
// ~ChainLink
//#############################################################################
//
ChainLink::~ChainLink()
{
Chain *chain = Cast_Object(Chain*, socket);
//
//--------------------------------------
// Remove this link from the linked list
//--------------------------------------
//
if (prevChainLink != NULL)
{
Check(prevChainLink);
prevChainLink->nextChainLink = nextChainLink;
}
else
{
Check(chain);
chain->head = nextChainLink;
}
if (nextChainLink != NULL)
{
Check(nextChainLink);
nextChainLink->prevChainLink = prevChainLink;
}
else
{
Check(chain);
chain->tail = prevChainLink;
}
prevChainLink = nextChainLink = NULL;
//
//------------------------------------------
// Remove this link from any plug references
//------------------------------------------
//
ReleaseFromPlug();
//
//-------------------------------------------------------------
// Tell the node to release this link. Note that this link
// is not referenced by the plug or the chain at this point in
// time.
//-------------------------------------------------------------
//
if (chain->GetReleaseNode() != NULL)
{
Check(chain->GetReleaseNode());
chain->GetReleaseNode()->ReleaseLinkHandler(chain, plug);
}
}
//
//#############################################################################
// TestInstance
//#############################################################################
//
Logical
ChainLink::TestInstance() const
{
Link::TestInstance();
if (prevChainLink != NULL)
{
Check_Signature(prevChainLink);
}
if (nextChainLink != NULL)
{
Check_Signature(nextChainLink);
}
return( True );
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Chain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//#############################################################################
// Chain
//#############################################################################
//
Chain::Chain(Node *node):
Socket(node)
{
head = NULL;
tail = NULL;
}
//
//#############################################################################
// ~Chain
//#############################################################################
//
Chain::~Chain()
{
SetReleaseNode(NULL);
while (head != NULL)
{
Unregister_Object(head);
delete head;
}
}
//
//#############################################################################
// TestInstance
//#############################################################################
//
Logical
Chain::TestInstance() const
{
Socket::TestInstance();
if (head != NULL)
{
Check(head);
}
if (tail != NULL)
{
Check(tail);
}
return True;
}
//
//#############################################################################
// AddImplementation
//#############################################################################
//
void
Chain::AddImplementation(Plug *plug)
{
Check(this);
tail = new ChainLink(this, plug, NULL, tail);
Register_Object(tail);
if (head == NULL)
{
head = tail;
}
}
//
//#############################################################################
// InsertChainLink
//#############################################################################
//
ChainLink*
Chain::InsertChainLink(
Plug *plug,
ChainLink *current_link
)
{
Check(this);
Check(plug);
Check(current_link);
ChainLink *new_link =
new ChainLink(
this,
plug,
current_link,
current_link->prevChainLink
);
Register_Object(new_link);
Check(head);
if (head == current_link)
{
head = new_link;
}
return new_link;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainIterator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//#############################################################################
// ChainIterator
//#############################################################################
//
ChainIterator::ChainIterator(Chain *chain):
SocketIterator(chain)
{
Check(chain);
currentLink = chain->head;
}
ChainIterator::ChainIterator(const ChainIterator &iterator):
SocketIterator(Cast_Object(Chain*, iterator.socket))
{
Check(&iterator);
currentLink = iterator.currentLink;
}
ChainIterator::~ChainIterator()
{
}
//
//###########################################################################
// TestInstance
//###########################################################################
//
Logical
ChainIterator::TestInstance() const
{
SocketIterator::TestInstance();
if (currentLink != NULL)
{
Check( currentLink );
}
return(True);
}
//
//###########################################################################
// First
//###########################################################################
//
void
ChainIterator::First()
{
currentLink = Cast_Object(Chain*, socket)->head;
}
//
//###########################################################################
// Last
//###########################################################################
//
void
ChainIterator::Last()
{
currentLink = Cast_Object(Chain*, socket)->tail;
}
//
//###########################################################################
// Next
//###########################################################################
//
void
ChainIterator::Next()
{
Check(currentLink);
currentLink = currentLink->nextChainLink;
}
//
//###########################################################################
// Previous
//###########################################################################
//
void
ChainIterator::Previous()
{
Check( currentLink );
currentLink = currentLink->prevChainLink;
}
//
//###########################################################################
// ReadAndNextImplementation
//###########################################################################
//
void*
ChainIterator::ReadAndNextImplementation()
{
if (currentLink != NULL)
{
Plug *plug;
Check(currentLink);
plug = currentLink->plug;
currentLink = currentLink->nextChainLink;
return plug;
}
return NULL;
}
//
//###########################################################################
// ReadAndPreviousImplementation
//###########################################################################
//
void*
ChainIterator::ReadAndPreviousImplementation()
{
if (currentLink != NULL)
{
Plug *plug;
Check(currentLink);
plug = currentLink->plug;
currentLink = currentLink->prevChainLink;
return plug;
}
return NULL;
}
//
//###########################################################################
// GetCurrentImplementation
//###########################################################################
//
void*
ChainIterator::GetCurrentImplementation()
{
if (currentLink != NULL)
{
Check(currentLink);
return currentLink->plug;
}
return NULL;
}
//
//###########################################################################
// GetSize
//###########################################################################
//
CollectionSize
ChainIterator::GetSize()
{
ChainLink *link;
CollectionSize count;
count = 0;
for (
link = Cast_Object(Chain*, socket)->head;
link != NULL;
link = link->nextChainLink
) {
Check(link);
count++;
}
return count;
}
//
//###########################################################################
// GetNthImplementation
//###########################################################################
//
void*
ChainIterator::GetNthImplementation(CollectionSize index)
{
ChainLink *link;
CollectionSize count;
count = 0;
for (
link = Cast_Object(Chain*, socket)->head;
link != NULL;
link = link->nextChainLink
) {
Check(link);
if (count == index) {
currentLink = link;
return currentLink->plug;
}
count++;
}
return NULL;
}
//
//###########################################################################
// Remove
//###########################################################################
//
void
ChainIterator::Remove()
{
ChainLink *oldLink = currentLink;
Check(currentLink);
currentLink = currentLink->nextChainLink;
Unregister_Object(oldLink);
delete oldLink ;
}
//
//###########################################################################
// InsertImplementation
//###########################################################################
//
void
ChainIterator::InsertImplementation(Plug *plug)
{
currentLink =
Cast_Object(Chain*, socket)->InsertChainLink(plug, currentLink);
Check(currentLink);
}
#ifdef TEST_CLASS
# include "chain.tcp"
#endif