//===========================================================================// // File: tree.hh // // Project: MUNGA Brick: Connection Library // // Contents: Interface specification of Tree class // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 10/01/94 ECH Initial coding. // // 11/02/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++ // // 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 "SortedSocket.hpp" #include "MemoryBlock.hpp" namespace Stuff { class Tree; class TreeIterator; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TreeNode ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class _declspec(novtable) TreeNode: public Link { friend class Tree; friend class TreeIterator; public: void TestInstance(); protected: ~TreeNode(); TreeNode( Tree *tree, Plug *plug ); void SetupTreeLinks( TreeNode *less, TreeNode *greater, TreeNode *parent ); TreeNode *less; TreeNode *greater; TreeNode *parent; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TreeNodeOf ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template class TreeNodeOf: public TreeNode { public: TreeNodeOf( Tree *tree, Plug *plug, const V &value ): TreeNode(tree, plug) {m_value = value;} void* operator new(size_t); void operator delete(void *where); V GetValue() {return m_value;} V* GetValuePointer() {return &m_value;} private: static MemoryBlock *s_allocatedMemory; static int s_allocationCount; V m_value; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~ TreeNodeOf templates ~~~~~~~~~~~~~~~~~~~~~~~~~ template MemoryBlock* TreeNodeOf::s_allocatedMemory = NULL; template int TreeNodeOf::s_allocationCount = 0; template void* TreeNodeOf::operator new(size_t) { Verify(s_allocationCount >= 0); if (s_allocationCount++ == 0) { s_allocatedMemory = new(g_Heap) MemoryBlock( sizeof(TreeNodeOf), 100, 100, "Stuff::TreeNodeOf", Stuff::g_ConnectionEngineHeap ); Register_Object(s_allocatedMemory); } Verify(s_allocationCount < INT_MAX); Check_Object(s_allocatedMemory); return s_allocatedMemory->New(); } template void TreeNodeOf::operator delete(void *where) { Check_Object(s_allocatedMemory); s_allocatedMemory->Delete(where); if (--s_allocationCount == 0) { Unregister_Object(s_allocatedMemory); delete s_allocatedMemory; s_allocatedMemory = NULL; } Verify(s_allocationCount >= 0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tree ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class _declspec(novtable) Tree: public SortedSocket { friend class TreeNode; friend class TreeIterator; public: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Public interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // // //-------------------------------------------------------------------- // Constructor, Destructor and testing //-------------------------------------------------------------------- // Tree( void *, bool has_unique_entries ): SortedSocket(NULL, has_unique_entries) {m_root = NULL;} ~Tree(); void TestInstance(); static void TestClass(); static void ProfileClass(); // //----------------------------------------------------------------------- // RemovePlug - Remove a plug from this socket, untyped access. //----------------------------------------------------------------------- // void DeletePlugs(); // //----------------------------------------------------------------------- // IsPlugMember - Determine if the plug is a member of this socket. //----------------------------------------------------------------------- // void* GetNthItem(unsigned index); // //----------------------------------------------------------------------- // IsEmpty - Returns true if the socket contains no plugs. //----------------------------------------------------------------------- // unsigned GetSize(); bool IsEmpty(); void AddValuePlug( Plug *plug, const void *value ); Plug* FindPlug(const void *value); protected: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Private interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // virtual TreeNode* MakeTreeNode( Plug *plug, const void *value )=0; virtual int CompareTreeNodes( TreeNode *link1, TreeNode *link2 )=0; virtual int CompareValueToTreeNode( const void *value, TreeNode *link )=0; void AddTreeNode(TreeNode *node); void SeverFromTreeNode(TreeNode *node); TreeNode* SearchForValue(const void *value); // //-------------------------------------------------------------------- // Private data //-------------------------------------------------------------------- // TreeNode *m_root; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TreeOf ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template class TreeOf: public Tree { public: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Public interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // TreeOf( void *, bool has_unique_entries ): Tree(NULL, has_unique_entries) {} // //-------------------------------------------------------------------- // Socket methods (see Socket for full listing) //-------------------------------------------------------------------- // void AddValue( T plug, const V &value ) {Tree::AddValuePlug(Cast_Pointer(Plug*,plug), &value);} void Remove(T plug) {Tree::RemovePlug(Cast_Pointer(Plug*,plug));} T Find(const V &value) {return (T)Tree::FindPlug(&value);} T GetNth(unsigned index) {return (T)Tree::GetNthItem(index);} private: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Private interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // TreeNode *MakeTreeNode( Plug *plug, const void *value ) { return new TreeNodeOf( this, plug, *Cast_Pointer(const V*, value) ); } int CompareTreeNodes( TreeNode *link1, TreeNode *link2 ); int CompareValueToTreeNode( const void *value, TreeNode *link ); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~ TreeOf templates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template int TreeOf::CompareTreeNodes( TreeNode *node1, TreeNode *node2 ) { V *ptr1 = Cast_Object(TreeNodeOf*, node1)->GetValuePointer(); V *ptr2 = Cast_Object(TreeNodeOf*, node2)->GetValuePointer(); Check_Pointer(ptr1); Check_Pointer(ptr2); if (*ptr1 == *ptr2) return 0; return ((*ptr1 > *ptr2) ? 1 : -1); } template int TreeOf::CompareValueToTreeNode( const void *value, TreeNode *node ) { Check_Pointer(value); V *ptr = Cast_Object(TreeNodeOf*, node)->GetValuePointer(); Check_Pointer(ptr); if (*Cast_Pointer(const V*, value) == *ptr) return 0; return (*Cast_Pointer(const V*, value) > *ptr) ? 1 : -1; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TreeIterator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class TreeIterator: public SortedIterator { public: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Public interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // // //-------------------------------------------------------------------- // Constructors, Destructor and testing //-------------------------------------------------------------------- // explicit TreeIterator(Tree *tree); Iterator* MakeClone(); ~TreeIterator(); void TestInstance(); // //-------------------------------------------------------------------- // Iterator methods (see Iterator for full listing) //-------------------------------------------------------------------- // Iterator& First(); Iterator& Last(); Iterator& Next(); Iterator& Previous(); void* ReadAndNextItem(); void* ReadAndPreviousItem(); void* GetCurrentItem(); void Remove(); void* GetNthItem(unsigned index); Plug* FindPlug(const void *value); void* GetPlugValue(); protected: // //-------------------------------------------------------------------- // Protected data //-------------------------------------------------------------------- // TreeNode *m_currentNode; // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Private interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // void ReceiveMemo( IteratorMemo memo, void *content ); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TreeIteratorOf ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template class TreeIteratorOf: public TreeIterator { public: // //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Public interface //-------------------------------------------------------------------- //-------------------------------------------------------------------- // // //-------------------------------------------------------------------- // Constructors and Destructor //-------------------------------------------------------------------- // explicit TreeIteratorOf(TreeOf *tree): TreeIterator(tree) {} Iterator* MakeClone() {return new TreeIteratorOf(*this);} // //-------------------------------------------------------------------- // Iterator methods (see Iterator for full listing) //-------------------------------------------------------------------- // T ReadAndNext() {return (T)TreeIterator::ReadAndNextItem();} T GetCurrent() {return (T)TreeIterator::GetCurrentItem();} T GetNth(unsigned index) {return (T)TreeIterator::GetNthItem(index);} T Find(const V &value) {return (T)TreeIterator::FindPlug(&value);} V GetValue() {return Cast_Object(TreeNodeOf*, currentNode)->GetValue();} operator T() {return TreeIterator::GetCurrent();} }; }