//===========================================================================// // File: table.hh // // Project: MUNGA Brick: Connection Library // // Contents: Interface specification for Tables // //---------------------------------------------------------------------------// // 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 // // 06/07/96 ECH Implemented socket based remove functionality // //---------------------------------------------------------------------------// // Copyright (C) 1994-1995, Virtual World Entertainment, Inc. // // PROPRIETARY AND CONFIDENTIAL // //===========================================================================// #pragma once #include "Stuff.hpp" #include "SortedSocket.hpp" #include "MemoryBlock.hpp" namespace Stuff { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TableEntry ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class Table; class _declspec(novtable) TableEntry: public Link { public: TableEntry( Table *table, Plug *plug ); ~TableEntry(); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TableEntryOf ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template class TableEntryOf: public TableEntry { public: TableEntryOf( Table *table, Plug *plug, const V &value ): TableEntry(table, plug) {m_value = value;} void* operator new(size_t); void operator delete(void *where); V GetValue() {return m_value;} V* GetValuePointer() {return &m_value;} private: static MemoryBlock *s_allocatedMemory; static int s_allocationCount; V m_value; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~ TableEntryOf templates ~~~~~~~~~~~~~~~~~~~~~~~~ template MemoryBlock* TableEntryOf::s_allocatedMemory = NULL; template int TableEntryOf::s_allocationCount = 0; template void* TableEntryOf::operator new(size_t) { Verify(s_allocationCount >= 0); if (s_allocationCount++ == 0) { s_allocatedMemory = new(g_Heap) MemoryBlock( sizeof(TableEntryOf), 100, 100, "Stuff::TableEntryOf", Stuff::g_ConnectionEngineHeap ); Register_Object(s_allocatedMemory); } Verify(s_allocationCount < INT_MAX); Check_Object(s_allocatedMemory); return s_allocatedMemory->New(); } template void TableEntryOf::operator delete(void *where) { Check_Object(s_allocatedMemory); s_allocatedMemory->Delete(where); if (--s_allocationCount == 0) { Unregister_Object(s_allocatedMemory); delete s_allocatedMemory; s_allocatedMemory = NULL; } Verify(s_allocationCount >= 0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ const unsigned TableNullIndex = -1; class _declspec(novtable) Table: public SortedSocket { friend class TableEntry; friend class TableIterator; public: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Public interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // // //-------------------------------------------------------------------- // Constructor, Destructor and testing //-------------------------------------------------------------------- // Table( void *node, bool has_unique_entries ); ~Table(); void TestInstance(); static bool TestClass(); static bool ProfileClass(); // //----------------------------------------------------------------------- // RemovePlug - Remove a plug from this socket, untyped access. //----------------------------------------------------------------------- // void DeletePlugs(); // //----------------------------------------------------------------------- // IsPlugMember - Determine if the plug is a member of this socket. //----------------------------------------------------------------------- // void* GetNthItem(unsigned index); // //----------------------------------------------------------------------- // IsEmpty - Returns true if the socket contains no plugs. //----------------------------------------------------------------------- // unsigned GetSize(); bool IsEmpty(); void AddValuePlug( Plug *plug, const void *value ); virtual Plug* FindPlug(const void *value); protected: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Private interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // virtual TableEntry *MakeTableEntry( Plug *plug, const void *value )=0; virtual int CompareTableEntries( TableEntry *entry1, TableEntry *entry2 )=0; virtual int CompareValueToTableEntry( const void *value, TableEntry *entry )=0; void AddTableEntry(TableEntry *entry); void SortTableEntries(); unsigned SearchForValue(const void *value); unsigned SearchForTableEntry(TableEntry *entry); void RemoveNthTableEntry(unsigned index); // //-------------------------------------------------------------------- // Private data //-------------------------------------------------------------------- // DynamicArrayOf m_array; unsigned m_numItems; }; inline TableEntry::TableEntry( Table *table, Plug *plug ): Link(table, plug) {Check_Object(this);} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TableOf ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template class TableOf: public Table { public: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Public interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // TableOf( void *node, bool has_unique_entries ): Table( NULL, has_unique_entries ) {} // //-------------------------------------------------------------------- // Socket methods (see Socket for full listing) //-------------------------------------------------------------------- // void AddValue( T plug, const V &value ) {Table::AddValuePlug(Cast_Object(Plug*,plug), &value);} void Remove(T plug) {Table::RemovePlug(Cast_Object(Plug*,plug));} T Find(const V &value) {return (T)Table::FindPlug(&value);} private: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Private interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // TableEntry* MakeTableEntry( Plug *plug, const void *value ) { return new TableEntryOf( this, plug, *Cast_Pointer(const V*, value) ); } int CompareTableEntries( TableEntry *entry1, TableEntry *entry2 ); int CompareValueToTableEntry( const void *value, TableEntry *entry ); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TableOf templates ~~~~~~~~~~~~~~~~~~~~~~~~~~~ template int TableOf::CompareTableEntries( TableEntry *entry1, TableEntry *entry2 ) { V *ptr1 = Cast_Object(TableEntryOf*, entry1)->GetValuePointer(); V *ptr2 = Cast_Object(TableEntryOf*, entry2)->GetValuePointer(); Check_Pointer(ptr1); Check_Pointer(ptr2); if (*ptr1 == *ptr2) return 0; return ((*ptr1 > *ptr2) ? 1 : -1); } template int TableOf::CompareValueToTableEntry( const void *value, TableEntry *link ) { Check_Pointer(value); V *ptr = Cast_Object(TableEntryOf*, link)->GetValuePointer(); Check_Pointer(ptr); if (*Cast_Pointer(const V*, value) == *ptr) return 0; return (*Cast_Pointer(const V*, value) > *ptr) ? 1 : -1; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TableIterator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class _declspec(novtable) TableIterator: public SortedIterator { public: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Public interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // // //-------------------------------------------------------------------- // Constructors, Destructor and testing //-------------------------------------------------------------------- // explicit TableIterator(Table *table); ~TableIterator(); // //-------------------------------------------------------------------- // Iterator methods (see Iterator for full listing) //-------------------------------------------------------------------- // Iterator& First(); Iterator& Last(); Iterator& Next(); Iterator& Previous(); void* GetCurrentItem(); void* ReadAndNextItem(); void* ReadAndPreviousItem(); void* GetNthItem(unsigned index); void Remove(); Plug* FindPlug(const void *value); void* GetPlugValue(); protected: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Protected interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // TableEntry* GetCurrentEntry() {return NthEntry(m_currentPosition);} // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Private interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // void ReceiveMemo( IteratorMemo memo, void *content ); TableEntry* NthEntry(unsigned index) #if defined(_ARMOR) ; #else {return Cast_Object(Table*,m_socket)->m_array[index];} #endif void IncrementPosition() {if (++m_currentPosition >= Cast_Object(Table*,m_socket)->m_numItems) m_currentPosition = TableNullIndex;} void DecrementPosition() {if (--m_currentPosition < 0) m_currentPosition = TableNullIndex;} // //-------------------------------------------------------------------- // Private data //-------------------------------------------------------------------- // unsigned m_currentPosition; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~ TableIteratorOf ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template class TableIteratorOf: public TableIterator { public: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Public interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // // //-------------------------------------------------------------------- // Constructors and Destructor //-------------------------------------------------------------------- // explicit TableIteratorOf(TableOf *table): TableIterator(table) {} Iterator* MakeClone() {return new TableIteratorOf(*this);} // //-------------------------------------------------------------------- // Iterator methods (see Iterator for full listing) //-------------------------------------------------------------------- // T ReadAndNext() {return (T)TableIterator::ReadAndNextItem();} T ReadAndPrevious() {return (T)TableIterator::ReadAndPreviousItem();} T GetCurrent() {return (T)TableIterator::GetCurrentItem();} T GetNth(unsigned index) {return (T)TableIterator::GetNthItem(index);} T Find(const V &value) {return (T)TableIterator::FindPlug(&value);} V GetValue() {return Cast_Object(TableEntryOf*, GetCurrentEntry())->GetValue();} operator T() {return TableIterator::GetCurrent();} }; }