Просмотр исходного кода

Fixing serializer so it properly handles large value types

Marko Pintera 11 лет назад
Родитель
Сommit
af2dbad955

+ 1 - 1
BansheeUtility/Include/BsMemorySerializer.h

@@ -46,6 +46,6 @@ namespace BansheeEngine
 		/* 								CONSTANTS	                     		*/
 		/* 								CONSTANTS	                     		*/
 		/************************************************************************/
 		/************************************************************************/
 	private:
 	private:
-		static const UINT32 WRITE_BUFFER_SIZE = 2048;
+		static const UINT32 WRITE_BUFFER_SIZE = 16384;
 	};
 	};
 }
 }

+ 68 - 46
BansheeUtility/Source/BsBinarySerializer.cpp

@@ -248,22 +248,27 @@ namespace BansheeEngine
 								else
 								else
 									typeSize = curField->getTypeSize();
 									typeSize = curField->getTypeSize();
 
 
-								if((*bytesWritten + typeSize) > bufferLength)
+								if ((*bytesWritten + typeSize) > bufferLength)
 								{
 								{
-									mTotalBytesWritten += *bytesWritten;
-									buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength);
-									if(buffer == nullptr || bufferLength < typeSize)
+									UINT8* tempBuffer = (UINT8*)stackAlloc(typeSize);
+									curField->arrayElemToBuffer(object, arrIdx, tempBuffer);
+
+									buffer = dataBlockToBuffer(tempBuffer, typeSize, buffer, bufferLength, bytesWritten, flushBufferCallback);
+									if (buffer == nullptr || bufferLength == 0)
 									{
 									{
-										return nullptr;
+										stackDeallocLast(tempBuffer);
 										si->onSerializationEnded(object);
 										si->onSerializationEnded(object);
+										return nullptr;
 									}
 									}
 
 
-									*bytesWritten = 0;
+									stackDeallocLast(tempBuffer);
+								}
+								else
+								{
+									curField->arrayElemToBuffer(object, arrIdx, buffer);
+									buffer += typeSize;
+									*bytesWritten += typeSize;
 								}
 								}
-
-								curField->arrayElemToBuffer(object, arrIdx, buffer);
-								buffer += typeSize;
-								*bytesWritten += typeSize;
 							}
 							}
 
 
 							break;
 							break;
@@ -312,22 +317,27 @@ namespace BansheeEngine
 							else
 							else
 								typeSize = curField->getTypeSize();
 								typeSize = curField->getTypeSize();
 
 
-							if((*bytesWritten + typeSize) > bufferLength)
+							if ((*bytesWritten + typeSize) > bufferLength)
 							{
 							{
-								mTotalBytesWritten += *bytesWritten;
-								buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength);
-								if(buffer == nullptr || bufferLength < typeSize)
+								UINT8* tempBuffer = (UINT8*)stackAlloc(typeSize);
+								curField->toBuffer(object, tempBuffer);
+								
+								buffer = dataBlockToBuffer(tempBuffer, typeSize, buffer, bufferLength, bytesWritten, flushBufferCallback);
+								if (buffer == nullptr || bufferLength == 0)
 								{
 								{
+									stackDeallocLast(tempBuffer);
 									si->onSerializationEnded(object);
 									si->onSerializationEnded(object);
 									return nullptr;
 									return nullptr;
 								}
 								}
-								*bytesWritten = 0;
-							}
-
 
 
-							curField->toBuffer(object, buffer);
-							buffer += typeSize;
-							*bytesWritten += typeSize;
+								stackDeallocLast(tempBuffer);
+							}
+							else
+							{
+								curField->toBuffer(object, buffer);
+								buffer += typeSize;
+								*bytesWritten += typeSize;
+							}
 
 
 							break;
 							break;
 						}
 						}
@@ -342,33 +352,12 @@ namespace BansheeEngine
 
 
 							// Data block data
 							// Data block data
 							UINT8* dataToStore = value.getData();
 							UINT8* dataToStore = value.getData();
