summaryrefslogtreecommitdiff
path: root/datamodel/dmelementdictionary.h
blob: c0ae14a5bc55584ac06c8bfee78cb0379a0da8dd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
//========= 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<AttributeInfo_t> 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