Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
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.
2026-06-24 21:28:16 -05:00

629 lines
15 KiB
C++

//===========================================================================//
// File: table.cc //
// Project: MUNGA Brick: Connection Library //
// Contents: Implementation details of Table class //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 09/30/94 ECH Initial coding. //
// 11/02/94 JMA Made compatible with SGI CC, merged with iterator //
// 11/03/94 ECH Made compatible with BC4.0 //
// 11/05/94 JMA Made compatible with GNU C++ //
// 12/12/94 ECH Changed release handling //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
// PROPRIETARY AND CONFIDENTIAL //
//===========================================================================//
#include "StuffHeaders.hpp"
//
//###########################################################################
// TABLEENTRY
//###########################################################################
//
TableEntry::~TableEntry()
{
Check_Object(this);
Table *table = Cast_Object(Table*, m_socket);
unsigned index;
//
//--------------------------------------
// Find the link in the table and remove
//--------------------------------------
//
index = table->SearchForTableEntry(this);
table->RemoveNthTableEntry(index);
//
//--------------------------------------------
// Notify iterators that link is being deleted
//--------------------------------------------
//
table->SendIteratorMemo(PlugRemoved, &index);
//
//------------------------------------------
// Remove this link from any m_plug references
//------------------------------------------
//
ReleaseFromPlug();
}
//
//###########################################################################
// TABLE
//###########################################################################
//
//
//###########################################################################
// Table
//###########################################################################
//
Table::Table(
void *,
bool has_unique_entries
):
SortedSocket(NULL, has_unique_entries)
{
m_numItems = 0;
}
//
//###########################################################################
// ~Table
//###########################################################################
//
Table::~Table()
{
Check_Object(this);
int i = m_numItems;
while (i > 0)
{
--i;
Check_Object(m_array[i]);
delete m_array[i];
}
}
//
//###########################################################################
// TestInstance
//###########################################################################
//
void
Table::TestInstance()
{
SortedSocket::TestInstance();
if (m_numItems > 0 || m_array.GetLength() > 0)
{
Verify(m_numItems > 0);
Verify(m_numItems <= m_array.GetLength());
}
}
//
//###########################################################################
// DeletePlugs
//###########################################################################
//
void
Table::DeletePlugs()
{
Check_Object(this);
int i = m_numItems;
while (i > 0)
{
--i;
Check_Object(m_array[i]);
Check_Object(m_array[i]->GetPlug());
delete m_array[i]->GetPlug();
}
}
//
//###########################################################################
// GetSize
//###########################################################################
//
unsigned
Table::GetSize()
{
return m_numItems;
}
//
//###########################################################################
// GetNthImplementation
//###########################################################################
//
void
*Table::GetNthItem(unsigned index)
{
if (index < m_numItems)
return m_array[index]->GetPlug();
return NULL;
}
//
//#############################################################################
// IsEmpty
//#############################################################################
//
bool
Table::IsEmpty()
{
Check_Object(this);
return (m_numItems == (unsigned)0);
}
//
//###########################################################################
// AddValueImplementation
//###########################################################################
//
void
Table::AddValuePlug(
Plug *m_plug,
const void *value
)
{
Check_Object(this);
TableEntry *link;
/*
* Verify that value has not been added
*/
Verify(HasUniqueEntries() ? (SearchForValue(value) == TableNullIndex) : true);
/*
* Make new table entry
*/
link = MakeTableEntry(m_plug, value);
Register_Object(link);
/*
* Add, sort and send memo to iterators to update references
*/
AddTableEntry(link);
SortTableEntries();
SendIteratorMemo(PlugAdded, link);
}
//
//###########################################################################
// FindImplementation
//###########################################################################
//
Plug*
Table::FindPlug(const void *value)
{
Check_Object(this);
unsigned index;
if ((index = SearchForValue(value)) != TableNullIndex)
{
Check_Object(m_array[index]);
return m_array[index]->GetPlug();
}
return NULL;
}
//
//###########################################################################
// AddTableEntry
//###########################################################################
//
void
Table::AddTableEntry(
TableEntry *link
)
{
Check_Object(link);
unsigned new_num_items = m_numItems+1;
if (new_num_items > m_array.GetLength())
m_array.SetLength(new_num_items);
m_array[m_numItems] = link;
m_numItems = new_num_items;
}
//
//###########################################################################
// SortTableEntries
//###########################################################################
//
void
Table::SortTableEntries()
{
Check_Object(this);
size_t i, j;
TableEntry *temp;
for (i = 1; i < m_numItems; i++)
{
temp = m_array[i];
j = i;
Verify(j-1 < m_numItems);
while (CompareTableEntries(m_array[j-1], temp) > 0)
{
Verify(j < m_numItems);
Verify(j-1 < m_numItems);
m_array[j] = m_array[j-1];
j--;
if (j < 1)
break;
}
Verify(j < m_numItems);
m_array[j] = temp;
}
}
//
//###########################################################################
// SearchForValue
//###########################################################################
//
unsigned
Table::SearchForValue(
const void *value
)
{
Check_Object(this);
unsigned n = m_numItems;
unsigned i = 0, j;
int k;
while (i < n)
{
j = (i + n - 1) >> 1;
if ((k = CompareValueToTableEntry(value, m_array[j])) == 0)
return j;
if (k < 0)
n = j;
else
i = j + 1;
}
return TableNullIndex;
}
//
//###########################################################################
// SearchForTableEntry
//###########################################################################
//
unsigned
Table::SearchForTableEntry(
TableEntry *link
)
{
Check_Object(this);
unsigned i;
for (i = 0; i < m_numItems; i++)
{
if (m_array[i] == link)
return i;
}
return TableNullIndex;
}
//
//###########################################################################
// RemoveNthTableEntry
//###########################################################################
//
void
Table::RemoveNthTableEntry(
unsigned index
)
{
Check_Object(this);
char *itemPtr, *lastItem;
size_t width;
/*
* Find the location of the item
*/
itemPtr = Cast_Pointer(char*, &m_array[index]);
/*
* Remove the item from the m_array
*/
width = sizeof(void*);
lastItem = Cast_Pointer(char*, m_array.GetData()) + (m_numItems - 1) * width;
if (itemPtr < lastItem)
memmove(itemPtr, itemPtr + width, (size_t)(lastItem - itemPtr));
/*
* Resize the m_array
*/
unsigned new_num_items = m_numItems-1;
if (new_num_items == 0)
m_array.SetLength(0);
m_numItems = new_num_items;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~ TableIterator inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~~
#if defined(_ARMOR)
TableEntry*
TableIterator::NthEntry(
unsigned index
)
{
Check_Object(this);
Table *table = Cast_Object(Table*, m_socket);
Check_Object(table->m_array[index]);
return table->m_array[index];
}
#endif
//
//###########################################################################
// TableIterator
//###########################################################################
//
TableIterator::TableIterator(Table *table):
SortedIterator(table)
{
if (table->m_array.GetLength() > 0)
m_currentPosition = 0;
else
m_currentPosition = TableNullIndex;
}
//
//###########################################################################
//###########################################################################
//
TableIterator::~TableIterator()
{
}
//
//###########################################################################
// First
//###########################################################################
//
Iterator&
TableIterator::First()
{
Table *table = Cast_Object(Table*,m_socket);
if (table->m_array.GetLength()>0)
m_currentPosition = 0;
return *this;
}
//
//###########################################################################
// Last
//###########################################################################
//
Iterator&
TableIterator::Last()
{
Table *table = Cast_Object(Table*,m_socket);
if (table->m_array.GetLength()>0)
m_currentPosition = table->m_numItems - 1;
return *this;
}
//
//###########################################################################
// Next
//###########################################################################
//
Iterator&
TableIterator::Next()
{
IncrementPosition();
return *this;
}
//
//###########################################################################
// Previous
//###########################################################################
//
Iterator&
TableIterator::Previous()
{
DecrementPosition();
return *this;
}
//
//###########################################################################
// ReadAndNextImplementation
//###########################################################################
//
void
*TableIterator::ReadAndNextItem()
{
if (m_currentPosition != TableNullIndex)
{
Plug *plug;
plug = NthEntry(m_currentPosition)->GetPlug();
IncrementPosition();
return plug;
}
return NULL;
}
//
//###########################################################################
// ReadAndPreviousImplementation
//###########################################################################
//
void
*TableIterator::ReadAndPreviousItem()
{
if (m_currentPosition != TableNullIndex)
{
Plug *m_plug;
m_plug = NthEntry(m_currentPosition)->GetPlug();
DecrementPosition();
return m_plug;
}
return NULL;
}
//
//###########################################################################
// GetCurrentItem
//###########################################################################
//
void
*TableIterator::GetCurrentItem()
{
if (m_currentPosition != TableNullIndex)
{
return NthEntry(m_currentPosition)->GetPlug();
}
return NULL;
}
//
//###########################################################################
// GetNthImplementation
//###########################################################################
//
void
*TableIterator::GetNthItem(unsigned index)
{
Table *table = Cast_Object(Table*, m_socket);
if (index < table->m_numItems)
return table->m_array[m_currentPosition=index]->GetPlug();
return NULL;
}
//
//###########################################################################
// Remove
//###########################################################################
//
void
TableIterator::Remove()
{
if (m_currentPosition != TableNullIndex)
{
Check_Object(NthEntry(m_currentPosition));
delete NthEntry(m_currentPosition);
}
}
//
//###########################################################################
// FindImplementation
//###########################################################################
//
Plug
*TableIterator::FindPlug(const void *value)
{
unsigned index;
Table *table = Cast_Object(Table*, m_socket);
if ((index = table->SearchForValue(value)) != TableNullIndex)
{
if (!table->HasUniqueEntries())
{
while (
index-1 >= 0 &&
table->CompareTableEntries(NthEntry(index-1), NthEntry(index)) == 0
)
{
index--;
}
}
return (NthEntry(m_currentPosition = index)->GetPlug());
}
m_currentPosition = TableNullIndex;
return NULL;
}
//
//###########################################################################
// FindImplementation
//###########################################################################
//
void*
TableIterator::GetPlugValue()
{
Check_Object(this);
STOP(("Not implemented"));
return NULL;
}
//
//###########################################################################
// ReceiveMemo
//###########################################################################
//
void
TableIterator::ReceiveMemo(
IteratorMemo memo,
void *content
)
{
switch (memo)
{
case PlugAdded:
{
Table *table = Cast_Object(Table*, m_socket);
Check_Object(table);
//
// If a m_plug is added before or at the current position then
// the current position should be incremented one forward,
// otherwise, no action is necessary
//
TableEntry *link;
unsigned index;
link = Cast_Object(TableEntry*, content);
index = table->SearchForTableEntry(link);
if (index <= m_currentPosition)
m_currentPosition++;
Verify(TableNullIndex == m_currentPosition || m_currentPosition < table->m_numItems);
}
break;
case PlugRemoved:
{
Table *table = Cast_Object(Table*, m_socket);
Check_Object(table);
//
// If a m_plug is removed before the current position then decrement
// the current position, else if the current position is at the end
// of the table then decrement the counter
//
unsigned index;
index = *Cast_Pointer(unsigned*,content);
if (m_currentPosition != TableNullIndex)
{
if (index < m_currentPosition || table->m_numItems <= m_currentPosition)
m_currentPosition--;
}
Verify(TableNullIndex == m_currentPosition || m_currentPosition < table->m_numItems);
}
break;
}
}