123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471 |
- //-----------------------------------------------------------------------------
- // Verve
- // Copyright (C) 2014 - Violent Tulip
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "Verve/Core/VTreeNode.h"
- #include "console/simObject.h"
- #include "platform/platform.h"
- //-----------------------------------------------------------------------------
- VTreeNode::VTreeNode( void )
- {
- mParentNode = NULL;
- mChildNode = NULL;
- mSiblingPrevNode = NULL;
- mSiblingNextNode = NULL;
- }
- VTreeNode::~VTreeNode( void )
- {
- // Delete Children.
- clear();
- // Detach.
- remove();
- }
- //-----------------------------------------------------------------------------
- //
- // Reference Methods.
- //
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::clear();
- //
- // Delete all child nodes.
- //
- //-----------------------------------------------------------------------------
- void VTreeNode::clear( void )
- {
- if ( !mChildNode )
- {
- return;
- }
- while ( mChildNode )
- {
- // Fetch Child Node.
- ITreeNode *node = mChildNode;
- // Clear It.
- node->clear();
- // Detach It.
- node->remove();
- // Delete It.
- SimObject *object = dynamic_cast<SimObject*>( node );
- if ( object )
- {
- object->deleteObject();
- }
- else
- {
- delete node;
- }
- }
- }
- //-----------------------------------------------------------------------------
- //
- // ITreeNode Methods.
- //
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::getRoot();
- //
- // Returns the root object.
- //
- //-----------------------------------------------------------------------------
- ITreeNode *VTreeNode::getRoot( void )
- {
- ITreeNode *parent = this;
- while ( parent->mParentNode )
- {
- parent = parent->mParentNode;
- }
- return parent;
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::getParent();
- //
- // Returns the parent object.
- //
- //-----------------------------------------------------------------------------
- ITreeNode *VTreeNode::getParent( void )
- {
- return mParentNode;
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::getChild();
- //
- // Returns the first child object.
- //
- //-----------------------------------------------------------------------------
- ITreeNode *VTreeNode::getChild( void )
- {
- return mChildNode;
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::getChild();
- //
- // Returns the first child object.
- //
- //-----------------------------------------------------------------------------
- ITreeNode *VTreeNode::getLastChild( void )
- {
- // Any Nodes?
- if ( !mChildNode )
- {
- // Null.
- return NULL;
- }
- // Front Node.
- ITreeNode *lastNode = mChildNode;
- // Fetch Last Node.
- while ( lastNode->mSiblingNextNode )
- {
- lastNode = lastNode->mSiblingNextNode;
- }
- // Return.
- return lastNode;
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::getPrevSibling();
- //
- // Returns the previous object in the linked list.
- //
- //-----------------------------------------------------------------------------
- ITreeNode *VTreeNode::getPrevSibling( void )
- {
- return mSiblingPrevNode;
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::getNextSibling();
- //
- // Returns the next object in the linked list.
- //
- //-----------------------------------------------------------------------------
- ITreeNode *VTreeNode::getNextSibling( void )
- {
- return mSiblingNextNode;
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::size();
- //
- // Returns the number of child objects. Only includes top level.
- //
- //-----------------------------------------------------------------------------
- int VTreeNode::size( void )
- {
- int size = 0;
- ITreeNode *node = mChildNode;
- while ( node )
- {
- size++;
- node = node->mSiblingNextNode;
- }
- return size;
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::at( pIndex );
- //
- // Returns the object at the given index.
- //
- //-----------------------------------------------------------------------------
- ITreeNode *VTreeNode::at( const int pIndex )
- {
- int index = 0;
- ITreeNode *node = mChildNode;
- while ( node )
- {
- if ( index++ == pIndex )
- {
- return node;
- }
- node = node->mSiblingNextNode;
- }
- return NULL;
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::getIndex();
- //
- // Returns the index of the object in relation to the sibling nodes.
- //
- //-----------------------------------------------------------------------------
- int VTreeNode::getIndex( void )
- {
- if ( !inTree() )
- {
- // No Index.
- return 0;
- }
- ITreeNode *walk = NULL;
- if ( mParentNode )
- {
- walk = mParentNode->mChildNode;
- }
- else
- {
- walk = this;
- while ( walk->mSiblingPrevNode )
- {
- // Walk Up.
- walk = walk->mSiblingPrevNode;
- }
- }
- for ( int i = 0; walk; walk = walk->mSiblingNextNode, i++ )
- {
- if ( walk == this )
- {
- return i;
- }
- }
- AssertFatal( false, "VTreeNode::getIndex() - Node List Broken?" );
- return 0;
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::addTo( pNode );
- //
- // Attach this node to the back of the target node.
- //
- //-----------------------------------------------------------------------------
- void VTreeNode::addTo( ITreeNode *pNode )
- {
- if ( inTree() )
- {
- // Already In Tree.
- return;
- }
- // Set Parent.
- mParentNode = pNode;
- if ( !pNode->mChildNode )
- {
- // Store Child Node.
- pNode->mChildNode = this;
- }
- else
- {
- // Front Node.
- ITreeNode *headNode = pNode->mChildNode;
- // Fetch Head Node.
- while ( headNode->mSiblingNextNode )
- {
- headNode = headNode->mSiblingNextNode;
- }
- // Reference Next Node.
- headNode->mSiblingNextNode = this;
- // Reference Previous Node.
- mSiblingPrevNode = headNode;
- }
- // Callback.
- onAttach();
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::addToFront( pNode );
- //
- // Attach this node to the front of the target node.
- //
- //-----------------------------------------------------------------------------
- void VTreeNode::addToFront( ITreeNode *pNode )
- {
- if ( inTree() )
- {
- // Already In Tree.
- return;
- }
- // Set Parent.
- mParentNode = pNode;
- if ( !pNode->mChildNode )
- {
- // Store Child Node.
- pNode->mChildNode = this;
- }
- else
- {
- // First Node.
- ITreeNode *childNode = pNode->mChildNode;
- // Reference Previous Node.
- childNode->mSiblingPrevNode = this;
- // Reference Next Node.
- mSiblingNextNode = childNode;
- // Store Child Node.
- pNode->mChildNode = this;
- }
- // Callback.
- onAttach();
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::remove();
- //
- // Detach this node from the current parent node.
- //
- //-----------------------------------------------------------------------------
- void VTreeNode::remove( void )
- {
- if ( !inTree() )
- {
- return;
- }
- // Callback.
- onDetach();
- if ( mParentNode && mParentNode->mChildNode == this )
- {
- // Update Parent Reference.
- mParentNode->mChildNode = mSiblingNextNode;
- }
- if ( mSiblingNextNode )
- {
- // Update Previous Node.
- mSiblingNextNode->mSiblingPrevNode = mSiblingPrevNode;
- }
- if ( mSiblingPrevNode )
- {
- // Update Next Node.
- mSiblingPrevNode->mSiblingNextNode = mSiblingNextNode;
- }
- // Remove References.
- mParentNode = mSiblingPrevNode = mSiblingNextNode = NULL;
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::moveTo( pNode );
- //
- // Detach this node and attach it to the target node.
- //
- //-----------------------------------------------------------------------------
- void VTreeNode::moveTo( ITreeNode *pNode )
- {
- if ( inTree() )
- {
- // Remove from Tree.
- remove();
- }
- // Add to tree.
- addTo( pNode );
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::onAttach();
- //
- // This method will be called when this node, or a parent node, is attached to
- // a node.
- //
- //-----------------------------------------------------------------------------
- void VTreeNode::onAttach( void )
- {
- // Notify Children.
- for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode )
- {
- node->onAttach();
- }
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::onDetach();
- //
- // This method will be called when this node, or a parent node, is detached.
- //
- //-----------------------------------------------------------------------------
- void VTreeNode::onDetach( void )
- {
- // Notify Children.
- for ( ITreeNode *node = mChildNode; node != NULL; node = node->mSiblingNextNode )
- {
- node->onDetach();
- }
- }
- //-----------------------------------------------------------------------------
- //
- // VTreeNode::inTree();
- //
- // Returns true if the node is the a member of a node tree.
- //
- //-----------------------------------------------------------------------------
- bool VTreeNode::inTree( void )
- {
- return !( mParentNode == NULL &&
- mSiblingPrevNode == NULL &&
- mSiblingNextNode == NULL );
- }
|