Browse Source

Added the ability to use custom allocators for serializable data blocks

Marko Pintera 12 years ago
parent
commit
e8f0a06858

+ 13 - 1
CamelotUtility/Include/CmRTTIManagedDataBlockField.h

@@ -8,8 +8,18 @@ namespace CamelotEngine
 {
 {
 	struct RTTIManagedDataBlockFieldBase : public RTTIField
 	struct RTTIManagedDataBlockFieldBase : public RTTIField
 	{
 	{
+		boost::function<UINT8*(UINT32)> mCustomAllocator;
+
 		virtual ManagedDataBlock getValue(void* object) = 0;
 		virtual ManagedDataBlock getValue(void* object) = 0;
 		virtual void setValue(void* object, ManagedDataBlock value) = 0;
 		virtual void setValue(void* object, ManagedDataBlock value) = 0;
+
+		UINT8* allocate(UINT32 bytes)
+		{
+			if(mCustomAllocator.empty())
+				return new UINT8[bytes];
+			else
+				return mCustomAllocator(bytes);
+		}
 	};
 	};
 
 
 	template <class DataType, class ObjectType>
 	template <class DataType, class ObjectType>
@@ -26,10 +36,12 @@ namespace CamelotEngine
 		 * @param	getter  	The getter method for the field. Cannot be null. Must be a specific signature: SerializableDataBlock(ObjectType*)
 		 * @param	getter  	The getter method for the field. Cannot be null. Must be a specific signature: SerializableDataBlock(ObjectType*)
 		 * @param	setter  	The setter method for the field. Can be null. Must be a specific signature: void(ObjectType*, SerializableDataBlock)	
 		 * @param	setter  	The setter method for the field. Can be null. Must be a specific signature: void(ObjectType*, SerializableDataBlock)	
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
 		 * @param	flags		Various flags you can use to specialize how systems handle this field
+		 * @param	customAllocator (optional) Custom allocator that will be used when de-serializing DataBlock memory.
 		 */
 		 */
-		void initSingle(const std::string& name, UINT16 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
+		void initSingle(const std::string& name, UINT16 uniqueId, boost::any getter, boost::any setter, UINT64 flags, boost::function<UINT8*(UINT32)> customAllocator = 0)
 		{
 		{
 			initAll(getter, setter, nullptr, nullptr, name, uniqueId, false, SerializableFT_DataBlock, flags);
 			initAll(getter, setter, nullptr, nullptr, name, uniqueId, false, SerializableFT_DataBlock, flags);
+			mCustomAllocator = customAllocator;
 		}
 		}
 
 
 		virtual UINT32 getTypeSize()
 		virtual UINT32 getTypeSize()

+ 2 - 2
CamelotUtility/Include/CmRTTIType.h

@@ -642,11 +642,11 @@ namespace CamelotEngine
 		}
 		}
 
 
 		template<class ObjectType>
 		template<class ObjectType>
-		void addDataBlockField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any setter, UINT64 flags)
+		void addDataBlockField(const std::string& name, UINT32 uniqueId, boost::any getter, boost::any setter, UINT64 flags, boost::function<UINT8*(UINT32)> customAllocator = 0)
 		{
 		{
 			RTTIManagedDataBlockField<ManagedDataBlock, ObjectType>* newField = 
 			RTTIManagedDataBlockField<ManagedDataBlock, ObjectType>* newField = 
 				CM_NEW(RTTIManagedDataBlockField<ManagedDataBlock BOOST_PP_COMMA() ObjectType>, GenAlloc) RTTIManagedDataBlockField<ManagedDataBlock, ObjectType>();
 				CM_NEW(RTTIManagedDataBlockField<ManagedDataBlock BOOST_PP_COMMA() ObjectType>, GenAlloc) RTTIManagedDataBlockField<ManagedDataBlock, ObjectType>();
-			newField->initSingle(name, uniqueId, getter,  setter, flags);
+			newField->initSingle(name, uniqueId, getter,  setter, flags, customAllocator);
 			addNewField(newField);
 			addNewField(newField);
 		}	
 		}	
 	};
 	};

+ 1 - 1
CamelotUtility/Source/CmBinarySerializer.cpp

@@ -760,7 +760,7 @@ namespace CamelotEngine
 						// Data block data
 						// Data block data
 						if(curField != nullptr)
 						if(curField != nullptr)
 						{
 						{
-							UINT8* dataCopy = new UINT8[dataBlockSize]; // TODO - Low priority. I need to read files better, so I
+							UINT8* dataCopy = curField->allocate(dataBlockSize); // TODO - Low priority. I need to read files better, so I
 							memcpy(dataCopy, data, dataBlockSize);		//    can just pass the buffer pointer directly without copying (possibly large amounts of data)
 							memcpy(dataCopy, data, dataBlockSize);		//    can just pass the buffer pointer directly without copying (possibly large amounts of data)
 
 
 							ManagedDataBlock value(dataCopy, dataBlockSize, false); // Not managed because I assume the owner class will decide whether to delete the data or keep it
 							ManagedDataBlock value(dataCopy, dataBlockSize, false); // Not managed because I assume the owner class will decide whether to delete the data or keep it