|
@@ -11,7 +11,7 @@ namespace CamelotEngine
|
|
|
* otherwise sizeof() is used.
|
|
* otherwise sizeof() is used.
|
|
|
*/
|
|
*/
|
|
|
template<class ElemType>
|
|
template<class ElemType>
|
|
|
- UINT32 rttiGetElemSize(ElemType& data)
|
|
|
|
|
|
|
+ UINT32 rttiGetElemSize(const ElemType& data)
|
|
|
{
|
|
{
|
|
|
if(RTTIPlainType<ElemType>::hasDynamicSize == 1)
|
|
if(RTTIPlainType<ElemType>::hasDynamicSize == 1)
|
|
|
return RTTIPlainType<ElemType>::getDynamicSize(data);
|
|
return RTTIPlainType<ElemType>::getDynamicSize(data);
|
|
@@ -27,7 +27,7 @@ namespace CamelotEngine
|
|
|
* bytes written and returns pointer to new memory.
|
|
* bytes written and returns pointer to new memory.
|
|
|
*/
|
|
*/
|
|
|
template<class ElemType>
|
|
template<class ElemType>
|
|
|
- char* rttiWriteElem(ElemType& data, char* memory)
|
|
|
|
|
|
|
+ char* rttiWriteElem(const ElemType& data, char* memory)
|
|
|
{
|
|
{
|
|
|
RTTIPlainType<ElemType>::toMemory(data, memory);
|
|
RTTIPlainType<ElemType>::toMemory(data, memory);
|
|
|
|
|
|
|
@@ -59,17 +59,18 @@ namespace CamelotEngine
|
|
|
enum { id = 0 };
|
|
enum { id = 0 };
|
|
|
enum { hasDynamicSize = 0 };
|
|
enum { hasDynamicSize = 0 };
|
|
|
|
|
|
|
|
- static void toMemory(T& data, char* memory)
|
|
|
|
|
|
|
+ static void toMemory(const T& data, char* memory)
|
|
|
{
|
|
{
|
|
|
memcpy(memory, &data, sizeof(T));
|
|
memcpy(memory, &data, sizeof(T));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- static void fromMemory(T& data, char* memory)
|
|
|
|
|
|
|
+ static UINT32 fromMemory(T& data, char* memory)
|
|
|
{
|
|
{
|
|
|
memcpy(&data, memory, sizeof(T));
|
|
memcpy(&data, memory, sizeof(T));
|
|
|
|
|
+ return sizeof(T);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- static UINT32 getDynamicSize(T& data)
|
|
|
|
|
|
|
+ static UINT32 getDynamicSize(const T& data)
|
|
|
{
|
|
{
|
|
|
assert(false);
|
|
assert(false);
|
|
|
return sizeof(T);
|
|
return sizeof(T);
|
|
@@ -79,11 +80,126 @@ namespace CamelotEngine
|
|
|
#define CM_ALLOW_MEMCPY_SERIALIZATION(type) \
|
|
#define CM_ALLOW_MEMCPY_SERIALIZATION(type) \
|
|
|
template<> struct RTTIPlainType<##type##> \
|
|
template<> struct RTTIPlainType<##type##> \
|
|
|
{ enum { id=0 }; enum { hasDynamicSize = 0 }; \
|
|
{ enum { id=0 }; enum { hasDynamicSize = 0 }; \
|
|
|
- static void toMemory(##type##& data, char* memory) \
|
|
|
|
|
|
|
+ static void toMemory(const type& data, char* memory) \
|
|
|
{ memcpy(memory, &data, sizeof(##type##)); } \
|
|
{ memcpy(memory, &data, sizeof(##type##)); } \
|
|
|
- static void fromMemory(##type##& data, char* memory) \
|
|
|
|
|
- { memcpy(&data, memory, sizeof(##type##)); } \
|
|
|
|
|
- static UINT32 getDynamicSize(##type##& data) \
|
|
|
|
|
|
|
+ static UINT32 fromMemory(##type##& data, char* memory) \
|
|
|
|
|
+ { memcpy(&data, memory, sizeof(##type##)); return sizeof(##type##); } \
|
|
|
|
|
+ static UINT32 getDynamicSize(const type& data) \
|
|
|
{ assert(false); return sizeof(##type##); } \
|
|
{ assert(false); return sizeof(##type##); } \
|
|
|
};
|
|
};
|
|
|
|
|
+
|
|
|
|
|
+ // RTTI types for some standard classes
|
|
|
|
|
+ template<class T> struct RTTIPlainType<std::vector<T>>
|
|
|
|
|
+ {
|
|
|
|
|
+ enum { id = TID_STDVECTOR }; enum { hasDynamicSize = 1 };
|
|
|
|
|
+
|
|
|
|
|
+ static void toMemory(const std::vector<T>& data, char* memory)
|
|
|
|
|
+ {
|
|
|
|
|
+ UINT32 size = (UINT32)data.size();
|
|
|
|
|
+
|
|
|
|
|
+ memcpy(memory, &size, sizeof(UINT32));
|
|
|
|
|
+ memory += sizeof(UINT32);
|
|
|
|
|
+
|
|
|
|
|
+ for(auto iter = data.begin(); iter != data.end(); ++iter)
|
|
|
|
|
+ {
|
|
|
|
|
+ UINT32 elementSize = RTTIPlainType<T>::getDynamicSize(*iter);
|
|
|
|
|
+ RTTIPlainType<T>::toMemory(*iter, memory);
|
|
|
|
|
+
|
|
|
|
|
+ memory += elementSize;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ static UINT32 fromMemory(std::vector<T>& data, char* memory)
|
|
|
|
|
+ {
|
|
|
|
|
+ UINT32 size;
|
|
|
|
|
+ memcpy(&size, memory, sizeof(UINT32));
|
|
|
|
|
+ memory += sizeof(UINT32);
|
|
|
|
|
+
|
|
|
|
|
+ for(UINT32 i = 0; i < size; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ T element;
|
|
|
|
|
+ UINT32 elementSize = RTTIPlainType<T>::fromMemory(element, memory);
|
|
|
|
|
+ data.push_back(element);
|
|
|
|
|
+
|
|
|
|
|
+ memory += elementSize;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return size;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ static UINT32 getDynamicSize(const std::vector<T>& data)
|
|
|
|
|
+ {
|
|
|
|
|
+ UINT64 dataSize = sizeof(UINT32);
|
|
|
|
|
+
|
|
|
|
|
+ for(auto iter = data.begin(); iter != data.end(); ++iter)
|
|
|
|
|
+ dataSize += RTTIPlainType<T>::getDynamicSize(*iter);
|
|
|
|
|
+
|
|
|
|
|
+ assert(dataSize <= std::numeric_limits<UINT32>::max());
|
|
|
|
|
+
|
|
|
|
|
+ return (UINT32)dataSize;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ template<class Key, class Value> struct RTTIPlainType<std::map<Key, Value>>
|
|
|
|
|
+ {
|
|
|
|
|
+ enum { id = TID_STDMAP }; enum { hasDynamicSize = 1 };
|
|
|
|
|
+
|
|
|
|
|
+ static void toMemory(const std::map<Key, Value>& data, char* memory)
|
|
|
|
|
+ {
|
|
|
|
|
+ UINT32 size = (UINT32)data.size();
|
|
|
|
|
+
|
|
|
|
|
+ memcpy(memory, &size, sizeof(UINT32));
|
|
|
|
|
+ memory += sizeof(UINT32);
|
|
|
|
|
+
|
|
|
|
|
+ for(auto iter = data.begin(); iter != data.end(); ++iter)
|
|
|
|
|
+ {
|
|
|
|
|
+ UINT32 keySize = RTTIPlainType<Key>::getDynamicSize(iter->first);
|
|
|
|
|
+ RTTIPlainType<Key>::toMemory(iter->first, memory);
|
|
|
|
|
+
|
|
|
|
|
+ memory += keySize;
|
|
|
|
|
+
|
|
|
|
|
+ UINT32 valueSize = RTTIPlainType<Value>::getDynamicSize(iter->second);
|
|
|
|
|
+ RTTIPlainType<Value>::toMemory(iter->second, memory);
|
|
|
|
|
+
|
|
|
|
|
+ memory += valueSize;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ static UINT32 fromMemory(std::map<Key, Value>& data, char* memory)
|
|
|
|
|
+ {
|
|
|
|
|
+ UINT32 size;
|
|
|
|
|
+ memcpy(&size, memory, sizeof(UINT32));
|
|
|
|
|
+ memory += sizeof(UINT32);
|
|
|
|
|
+
|
|
|
|
|
+ for(UINT32 i = 0; i < size; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ Key key;
|
|
|
|
|
+ UINT32 keySize = RTTIPlainType<Key>::fromMemory(key, memory);
|
|
|
|
|
+ memory += keySize;
|
|
|
|
|
+
|
|
|
|
|
+ Value value;
|
|
|
|
|
+ UINT32 valueSize = RTTIPlainType<Value>::fromMemory(value, memory);
|
|
|
|
|
+ memory += valueSize;
|
|
|
|
|
+
|
|
|
|
|
+ data[key] = value;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return size;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ static UINT32 getDynamicSize(const std::map<Key, Value>& data)
|
|
|
|
|
+ {
|
|
|
|
|
+ UINT64 dataSize = sizeof(UINT32);
|
|
|
|
|
+
|
|
|
|
|
+ for(auto iter = data.begin(); iter != data.end(); ++iter)
|
|
|
|
|
+ {
|
|
|
|
|
+ dataSize += RTTIPlainType<Key>::getDynamicSize(iter->first);
|
|
|
|
|
+ dataSize += RTTIPlainType<Value>::getDynamicSize(iter->second);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ assert(dataSize <= std::numeric_limits<UINT32>::max());
|
|
|
|
|
+
|
|
|
|
|
+ return (UINT32)dataSize;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
}
|
|
}
|