//===========================================================================// // File: schain.cc // // Contents: Implementation details of safe chains // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 09/29/94 ECH Initial coding. // // 11/01/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++ // //---------------------------------------------------------------------------// // Copyright (C) 1994-1995, Virtual World Entertainment, Inc. // // PROPRIETARY AND CONFIDENTIAL // //===========================================================================// #include "StuffHeaders.hpp" // //########################################################################### // SCHAINLINK //########################################################################### // MemoryBlock* SafeChainLink::s_AllocatedMemory = NULL; // //########################################################################### //########################################################################### // void SafeChainLink::InitializeClass(size_t block_count) { Verify(!s_AllocatedMemory); s_AllocatedMemory = new MemoryBlock( sizeof(SafeChainLink), block_count, block_count>>2, "Stuff::SafeChainLink", g_ConnectionEngineHeap ); } // //########################################################################### //########################################################################### // void SafeChainLink::TerminateClass() { delete s_AllocatedMemory; s_AllocatedMemory = NULL; } // //########################################################################### // SafeChainLink //########################################################################### // SafeChainLink::SafeChainLink( SafeChain *chain, Plug *m_plug, SafeChainLink *nextSafeChainLink, SafeChainLink *prevSafeChainLink ): Link(chain, m_plug) { // //------------------------- // Link into existing chain //------------------------- // if ((m_nextSafeChainLink = nextSafeChainLink) != NULL) { Check_Object(m_nextSafeChainLink); m_nextSafeChainLink->m_prevSafeChainLink = this; } if ((m_prevSafeChainLink = prevSafeChainLink) != NULL) { Check_Object(m_prevSafeChainLink); m_prevSafeChainLink->m_nextSafeChainLink = this; } } // //########################################################################### // ~SafeChainLink //########################################################################### // SafeChainLink::~SafeChainLink() { Check_Object(this); SafeChain *chain = Cast_Object(SafeChain*, m_socket); // //--------------------------------------------- // Notify iterators that the link is going away //--------------------------------------------- // chain->SendIteratorMemo(PlugRemoved, this); // //--------------------------- // Remove from existing links //--------------------------- // if (m_prevSafeChainLink != NULL) { Check_Object(m_prevSafeChainLink); m_prevSafeChainLink->m_nextSafeChainLink = m_nextSafeChainLink; } else { Check_Object(chain); chain->m_head = m_nextSafeChainLink; } if (m_nextSafeChainLink != NULL) { Check_Object(m_nextSafeChainLink); m_nextSafeChainLink->m_prevSafeChainLink = m_prevSafeChainLink; } else { Check_Object(chain); chain->m_tail = m_prevSafeChainLink; } m_prevSafeChainLink = m_nextSafeChainLink = NULL; // //------------------------------------------ // Remove this link from any m_plug references //------------------------------------------ // ReleaseFromPlug(); } // //########################################################################### // TestInstance //########################################################################### // void SafeChainLink::TestInstance() { Link::TestInstance(); if (m_prevSafeChainLink != NULL) { Check_Signature(m_prevSafeChainLink); } if (m_nextSafeChainLink != NULL) { Check_Signature(m_nextSafeChainLink); } } // //########################################################################### // SCHAIN //########################################################################### // // //########################################################################### // SafeChain //########################################################################### // SafeChain::SafeChain(void *node) { m_head = NULL; m_tail = NULL; } // //########################################################################### // ~SafeChain //########################################################################### // SafeChain::~SafeChain() { Check_Object(this); SafeChainLink *link = m_head; while (link) { Check_Object(link); SafeChainLink *next = link->m_nextSafeChainLink; Check_Object(link); delete link; link = next; } } // //########################################################################### // TestInstance //########################################################################### // void SafeChain::TestInstance() { SafeSocket::TestInstance(); if (m_head != NULL) { Check_Object(m_head); } } // //########################################################################### // AddImplementation //########################################################################### // void SafeChain::AddPlug(Plug *m_plug) { Check_Object(this); m_tail = new SafeChainLink(this, m_plug, NULL, m_tail); Check_Object(m_tail); if (m_head == NULL) { m_head = m_tail; } } // //############################################################################# // DeletePlugs //############################################################################# // void SafeChain::DeletePlugs() { SafeChainLink *link = m_head; while (link) { Check_Object(link); SafeChainLink *next = link->m_nextSafeChainLink; Check_Object(link); Check_Object(link->GetPlug()); delete link->GetPlug(); link = next; } } // //########################################################################### // GetSize //########################################################################### // unsigned SafeChain::GetSize() { Check_Object(this); unsigned count = 0; for (SafeChainLink *link=m_head; link != NULL; link = link->m_nextSafeChainLink) { Check_Object(link); count++; } return count; } // //########################################################################### // GetNthImplementation //########################################################################### // void* SafeChain::GetNthItem(unsigned index) { Check_Object(this); unsigned count = 0; for (SafeChainLink *link=m_head; link != NULL; link = link->m_nextSafeChainLink) { Check_Object(link); if (count == index) return link->GetPlug(); count++; } return NULL; } // //############################################################################# // IsEmpty //############################################################################# // bool SafeChain::IsEmpty() { Check_Object(this); return (m_head == NULL); } // //########################################################################### // InsertPlug //########################################################################### // SafeChainLink* SafeChain::InsertSafeChainLink( Plug *m_plug, SafeChainLink *link ) { Check_Object(this); Check_Object(link); Check_Object(m_plug); SafeChainLink *new_link = new SafeChainLink( this, m_plug, link, link->m_prevSafeChainLink ); Check_Object(new_link); Check_Object(m_head); if (m_head == link) { m_head = new_link; } return new_link; } // //########################################################################### // SafeChainIterator //########################################################################### // SafeChainIterator::SafeChainIterator( SafeChain *chain, bool move_next_on_remove ): SafeIterator(chain) { Check_Object(chain); m_currentLink = chain->m_head; m_moveNextOnRemove = move_next_on_remove; } SafeChainIterator::SafeChainIterator(const SafeChainIterator &iterator): SafeIterator(Cast_Object(SafeChain*, iterator.m_socket)) { Check_Object(&iterator); m_currentLink = iterator.m_currentLink; m_moveNextOnRemove = iterator.m_moveNextOnRemove; } SafeChainIterator::~SafeChainIterator() { Check_Object(this); } // //########################################################################### // TestInstance //########################################################################### // void SafeChainIterator::TestInstance() const { SafeIterator::TestInstance(); if (m_currentLink != NULL) { Check_Object(m_currentLink); } } // //########################################################################### // First //########################################################################### // Iterator& SafeChainIterator::First() { Check_Object(this); m_currentLink = Cast_Object(SafeChain*, m_socket)->m_head; return *this; } // //########################################################################### // Last //########################################################################### // Iterator& SafeChainIterator::Last() { Check_Object(this); m_currentLink = Cast_Object(SafeChain*, m_socket)->m_tail; return *this; } // //########################################################################### // Next //########################################################################### // Iterator& SafeChainIterator::Next() { Check_Object(this); Check_Object(m_currentLink); m_currentLink = m_currentLink->m_nextSafeChainLink; return *this; } // //########################################################################### // Previous //########################################################################### // Iterator& SafeChainIterator::Previous() { Check_Object(this); Check_Object(m_currentLink); m_currentLink = m_currentLink->m_prevSafeChainLink; return *this; } // //########################################################################### // ReadAndNextItem //########################################################################### // void* SafeChainIterator::ReadAndNextItem() { Check_Object(this); if (m_currentLink != NULL) { Plug *m_plug; Check_Object(m_currentLink); m_plug = m_currentLink->GetPlug(); m_currentLink = m_currentLink->m_nextSafeChainLink; return m_plug; } return NULL; } // //########################################################################### // ReadAndPreviousItem //########################################################################### // void* SafeChainIterator::ReadAndPreviousItem() { Check_Object(this); if (m_currentLink != NULL) { Plug *m_plug; Check_Object(m_currentLink); m_plug = m_currentLink->m_plug; m_currentLink = m_currentLink->m_prevSafeChainLink; return m_plug; } return NULL; } // //########################################################################### // GetCurrentItem //########################################################################### // void* SafeChainIterator::GetCurrentItem() { Check_Object(this); if (m_currentLink != NULL) { Check_Object(m_currentLink); return m_currentLink->GetPlug(); } return NULL; } // //########################################################################### // GetNthImplementation //########################################################################### // void* SafeChainIterator::GetNthItem(unsigned index) { Check_Object(this); unsigned count = 0; for ( SafeChainLink *link=Cast_Object(SafeChain*, m_socket)->m_head; link != NULL; link = link->m_nextSafeChainLink ) { Check_Object(link); if (count == index) { m_currentLink = link; return link->GetPlug(); } count++; } return NULL; } // //########################################################################### // Remove //########################################################################### // void SafeChainIterator::Remove() { Check_Object(this); Check_Object(m_currentLink); Check_Object(m_currentLink); delete m_currentLink; } // //############################################################################# // InsertImplementation //############################################################################# // void SafeChainIterator::InsertPlug(Plug *m_plug) { Check_Object(this); m_currentLink = Cast_Object(SafeChain*, m_socket)->InsertSafeChainLink(m_plug, m_currentLink); Check_Object(m_currentLink); } // //########################################################################### // ReceiveMemo //########################################################################### // void SafeChainIterator::ReceiveMemo( IteratorMemo memo, void *content ) { Check_Object(this); if (memo == PlugRemoved) { if (content == m_currentLink) { if (m_moveNextOnRemove) Next(); else Previous(); } } }