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
|
#ifndef ITERATETYPETREE_H
#define ITERATETYPETREE_H
#include "TypeTree.h"
#include "SerializeTraits.h"
#include "TransferUtility.h"
/* Iterate typetree is used to process serialized data in arbitrary ways.
struct IterateTypeTreeFunctor
{
// return true if you want to recurse into the function
bool operator () (const TypeTree& typeTree, dynamic_array<UInt8>& data, int bytePosition)
{
}
}
TypeTree typeTree;
dynamic_array<UInt8> data
// Create typetree and data
GenerateTypeTree(object);
WriteObjectToVector(object, &data);
// Modify data
IterateTypeTreeFunctor func;
IterateTypeTree (typeTree, data, func);
ReadObjectFromVector(&object, data, typeTree);
object.CheckConsistency ();
object.AwakeFromLoad (false);
object.SetDirty ();
*/
inline SInt32 ExtractPPtrInstanceID (const UInt8* data)
{
return *reinterpret_cast<const SInt32*> (data);
}
inline SInt32 ExtractPPtrInstanceID (const dynamic_array<UInt8>& data, int bytePosition)
{
return ExtractPPtrInstanceID(&data[bytePosition]);
}
inline void SetPPtrInstanceID (SInt32 instanceID, dynamic_array<UInt8>& data, int bytePosition)
{
*reinterpret_cast<SInt32*> (&data[bytePosition]) = instanceID;
}
inline bool IsTypeTreePPtr (const TypeTree& typeTree)
{
return typeTree.m_Type.find ("PPtr<") == 0;
}
inline bool IsTypeTreeString (const TypeTree& typeTree)
{
return typeTree.m_Type == "string" && typeTree.m_Children.size() == 1 && typeTree.m_Children.back().m_IsArray;
}
inline bool IsTypeTreePPtrArray (const TypeTree& typeTree)
{
return typeTree.m_IsArray && typeTree.m_Children.back().m_Type.find ("PPtr<") == 0;
}
inline bool IsTypeTreeArraySize (const TypeTree& typeTree)
{
return typeTree.m_Father != NULL && typeTree.m_Father->m_IsArray && &typeTree.m_Father->m_Children.front() == &typeTree;
}
inline bool IsTypeTreeArrayElement (const TypeTree& typeTree)
{
return typeTree.m_Father != NULL && typeTree.m_Father->m_IsArray && &typeTree.m_Father->m_Children.back() == &typeTree;
}
inline bool IsTypeTreeArrayOrArrayContainer (const TypeTree& typeTree)
{
return typeTree.m_IsArray || (typeTree.m_Children.size() == 1 && typeTree.m_Children.back().m_IsArray);
}
inline bool IsTypeTreeArray (const TypeTree& typeTree)
{
return typeTree.m_IsArray;
}
inline int ExtractArraySize (const UInt8* data)
{
return *reinterpret_cast<const SInt32*> (data);
}
inline void SetArraySize (UInt8* data, SInt32 size)
{
*reinterpret_cast<SInt32*> (data) = size;
}
inline int ExtractArraySize (const dynamic_array<UInt8>& data, int bytePosition)
{
return *reinterpret_cast<const SInt32*> (&data[bytePosition]);
}
inline UInt32 Align4_Iterate (UInt32 size)
{
UInt32 value = ((size + 3) >> 2) << 2;
return value;
}
#if UNITY_EDITOR
template<class Functor>
void IterateTypeTree (const TypeTree& typeTree, dynamic_array<UInt8>& data, Functor& functor)
{
int bytePosition = 0;
IterateTypeTree (typeTree, data, &bytePosition, functor);
}
template<class Functor>
void IterateTypeTree (const TypeTree& typeTree, dynamic_array<UInt8>& data, int* bytePosition, Functor& functor)
{
if (functor (typeTree, data, *bytePosition))
{
if (typeTree.m_IsArray)
{
// First child in an array is the size
// Second child is the homogenous type of the array
AssertIf (typeTree.m_Children.front ().m_Type != SerializeTraits<SInt32>::GetTypeString (NULL) || typeTree.m_Children.front ().m_Name != "size" || typeTree.m_Children.size () != 2);
functor (typeTree.m_Children.front (), data, *bytePosition);
SInt32 arraySize, i;
arraySize = *reinterpret_cast<SInt32*> (&data[*bytePosition]);
*bytePosition += sizeof (arraySize);
for (i=0;i<arraySize;i++)
IterateTypeTree (typeTree.m_Children.back (), data, bytePosition, functor);
}
else
{
TypeTree::TypeTreeList::const_iterator i;
for (i = typeTree.m_Children.begin (); i != typeTree.m_Children.end ();++i)
IterateTypeTree (*i, data, bytePosition, functor);
}
if (typeTree.IsBasicDataType ())
*bytePosition += typeTree.m_ByteSize;
if (typeTree.m_MetaFlag & kAlignBytesFlag)
*bytePosition = Align4_Iterate (*bytePosition);
}
else
{
WalkTypeTree(typeTree, data.begin (), bytePosition);
}
}
#endif
#endif
|