//===========================================================================// // File: chain.hh // // Project: MUNGA Brick: Connection Engine // // Contents: Interface specification 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 // // 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 "MemoryBlock.hpp" namespace Stuff { class Chain; class ChainIterator; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainLink ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class ChainLink #if defined(_ARMOR) : public Stuff::Signature #endif { public: friend class Chain; friend class ChainIterator; friend class Plug; static void InitializeClass(size_t block_count); static void TerminateClass(); public: void TestInstance() {} // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Chain* GetChain() {return m_chain;} Plug* GetPlug() {return m_plug;} protected: ~ChainLink(); explicit ChainLink( Chain *chain, Plug *plug, ChainLink *nextChainLink, ChainLink *prevChainLink ); // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // void ReleaseFromPlug(); void AddToPlug(Plug *plug); Plug *m_plug; ChainLink *m_nextChainLink, *m_prevChainLink; Chain *m_chain; ChainLink *m_nextPlugLink; static MemoryBlock *s_AllocatedMemory; void* operator new(size_t) {return s_AllocatedMemory->New();} void operator delete(void *where) {s_AllocatedMemory->Delete(where);} }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Chain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class _declspec(novtable) Chain #if defined(_ARMOR) : public Stuff::Signature #endif { friend class ChainLink; friend class ChainIterator; public: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Public interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // // //-------------------------------------------------------------------- // Constructor, Destructor and testing //-------------------------------------------------------------------- // explicit Chain(void *data=NULL) {m_head = m_tail = NULL;} ~Chain(); void TestInstance() {} static bool TestClass(); static bool ProfileClass(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Socket methods // public: // //----------------------------------------------------------------------- // DeletePlugs - For each plug in the socket, the routine unregisters it // and then deletes it. //----------------------------------------------------------------------- // void AddPlug(Plug *plug); // //----------------------------------------------------------------------- // RemovePlug - Remove a plug from this socket, untyped access. //----------------------------------------------------------------------- // void DeletePlugs(); void RemovePlug(Plug *plug) { Check_Object(this); Check_Object(plug); plug->RemoveChain(this); } // //----------------------------------------------------------------------- // IsPlugMember - Determine if the plug is a member of this socket. //----------------------------------------------------------------------- // void* GetNthItem(unsigned index); bool IsPlugMember(Plug *plug) { Check_Object(this); Check_Object(plug); return plug->IsChainMember(this); } // //----------------------------------------------------------------------- // IsEmpty - Returns true if the socket contains no plugs. //----------------------------------------------------------------------- // unsigned GetSize(); bool IsEmpty() {Check_Object(this); return (m_head == NULL);} protected: // //-------------------------------------------------------------------- // Private methods //-------------------------------------------------------------------- // ChainLink* InsertChainLink( Plug *plug, ChainLink *current_link ); // //-------------------------------------------------------------------- // Private data //-------------------------------------------------------------------- // ChainLink *m_head, *m_tail; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainOf ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template class ChainOf: public Chain { public: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Public interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // explicit ChainOf(void *node=NULL) {} // //-------------------------------------------------------------------- // Socket methods (see Socket for full listing) //-------------------------------------------------------------------- // void Add(T plug) {Chain::AddPlug(Cast_Pointer(Plug*, plug));} void Remove(T plug) {Chain::RemovePlug(Cast_Pointer(Plug*, plug));} T GetNth(unsigned index) {return (T)Chain::GetNthItem(index);} }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainIterator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class _declspec(novtable) ChainIterator #if defined(_ARMOR) : public Stuff::Signature #endif { public: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Public interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // // //-------------------------------------------------------------------- // Constructors, Destructor and testing //-------------------------------------------------------------------- // explicit ChainIterator(Chain *chain): m_chain(chain) {Check_Object(chain); m_currentLink = chain->m_head;} ChainIterator(const ChainIterator &iterator): m_chain(iterator.m_chain) {Check_Object(&iterator); m_currentLink = iterator.m_currentLink;} virtual ChainIterator* MakeClone()=0; void TestInstance() const {} // //-------------------------------------------------------------------- // Iterator methods (see Iterator for full listing) //-------------------------------------------------------------------- // ChainIterator& First() { Check_Object(this); m_currentLink = m_chain->m_head; return *this; } ChainIterator& Last() { Check_Object(this); m_currentLink = m_chain->m_tail; return *this; } ChainIterator& Next() { Check_Object(this); Check_Object(m_currentLink); m_currentLink = m_currentLink->m_nextChainLink; return *this; } ChainIterator& Previous() { Check_Object(this); Check_Object(m_currentLink); m_currentLink = m_currentLink->m_prevChainLink; return *this; } void* ReadAndNextItem() { if (m_currentLink != NULL) { Check_Object(m_currentLink); Plug *plug = m_currentLink->m_plug; m_currentLink = m_currentLink->m_nextChainLink; return plug; } return NULL; } void* ReadAndPreviousItem() { if (m_currentLink != NULL) { Check_Object(m_currentLink); Plug *plug = m_currentLink->m_plug; m_currentLink = m_currentLink->m_prevChainLink; return plug; } return NULL; } void* GetCurrentItem() { Check_Object(this); if (m_currentLink != NULL) { Check_Object(m_currentLink); return m_currentLink->m_plug; } return NULL; } unsigned GetSize() {Check_Object(this); return m_chain->GetSize();} void* GetNthItem(unsigned index); ChainIterator& operator++() {return Next();} ChainIterator& operator--() {return Previous();} Plug* ReadAndNextPlug() {return static_cast(ReadAndNextItem());} Plug* GetCurrentPlug() {return static_cast(GetCurrentItem());} void DeletePlugs() {Check_Object(m_chain); m_chain->DeletePlugs();} void Remove(); void InsertPlug(Plug*); protected: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Protected data //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Chain *m_chain; ChainLink *m_currentLink; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainIteratorOf ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template class ChainIteratorOf: public ChainIterator { public: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Public interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // // //-------------------------------------------------------------------- // Constructors and Destructor //-------------------------------------------------------------------- // explicit ChainIteratorOf(ChainOf *chain): ChainIterator(chain) {} explicit ChainIteratorOf(const ChainIteratorOf &iterator): ChainIterator(iterator) {} ChainIterator* MakeClone() {return new(g_Heap) ChainIteratorOf(*this);} // //-------------------------------------------------------------------- // Iterator methods (see Iterator for full listing) //-------------------------------------------------------------------- // T ReadAndNext() {return (T)ChainIterator::ReadAndNextItem();} T ReadAndPrevious() {return (T)ChainIterator::ReadAndPreviousItem();} T GetCurrent() {return (T)ChainIterator::GetCurrentItem();} T GetNth(unsigned index) {return (T)ChainIterator::GetNthItem(index);} void Insert(T plug) {ChainIterator::InsertPlug(Cast_Object(Plug*,plug));} operator T() {return ChainIterator::GetCurrent();} }; }