#include "munga.h" #pragma hdrstop #include "schain.h" #include "node.h" // //########################################################################### // SCHAINLINK //########################################################################### // MemoryBlock *SChainLink::GetAllocatedMemory() { static MemoryBlock allocatedMemory(sizeof(SChainLink), SCHAINLINK_MEMORYBLOCK_ALLOCATION, SCHAINLINK_MEMORYBLOCK_ALLOCATION, "SChainLink"); return &allocatedMemory; } // //########################################################################### // SChainLink //########################################################################### // SChainLink::SChainLink( SChain *chain, Plug *plug, SChainLink *nextSChainLink, SChainLink *prevSChainLink ): Link(chain, plug) { // //------------------------- // Link into existing chain //------------------------- // if ((this->nextSChainLink = nextSChainLink) != NULL) { Check(nextSChainLink); nextSChainLink->prevSChainLink = this; } if ((this->prevSChainLink = prevSChainLink) != NULL) { Check(prevSChainLink); prevSChainLink->nextSChainLink = this; } } // //########################################################################### // ~SChainLink //########################################################################### // SChainLink::~SChainLink() { SChain *chain = Cast_Object(SChain*, socket); // //--------------------------------------------- // Notify iterators that the link is going away //--------------------------------------------- // chain->SendIteratorMemo(PlugRemoved, this); // //--------------------------- // Remove from existing links //--------------------------- // if (prevSChainLink != NULL) { Check(prevSChainLink); prevSChainLink->nextSChainLink = nextSChainLink; } else { Check(chain); chain->head = nextSChainLink; } if (nextSChainLink != NULL) { Check(nextSChainLink); nextSChainLink->prevSChainLink = prevSChainLink; } else { Check(chain); chain->tail = prevSChainLink; } prevSChainLink = nextSChainLink = 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 SChainLink::TestInstance() const { Link::TestInstance(); if (prevSChainLink != NULL) { Check_Signature(prevSChainLink); } if (nextSChainLink != NULL) { Check_Signature(nextSChainLink); } return True; } // //########################################################################### // SCHAIN //########################################################################### // // //########################################################################### // SChain //########################################################################### // SChain::SChain( Node *node ) : SafeSocket( node ) { head = NULL; tail = NULL; } // //########################################################################### // ~SChain //########################################################################### // SChain::~SChain() { SetReleaseNode(NULL); while (head != NULL) { Unregister_Object(head); delete head; } } // //########################################################################### // TestInstance //########################################################################### // Logical SChain::TestInstance() const { SafeSocket::TestInstance(); if (head != NULL) { Check(head); } return True; } // //########################################################################### // AddImplementation //########################################################################### // void SChain::AddImplementation( Plug *plug ) { tail = new SChainLink(this, plug, NULL, tail); Register_Object(tail); if (head == NULL) { head = tail; } } // //########################################################################### // InsertPlug //########################################################################### // SChainLink* SChain::InsertSChainLink( Plug *plug, SChainLink *link ) { Check(this); Check(link); Check(plug); SChainLink *new_link = new SChainLink( this, plug, link, link->prevSChainLink ); Register_Object(new_link); Check(head); if (head == link) { head = new_link; } return new_link; } // //########################################################################### // SChainIterator //########################################################################### // SChainIterator::SChainIterator(SChain *chain): SafeIterator(chain) { Check(chain); currentLink = chain->head; } SChainIterator::SChainIterator(const SChainIterator &iterator): SafeIterator(Cast_Object(SChain*, iterator.socket)) { Check(&iterator); currentLink = iterator.currentLink; } SChainIterator::~SChainIterator() { } // //########################################################################### // TestInstance //########################################################################### // Logical SChainIterator::TestInstance() const { SafeIterator::TestInstance(); if (currentLink != NULL) { Check(currentLink); } return True; } // //########################################################################### // First //########################################################################### // void SChainIterator::First() { currentLink = Cast_Object(SChain*, socket)->head; } // //########################################################################### // Last //########################################################################### // void SChainIterator::Last() { currentLink = Cast_Object(SChain*, socket)->tail; } // //########################################################################### // Next //########################################################################### // void SChainIterator::Next() { Check(currentLink); currentLink = currentLink->nextSChainLink; } // //########################################################################### // Previous //########################################################################### // void SChainIterator::Previous() { Check(currentLink); currentLink = currentLink->prevSChainLink; } // //########################################################################### // ReadAndNextImplementation //########################################################################### // void* SChainIterator::ReadAndNextImplementation() { if (currentLink != NULL) { Plug *plug; Check(currentLink); plug = currentLink->GetPlug(); currentLink = currentLink->nextSChainLink; return plug; } return NULL; } // //########################################################################### // ReadAndPreviousImplementation //########################################################################### // void* SChainIterator::ReadAndPreviousImplementation() { if (currentLink != NULL) { Plug *plug; Check(currentLink); plug = currentLink->plug; currentLink = currentLink->prevSChainLink; return plug; } return NULL; } // //########################################################################### // GetCurrentImplementation //########################################################################### // void* SChainIterator::GetCurrentImplementation() { if (currentLink != NULL) { Check(currentLink); return currentLink->GetPlug(); } return NULL; } // //########################################################################### // GetSize //########################################################################### // CollectionSize SChainIterator::GetSize() { SChainLink *link; CollectionSize count; count = 0; for ( link = Cast_Object(SChain*, socket)->head; link != NULL; link = link->nextSChainLink ) { Check(link); count++; } return count; } // //########################################################################### // GetNthImplementation //########################################################################### // void* SChainIterator::GetNthImplementation( CollectionSize index ) { SChainLink *link; CollectionSize count; count = 0; for ( link = Cast_Object(SChain*, socket)->head; link != NULL; link = link->nextSChainLink ) { Check(link); if (count == index) { currentLink = link; return currentLink->GetPlug(); } count++; } return NULL; } // //########################################################################### // Remove //########################################################################### // void SChainIterator::Remove() { Check(currentLink); Unregister_Object(currentLink); delete currentLink; } // //############################################################################# // InsertImplementation //############################################################################# // void SChainIterator::InsertImplementation(Plug *plug) { currentLink = Cast_Object(SChain*, socket)->InsertSChainLink(plug, currentLink); Check(currentLink); } // //########################################################################### // ReceiveMemo //########################################################################### // void SChainIterator::ReceiveMemo( IteratorMemo memo, void *content ) { if (memo == PlugRemoved) { if (content == currentLink) { Next(); } } } #ifdef TEST_CLASS # include "schain.tcp" #endif