summaryrefslogtreecommitdiff
path: root/Runtime/Serialize/TypeTree.h
blob: 0fd6e2f2151439d21583912cc28f0438818af98d (plain)
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
#ifndef TYPETREE_H
#define TYPETREE_H

#include <list>
#include <vector>
#include <string>

#include "Runtime/Misc/Allocator.h"
#include "Configuration/UnityConfigure.h"
#include "SerializationMetaFlags.h"
#include "Runtime/Allocator/MemoryMacros.h"
#include "Runtime/Serialize/SwapEndianBytes.h"

typedef UNITY_VECTOR(kMemSerialization, UInt8) SerializationCache;

template<bool kSwap, class T>
// Need this in order for Asset bundles to load correctly when the code is optimized
#if UNITY_BB10
__attribute__ ((noinline))
#endif
void ReadHeaderCache (T& t, UInt8 const*& c)
{
	t = *(T const*)c;
	if (kSwap)
		SwapEndianBytes (t);
	c += sizeof (T);
}

template<bool kSwap, class T>
void WriteHeaderCache (const T& t, SerializationCache& vec)
{
	vec.resize (vec.size () + sizeof (T));
	T& dst = *reinterpret_cast<T*> (&vec[vec.size () - sizeof (T)]);
	dst = t;
	if (kSwap)
		SwapEndianBytes (dst);
}

UNITY_STR_IMPL(TypeTreeString, kMemTypeTree);

/// A TypeTree contains information on serialized data.
/// It is a tree storing the name, and type and other information generated by the serialization code,
/// of every variable and all its variables that it might contain.
/// A TypeTree can be generated using a ProxyTransfer class.
/// There are convenience function which generate them from an object in TransferUtility.h

class TypeTree
{
	public:

	typedef UNITY_LIST(kMemTypeTree,TypeTree) TypeTreeList;
	typedef TypeTreeList::iterator iterator;
	typedef TypeTreeList::const_iterator const_iterator;
	TypeTreeList                m_Children; // The children of the Type (eg. a Vector3f has 3 children, float x, float y, float z)
	TypeTree*					m_Father;
	
	TypeTreeString				m_Type;// The type of the variable (eg. "Vector3f", "int")
	TypeTreeString				m_Name;// The name of the property (eg. "m_LocalPosition")
	SInt32						m_ByteSize;//= -1 if its not determinable (arrays) 
	SInt32						m_Index; // The index of the property (Prefabs use this index in the override bitset)
	SInt32						m_IsArray;// Is the TypeTree an array (first child is the size, second child is the type of the array elements)
	SInt32						m_Version; // The version of the serialization format as represented by this type tree.  Usually determined by Transfer() functions.

	// Serialization meta data (eg. to hide variables in the property editor)
	// Children or their meta flags with their parents!
	TransferMetaFlags			m_MetaFlag;
	SInt32						m_ByteOffset; // The byteoffset into the property in memory. When a variable on the stack is serialized m_ByteOffset is -1.
	void*						m_DirectPtr; // The direct ptr into the property in memory. NULL if it can't be used.
	
	TypeTree ();
	TypeTree (const std::string& name, const std::string& type, SInt32 size);
	
	void DebugPrint (std::string& buffer, int level = 0) const;
	bool IsBasicDataType ()const { return m_Children.empty () && m_ByteSize > 0; }
	
	iterator begin ()			{ return m_Children.begin (); }
	iterator end () 			{ return m_Children.end (); }
	const_iterator begin ()	const		{ return m_Children.begin (); }
	const_iterator end () const 		{ return m_Children.end (); }
	
	void operator = (const TypeTree& typeTree);
};

void GetTypePath (const TypeTree* type, std::string& s);
const TypeTree& GetElementTypeFromContainer (const TypeTree& typeTree);
SInt32 GetContainerArraySize (const TypeTree& typeTree, void* data);
void AppendTypeTree (TypeTree& typeTree, TypeTree::iterator begin, TypeTree::iterator end);
void AppendTypeTree (TypeTree& typeTree, const TypeTree& typeTreeToAdd);
void RemoveFromTypeTree (TypeTree& typeTree, TypeTree::iterator begin, TypeTree::iterator end);

class Type
{
	TypeTree*	m_OldType;	// Type loaded from Disk
	TypeTree*	m_NewType;	// Active type
	bool			m_Equals;	// Are oldType and newType equal
	
	public:
	
	Type ();
	
	~Type ();
	
	TypeTree* GetOldType () 		{ return m_OldType; }
	TypeTree* GetNewType () 		{ return m_NewType; }

	bool EqualTypes () 				{ return m_Equals; }
	
	void SetOldType (TypeTree* t);
	void SetNewType (TypeTree* t);	
};

/// Reads/Writes a typetree to a vector<UInt8> with the first four bits being the version of the typetree
bool ReadVersionedTypeTreeFromVector (TypeTree* typeTree, UInt8 const*& iterator, UInt8 const* end, bool swapEndianess);

/// Reads/Writes a typeTree to a cache, used direcly by SerializedFile
bool ReadTypeTree (TypeTree& t, UInt8 const*& iterator, UInt8 const* end, int version, bool swapEndian);
void WriteTypeTree (TypeTree& t, SerializationCache& cache, bool swapEndianess);

bool IsStreamedBinaryCompatbile (const TypeTree& lhs, const TypeTree& rhs);
bool IsStreamedBinaryCompatbileAndIndices (const TypeTree& lhs, const TypeTree& rhs);


void WriteString (TypeTreeString const& s, SerializationCache& cache);
void WriteString (UnityStr const& s, SerializationCache& cache);
bool ReadString (TypeTreeString& s, UInt8 const*& iterator, UInt8 const* end);
bool ReadString (UnityStr& s, UInt8 const*& iterator, UInt8 const* end);

UInt32 HashTypeTree (TypeTree& typeTree);

#endif