-							UINT32 remainingSize = dataBlockSize;
-							while(remainingSize > 0)
-							{
-								UINT32 remainingSpaceInBuffer = bufferLength - *bytesWritten;
 
 
-								if(remainingSize <= remainingSpaceInBuffer)
-								{
-									COPY_TO_BUFFER(dataToStore, remainingSize);
-									remainingSize = 0;
-								}
-								else
-								{
-									memcpy(buffer, dataToStore, remainingSpaceInBuffer);
-									buffer += remainingSpaceInBuffer;
-									*bytesWritten += remainingSpaceInBuffer;
-									dataToStore += remainingSpaceInBuffer;
-									remainingSize -= remainingSpaceInBuffer;
-								
-									mTotalBytesWritten += *bytesWritten;
-									buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength);
-									if(buffer == nullptr || bufferLength == 0) 
-									{
-										si->onSerializationEnded(object);
-										return nullptr;
-									}
-									*bytesWritten = 0;
-								}
+							buffer = dataBlockToBuffer(dataToStore, dataBlockSize, buffer, bufferLength, bytesWritten, flushBufferCallback);
+							if (buffer == nullptr || bufferLength == 0)
+							{
+								si->onSerializationEnded(object);
+								return nullptr;
 							}
 							}
 
 
 							break;
 							break;
@@ -1060,6 +1049,39 @@ exit:
 		return emptyObject;
 		return emptyObject;
 	}
 	}
 
 
+	UINT8* BinarySerializer::dataBlockToBuffer(UINT8* data, UINT32 size, UINT8* buffer, UINT32& bufferLength, int* bytesWritten,
+		std::function<UINT8*(UINT8* buffer, int bytesWritten, UINT32& newBufferSize)> flushBufferCallback)
+	{
+		UINT32 remainingSize = size;
+		while (remainingSize > 0)
+		{
+			UINT32 remainingSpaceInBuffer = bufferLength - *bytesWritten;
+
+			if (remainingSize <= remainingSpaceInBuffer)
+			{
+				COPY_TO_BUFFER(data, remainingSize);
+				remainingSize = 0;
+			}
+			else
+			{
+				memcpy(buffer, data, remainingSpaceInBuffer);
+				buffer += remainingSpaceInBuffer;
+				*bytesWritten += remainingSpaceInBuffer;
+				data += remainingSpaceInBuffer;
+				remainingSize -= remainingSpaceInBuffer;
+
+				mTotalBytesWritten += *bytesWritten;
+				buffer = flushBufferCallback(buffer - *bytesWritten, *bytesWritten, bufferLength);
+				if (buffer == nullptr || bufferLength == 0)
+					return nullptr;
+
+				*bytesWritten = 0;
+			}
+		}
+
+		return buffer;
+	}
+
 	UINT32 BinarySerializer::findOrCreatePersistentId(IReflectable* object)
 	UINT32 BinarySerializer::findOrCreatePersistentId(IReflectable* object)
 	{
 	{
 		void* ptrAddress = (void*)object;
 		void* ptrAddress = (void*)object;

+ 3 - 3
BansheeUtility/Source/BsMemorySerializer.cpp

@@ -21,7 +21,7 @@ namespace BansheeEngine
 		BinarySerializer bs;
 		BinarySerializer bs;
 
 
 		BufferPiece piece;
 		BufferPiece piece;
-		piece.buffer = (UINT8*)stackAlloc(WRITE_BUFFER_SIZE);
+		piece.buffer = (UINT8*)bs_alloc(WRITE_BUFFER_SIZE);
 		piece.size = 0;
 		piece.size = 0;
 
 
 		mBufferPieces.push_back(piece);
 		mBufferPieces.push_back(piece);
@@ -46,7 +46,7 @@ namespace BansheeEngine
 
 
 		for(auto iter = mBufferPieces.rbegin(); iter != mBufferPieces.rend(); ++iter)
 		for(auto iter = mBufferPieces.rbegin(); iter != mBufferPieces.rend(); ++iter)
 		{
 		{
-			stackDeallocLast(iter->buffer);
+			bs_free(iter->buffer);
 		}
 		}
 
 
 		return resultBuffer;
 		return resultBuffer;
@@ -65,7 +65,7 @@ namespace BansheeEngine
 		mBufferPieces.back().size = bytesWritten;
 		mBufferPieces.back().size = bytesWritten;
 
 
 		BufferPiece piece;
 		BufferPiece piece;
-		piece.buffer = (UINT8*)stackAlloc(WRITE_BUFFER_SIZE);
+		piece.buffer = (UINT8*)bs_alloc(WRITE_BUFFER_SIZE);
 		piece.size = 0;
 		piece.size = 0;
 
 
 		mBufferPieces.push_back(piece);
 		mBufferPieces.push_back(piece);