#include "munga.h" #pragma hdrstop #include "chain.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainLink ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MemoryBlock *ChainLink::GetAllocatedMemory() { static MemoryBlock allocatedMemory(sizeof(ChainLink), CHAINLINK_MEMORYBLOCK_ALLOCATION, CHAINLINK_MEMORYBLOCK_ALLOCATION, "ChainLink"); return &allocatedMemory; } // //############################################################################# // ChainLink //############################################################################# // ChainLink::ChainLink( Chain *chain, Plug *plug, ChainLink *next_link, ChainLink *prev_link ): Link(chain, plug) { // //------------------------- // Link into existing chain //------------------------- // if ((nextChainLink = next_link) != NULL) { Check(nextChainLink); nextChainLink->prevChainLink = this; } if ((prevChainLink = prev_link) != NULL) { Check(prevChainLink); prevChainLink->nextChainLink = this; } } // //############################################################################# // ~ChainLink //############################################################################# // ChainLink::~ChainLink() { Chain *chain = Cast_Object(Chain*, socket); // //-------------------------------------- // Remove this link from the linked list //-------------------------------------- // if (prevChainLink != NULL) { Check(prevChainLink); prevChainLink->nextChainLink = nextChainLink; } else { Check(chain); chain->head = nextChainLink; } if (nextChainLink != NULL) { Check(nextChainLink); nextChainLink->prevChainLink = prevChainLink; } else { Check(chain); chain->tail = prevChainLink; } prevChainLink = nextChainLink = 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 ChainLink::TestInstance() const { Link::TestInstance(); if (prevChainLink != NULL) { Check_Signature(prevChainLink); } if (nextChainLink != NULL) { Check_Signature(nextChainLink); } return( True ); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Chain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // //############################################################################# // Chain //############################################################################# // Chain::Chain(Node *node): Socket(node) { head = NULL; tail = NULL; } // //############################################################################# // ~Chain //############################################################################# // Chain::~Chain() { SetReleaseNode(NULL); while (head != NULL) { Unregister_Object(head); delete head; } } // //############################################################################# // TestInstance //############################################################################# // Logical Chain::TestInstance() const { Socket::TestInstance(); if (head != NULL) { Check(head); } if (tail != NULL) { Check(tail); } return True; } // //############################################################################# // AddImplementation //############################################################################# // void Chain::AddImplementation(Plug *plug) { Check(this); tail = new ChainLink(this, plug, NULL, tail); Register_Object(tail); if (head == NULL) { head = tail; } } // //############################################################################# // InsertChainLink //############################################################################# // ChainLink* Chain::InsertChainLink( Plug *plug, ChainLink *current_link ) { Check(this); Check(plug); Check(current_link); ChainLink *new_link = new ChainLink( this, plug, current_link, current_link->prevChainLink ); Register_Object(new_link); Check(head); if (head == current_link) { head = new_link; } return new_link; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ChainIterator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // //############################################################################# // ChainIterator //############################################################################# // ChainIterator::ChainIterator(Chain *chain): SocketIterator(chain) { Check(chain); currentLink = chain->head; } ChainIterator::ChainIterator(const ChainIterator &iterator): SocketIterator(Cast_Object(Chain*, iterator.socket)) { Check(&iterator); currentLink = iterator.currentLink; } ChainIterator::~ChainIterator() { } // //########################################################################### // TestInstance //########################################################################### // Logical ChainIterator::TestInstance() const { SocketIterator::TestInstance(); if (currentLink != NULL) { Check( currentLink ); } return(True); } // //########################################################################### // First //########################################################################### // void ChainIterator::First() { currentLink = Cast_Object(Chain*, socket)->head; } // //########################################################################### // Last //########################################################################### // void ChainIterator::Last() { currentLink = Cast_Object(Chain*, socket)->tail; } // //########################################################################### // Next //########################################################################### // void ChainIterator::Next() { Check(currentLink); currentLink = currentLink->nextChainLink; } // //########################################################################### // Previous //########################################################################### // void ChainIterator::Previous() { Check( currentLink ); currentLink = currentLink->prevChainLink; } // //########################################################################### // ReadAndNextImplementation //########################################################################### // void* ChainIterator::ReadAndNextImplementation() { if (currentLink != NULL) { Plug *plug; Check(currentLink); plug = currentLink->plug; currentLink = currentLink->nextChainLink; return plug; } return NULL; } // //########################################################################### // ReadAndPreviousImplementation //########################################################################### // void* ChainIterator::ReadAndPreviousImplementation() { if (currentLink != NULL) { Plug *plug; Check(currentLink); plug = currentLink->plug; currentLink = currentLink->prevChainLink; return plug; } return NULL; } // //########################################################################### // GetCurrentImplementation //########################################################################### // void* ChainIterator::GetCurrentImplementation() { if (currentLink != NULL) { Check(currentLink); return currentLink->plug; } return NULL; } // //########################################################################### // GetSize //########################################################################### // CollectionSize ChainIterator::GetSize() { ChainLink *link; CollectionSize count; count = 0; for ( link = Cast_Object(Chain*, socket)->head; link != NULL; link = link->nextChainLink ) { Check(link); count++; } return count; } // //########################################################################### // GetNthImplementation //########################################################################### // void* ChainIterator::GetNthImplementation(CollectionSize index) { ChainLink *link; CollectionSize count; count = 0; for ( link = Cast_Object(Chain*, socket)->head; link != NULL; link = link->nextChainLink ) { Check(link); if (count == index) { currentLink = link; return currentLink->plug; } count++; } return NULL; } // //########################################################################### // Remove //########################################################################### // void ChainIterator::Remove() { ChainLink *oldLink = currentLink; Check(currentLink); currentLink = currentLink->nextChainLink; Unregister_Object(oldLink); delete oldLink ; } // //########################################################################### // InsertImplementation //########################################################################### // void ChainIterator::InsertImplementation(Plug *plug) { currentLink = Cast_Object(Chain*, socket)->InsertChainLink(plug, currentLink); Check(currentLink); } #ifdef TEST_CLASS # include "chain.tcp" #endif