summaryrefslogtreecommitdiff
path: root/Runtime/Utilities/Utility.h
blob: b24fcbaec8c5b8f592dbe1a7f2c87963c2f00a27 (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
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#ifndef UTILITY_H
#define UTILITY_H

#include "Runtime/Allocator/MemoryMacros.h"

#define UNUSED(x)	(void)sizeof(x)

#define SAFE_RELEASE(obj) if (obj) { (obj)->Release(); (obj) = NULL; } else {}
#define SAFE_RELEASE_LABEL(obj,label) if (obj) { (obj)->Release(label); (obj) = NULL; } else {}

template <class T0, class T1>
inline void CopyData (T0 *dst, const T1 *src, long int inHowmany)
{
	for (long int i=0;i<inHowmany;i++)
	{
		dst[i] = src[i];
	}
}

template <class DataType>
inline void CopyOverlappingData (DataType *dst, const DataType *src, long int inHowmany)
{
	if (dst < src)
	{
		for (long int i=0;i<inHowmany;i++)
		{
			dst[i] = src[i];
		}
	}
	else if (dst > src)
	{
		for (long int i=inHowmany-1;i>=0;i--)
		{
			dst[i] = src[i];
		}
	}
}

template <class DataType>
inline void CopyRange (DataType *dst, const DataType *src, long int inStart, long int inHowmany)
{
	for (long int i=inStart;i<inHowmany+inStart;i++)
	{
		dst[i] = src[i];
	}
}

template <class DataType>
inline void CopyData (DataType *dst, const DataType src, long int inHowmany)
{
	for (long int i=0;i<inHowmany;i++)
	{
		dst[i] = src;
	}
}

template <class DataType>
inline void CopyDataReverse (DataType *dst, const DataType *src, long int inHowmany)
{
	for (long int i=0;i<inHowmany;i++)
	{
		dst[i] = src[inHowmany-1-i];
	}
}

template <class DataType>
inline bool CompareArrays (const DataType *lhs, const DataType *rhs, long int arraySize)
{
	for (long int i=0; i<arraySize; i++)
	{
		if (lhs[i] != rhs[i])
			return false;
	}
	return true;
}

template <class DataType>
inline bool CompareMemory (const DataType& lhs, const DataType& rhs)
{
#ifdef ALIGN_OF
	// We check at compile time if it's safe to cast data to int*
	if (ALIGN_OF(DataType) >= ALIGN_OF(int) && (sizeof(DataType) % sizeof(int))==0)
	{
		return CompareArrays((const int*)&lhs, (const int*)&rhs, sizeof(DataType) / sizeof(int));
	}
#endif
	return CompareArrays((const char*)&lhs, (const char*)&rhs, sizeof(DataType));
}

template <class T>
class UNITY_AutoDelete
{
public:
	UNITY_AutoDelete() : m_val(T()) { }
	~UNITY_AutoDelete() { if(m_val) UNITY_DELETE ( m_val, m_label ); }

	void Assign(T val, MemLabelId label) { m_val = val; m_label = label; return *this; }
	bool operator!() { return !m_val; }

	/* Releases the internal pointer without deleting */
	T releasePtr() { T tmp = m_val; m_val = T(); return tmp; }
private:
	UNITY_AutoDelete &operator=(T val);
	UNITY_AutoDelete(const UNITY_AutoDelete<T>& other); // disabled
	void operator=(const UNITY_AutoDelete<T>& other); // disabled
	T m_val;
	MemLabelId m_label;
};

class AutoFree
{
public:
	AutoFree() : m_val(NULL), m_label(kMemDefault) { }
	~AutoFree() { if(m_val) UNITY_FREE ( m_label, m_val ); }

	bool operator!() { return !m_val; }
	void Assign(void* val, MemLabelId label) { m_label = label; m_val = val; }

	/* Releases the internal pointer without deleting */
	void* releasePtr() { void* tmp = m_val; m_val = NULL; return tmp; }
private:
	AutoFree &operator=(void* val); // disabled
	AutoFree(const AutoFree& other); // disabled
	void operator=(const AutoFree& other); // disabled
	void* m_val;
	MemLabelId m_label;
};

template <class T>
inline T clamp (const T&t, const T& t0, const T& t1)
{
	if (t < t0)
		return t0;
	else if (t > t1)
		return t1;
	else
		return t;
}

template <>
inline float clamp (const float&t, const float& t0, const float& t1)
{
#if UNITY_XENON || UNITY_PS3
	return FloatMin(FloatMax(t, t0), t1);
#else
	if (t < t0)
		return t0;
	else if (t > t1)
		return t1;
	else
		return t;
#endif
}

template <class T>
inline T clamp01 (const T& t)
{
	if (t < 0)
		return 0;
	else if (t > 1)
		return 1;
	else
		return t;
}

template <>
inline float clamp01<float> (const float& t)
{
#if UNITY_XENON || UNITY_PS3
	return FloatMin(FloatMax(t, 0.0f), 1.0f);
#else
	if (t < 0.0F)
		return 0.0F;
	else if (t > 1.0F)
		return 1.0F;
	else
		return t;
#endif
}

// Asserts if from is NULL or can't be cast to type To
template<class To, class From> inline
To assert_cast (From from)
{
	AssertIf (dynamic_cast<To> (from) == NULL);
	return static_cast<To> (from);
}

inline float SmoothStep (float from, float to, float t) 
{
	t = clamp01(t);
	t = -2.0F * t*t*t + 3.0F * t*t;
	return to * t + from * (1.0f - t);
}
// Rounds value down.
// Note: base must be power of two value.
inline UInt32 RoundDown (UInt32 value, SInt32 base)
{
	return value & (-base);
}
// Rounds value up.
// Note: base must be power of two value.
inline UInt32 RoundUp (UInt32 value, SInt32 base)
{
	return (value + base - 1) & (-base);
}

template<class T>
inline T* Stride (T* p, size_t offset)
{
	return reinterpret_cast<T*>((char*)p + offset);
}

#endif // include-guard