//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //============================================================================= #ifndef DMELEMENTDICTIONARY_H #define DMELEMENTDICTIONARY_H #ifdef _WIN32 #pragma once #endif #include "tier1/utlvector.h" #include "datamodel/idatamodel.h" #include "datamodel/dmattribute.h" #include "tier1/utlrbtree.h" #include "tier1/utlhash.h" //----------------------------------------------------------------------------- // Forward declarations //----------------------------------------------------------------------------- class CDmElement; class CDmAttribute; //----------------------------------------------------------------------------- // Element dictionary used in unserialization //----------------------------------------------------------------------------- typedef int DmElementDictHandle_t; enum { ELEMENT_DICT_HANDLE_INVALID = (DmElementDictHandle_t)~0 }; class CDmElementDictionary { public: CDmElementDictionary(); DmElementDictHandle_t InsertElement( CDmElement *pElement ); CDmElement *GetElement( DmElementDictHandle_t handle ); void AddAttribute( CDmAttribute *pAttribute, const DmObjectId_t &pElementId ); void AddArrayAttribute( CDmAttribute *pAttribute, DmElementDictHandle_t hChild ); void AddArrayAttribute( CDmAttribute *pAttribute, const DmObjectId_t &pElementId ); DmElementHandle_t SetElementId( DmElementDictHandle_t hDictHandle, const DmObjectId_t &newId, DmConflictResolution_t idConflictResolution ); // Finds an element into the table DmElementDictHandle_t FindElement( CDmElement *pElement ); // Hook up all element references (which were unserialized as object ids) void HookUpElementReferences(); // Clears the dictionary void Clear(); // iteration through elements DmElementDictHandle_t FirstElement() { return 0; } DmElementDictHandle_t NextElement( DmElementDictHandle_t h ) { return m_Dict.IsValidIndex( h+1 ) ? h+1 : ELEMENT_DICT_HANDLE_INVALID; } private: struct AttributeInfo_t { CDmAttribute *m_pAttribute; int m_nType; // AT_ELEMENT or AT_OBJECTID union { DmElementDictHandle_t m_hElement; DmObjectId_t m_ObjectId; }; }; typedef CUtlVector AttributeList_t; struct DmIdPair_t { DmObjectId_t m_oldId; DmObjectId_t m_newId; DmIdPair_t() {} DmIdPair_t( const DmObjectId_t &id ) { CopyUniqueId( id, &m_oldId ); } DmIdPair_t( const DmObjectId_t &oldId, const DmObjectId_t &newId ) { CopyUniqueId( oldId, &m_oldId ); CopyUniqueId( newId, &m_newId ); } DmIdPair_t &operator=( const DmIdPair_t &that ) { CopyUniqueId( that.m_oldId, &m_oldId ); CopyUniqueId( that.m_newId, &m_newId ); return *this; } static unsigned int HashKey( const DmIdPair_t& that ) { return *( unsigned int* )&that.m_oldId.m_Value; } static bool Compare( const DmIdPair_t& a, const DmIdPair_t& b ) { return IsUniqueIdEqual( a.m_oldId, b.m_oldId ); } }; struct DeletionInfo_t { DeletionInfo_t() {} DeletionInfo_t( DmElementHandle_t hElement ) : m_hElementToDelete( hElement ) {} bool operator==( const DeletionInfo_t& src ) const { return m_hElementToDelete == src.m_hElementToDelete; } DmElementDictHandle_t m_hDictHandle; DmElementHandle_t m_hElementToDelete; DmElementHandle_t m_hReplacementElement; }; // Hook up all element references (which were unserialized as object ids) void HookUpElementAttributes(); void HookUpElementArrayAttributes(); void RemoveAttributeInfosOfElement( AttributeList_t &attributes, DmElementHandle_t hElement ); CUtlVector< DmElementHandle_t > m_Dict; AttributeList_t m_Attributes; AttributeList_t m_ArrayAttributes; CUtlVector< DeletionInfo_t > m_elementsToDelete; CUtlHash< DmIdPair_t > m_idmap; }; //----------------------------------------------------------------------------- // Element dictionary used in serialization //----------------------------------------------------------------------------- class CDmElementSerializationDictionary { public: CDmElementSerializationDictionary(); // Creates the list of all things to serialize void BuildElementList( CDmElement *pRoot, bool bFlatMode ); // Should I inline the serialization of this element? bool ShouldInlineElement( CDmElement *pElement ); // Clears the dictionary void Clear(); // Iterates over all root elements to serialize DmElementDictHandle_t FirstRootElement() const; DmElementDictHandle_t NextRootElement( DmElementDictHandle_t h ) const; CDmElement* GetRootElement( DmElementDictHandle_t h ); // Finds the handle of the element DmElementDictHandle_t Find( CDmElement *pElement ); // How many root elements do we have? int RootElementCount() const; private: struct ElementInfo_t { bool m_bRoot; CDmElement* m_pElement; }; // Creates the list of all things to serialize void BuildElementList_R( CDmElement *pRoot, bool bFlatMode, bool bIsRoot ); static bool LessFunc( const ElementInfo_t &lhs, const ElementInfo_t &rhs ); CUtlBlockRBTree< ElementInfo_t, DmElementDictHandle_t > m_Dict; }; #endif // DMELEMENTDICTIONARY_H