Browse Source

Remove reference counted DataBlocks from Variant. Document loads are slightly faster.

Lloyd Weehuizen 15 years ago
parent
commit
b60bd21aa0
3 changed files with 79 additions and 139 deletions
  1. 5 20
      Include/Rocket/Core/Variant.h
  2. 13 14
      Include/Rocket/Core/Variant.inl
  3. 61 105
      Source/Core/Variant.cpp

+ 5 - 20
Include/Rocket/Core/Variant.h

@@ -141,29 +141,14 @@ public:
 	Variant& operator=(const Variant& copy);
 	Variant& operator=(const Variant& copy);
 
 
 private:
 private:
-	// Actual variant data, reference counted across variants.
-	class DataBlock
-	{
-	public:
-		DataBlock();    
-		~DataBlock();
-		void Clear();
-		Type type;
-
+	
 #ifdef ROCKET_ARCH_64
 #ifdef ROCKET_ARCH_64
-		static const int BUFFER_SIZE = 24; // Required for Strings
+		static const int LOCAL_DATA_SIZE = 32; // Required for Strings
 #else
 #else
-		static const int BUFFER_SIZE = 16;
+		static const int LOCAL_DATA_SIZE = 24;
 #endif
 #endif
-		char data[BUFFER_SIZE];
-		void* data_ptr;
-
-		mutable int reference_count;
-	};
-	DataBlock* data_block;
-
-	void NewDataBlock(Type type);  
-	void ReleaseDataBlock();
+	Type type;
+	char data[LOCAL_DATA_SIZE];
 };
 };
 
 
 #include <Rocket/Core/Variant.inl>
 #include <Rocket/Core/Variant.inl>

+ 13 - 14
Include/Rocket/Core/Variant.inl

@@ -27,9 +27,8 @@
 
 
 // Constructs a variant with internal data.
 // Constructs a variant with internal data.
 template< typename T >
 template< typename T >
-Variant::Variant(const T& t)
+Variant::Variant(const T& t) : type(NONE)
 {
 {
-	data_block = NULL;
 	Set( t );
 	Set( t );
 }
 }
 
 
@@ -37,50 +36,50 @@ Variant::Variant(const T& t)
 template< typename T >
 template< typename T >
 bool Variant::GetInto(T& value) const
 bool Variant::GetInto(T& value) const
 {	
 {	
-	switch (GetType())
+	switch (type)
 	{
 	{
 		case BYTE:
 		case BYTE:
-			return TypeConverter< byte, T >::Convert(*(byte*)data_block->data_ptr, value);
+			return TypeConverter< byte, T >::Convert(*(byte*)data, value);
 		break;
 		break;
 
 
 		case CHAR:
 		case CHAR:
-			return TypeConverter< char, T >::Convert(*(char*)data_block->data_ptr, value);
+			return TypeConverter< char, T >::Convert(*(char*)data, value);
 		break;
 		break;
 
 
 		case FLOAT:
 		case FLOAT:
-			return TypeConverter< float, T >::Convert(*(float*)data_block->data_ptr, value);
+			return TypeConverter< float, T >::Convert(*(float*)data, value);
 		break;
 		break;
 
 
 		case INT:
 		case INT:
-			return TypeConverter< int, T >::Convert(*(int*)data_block->data_ptr, value);
+			return TypeConverter< int, T >::Convert(*(int*)data, value);
 		break;
 		break;
 
 
 		case STRING:
 		case STRING:
-			return TypeConverter< String, T >::Convert(*(String*)data_block->data_ptr, value);
+			return TypeConverter< String, T >::Convert(*(String*)data, value);
 		break;
 		break;
 
 
 		case WORD:
 		case WORD:
-			return TypeConverter< word, T >::Convert(*(word*)data_block->data_ptr, value);
+			return TypeConverter< word, T >::Convert(*(word*)data, value);
 		break;
 		break;
 
 
 		case VECTOR2:
 		case VECTOR2:
-			return TypeConverter< Vector2f, T >::Convert(*(Vector2f*)data_block->data_ptr, value);
+			return TypeConverter< Vector2f, T >::Convert(*(Vector2f*)data, value);
 		break;
 		break;
 
 
 		case COLOURF:
 		case COLOURF:
-			return TypeConverter< Colourf, T >::Convert(*(Colourf*)data_block->data_ptr, value);
+			return TypeConverter< Colourf, T >::Convert(*(Colourf*)data, value);
 		break;
 		break;
 
 
 		case COLOURB:
 		case COLOURB:
-			return TypeConverter< Colourb, T >::Convert(*(Colourb*)data_block->data_ptr, value);
+			return TypeConverter< Colourb, T >::Convert(*(Colourb*)data, value);
 		break;
 		break;
 
 
 		case SCRIPTINTERFACE:
 		case SCRIPTINTERFACE:
-			return TypeConverter< ScriptInterface*, T >::Convert((ScriptInterface*)data_block->data_ptr, value);
+			return TypeConverter< ScriptInterface*, T >::Convert((ScriptInterface*)data, value);			
 		break;
 		break;
 
 
 		case VOIDPTR:
 		case VOIDPTR:
-			return TypeConverter< void*, T >::Convert(data_block->data_ptr, value);
+			return TypeConverter< void*, T >::Convert((void*)data, value);
 		break;
 		break;
 	}
 	}
 
 

+ 61 - 105
Source/Core/Variant.cpp

@@ -31,86 +31,113 @@
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 
 
-Variant::Variant()
+Variant::Variant() : type(NONE)
 {
 {
-	data_block = NULL;
-	
 	// Make sure our object size assumptions fit inside the static buffer
 	// Make sure our object size assumptions fit inside the static buffer
-	ROCKET_STATIC_ASSERT(sizeof(String) <= DataBlock::BUFFER_SIZE, Invalid_Size_String);
-	ROCKET_STATIC_ASSERT(sizeof(Colourb) <= DataBlock::BUFFER_SIZE, Invalid_Size_Colourb);
-	ROCKET_STATIC_ASSERT(sizeof(Colourf) <= DataBlock::BUFFER_SIZE, Invalid_Size_Colourf);
+	ROCKET_STATIC_ASSERT(sizeof(Colourb) <= LOCAL_DATA_SIZE, Invalid_Size_Colourb);
+	ROCKET_STATIC_ASSERT(sizeof(Colourf) <= LOCAL_DATA_SIZE, Invalid_Size_Colourf);
+	ROCKET_STATIC_ASSERT(sizeof(String) <= LOCAL_DATA_SIZE, Invalid_Size_Colourf);
 }
 }
 
 
-Variant::Variant( const Variant& copy )
+Variant::Variant( const Variant& copy ) : type(NONE)
 {
 {
-	data_block = NULL;
 	Set(copy);
 	Set(copy);
 }
 }
 
 
 Variant::~Variant() 
 Variant::~Variant() 
 {
 {
-	ReleaseDataBlock();
+	Clear();
 }
 }
 
 
 void Variant::Clear()
 void Variant::Clear()
 {
 {
-	ReleaseDataBlock();
+	// Free any allocated types.
+	switch (type) 
+	{      
+		case STRING:
+		{
+			// Clean up the string.
+			String* string = (String*)data;
+			string->~String();
+		}
+		break;
+			
+		default:
+		break;
+	}
+	type = NONE;
 }
 }
 
 
 Variant::Type Variant::GetType() const
 Variant::Type Variant::GetType() const
 {
 {
-	if (!data_block)
-		return NONE;
-	
-	return data_block->type;
+	return type;
 }
 }
 
 
 //////////////////////////////////////////////////
 //////////////////////////////////////////////////
 // Set methods
 // Set methods
 //////////////////////////////////////////////////
 //////////////////////////////////////////////////
 
 
-#define SET_VARIANT(type) *((type*)data_block->data_ptr) = value;
+#define SET_VARIANT(type) *((type*)data) = value;
 
 
 void Variant::Set(const Variant& copy)
 void Variant::Set(const Variant& copy)
 {
 {
-	ReleaseDataBlock();
-	if (copy.data_block)
-		copy.data_block->reference_count++;
-	data_block = copy.data_block;
+	switch (copy.type)
+	{
+		case STRING:
+		{
+			// Create the string
+			Set(*(String*)copy.data);
+		}
+		break;
+			
+		default:
+			Clear();
+			memcpy(data, copy.data, LOCAL_DATA_SIZE);
+		break;	
+	}
+	type = copy.type;
 }
 }
 
 
 void Variant::Set(const byte value)
 void Variant::Set(const byte value)
 {
 {
-	NewDataBlock(BYTE);
+	type = BYTE;
 	SET_VARIANT(byte);
 	SET_VARIANT(byte);
 }
 }
 
 
 void Variant::Set(const char value)
 void Variant::Set(const char value)
 {
 {
-	NewDataBlock(CHAR);
+	type = CHAR;
 	SET_VARIANT(char);
 	SET_VARIANT(char);
 }
 }
 
 
 void Variant::Set(const float value)
 void Variant::Set(const float value)
 {
 {
-	NewDataBlock(FLOAT);
+	type = FLOAT;
 	SET_VARIANT(float);
 	SET_VARIANT(float);
 }
 }
 
 
 void Variant::Set(const int value)
 void Variant::Set(const int value)
 {
 {
-	NewDataBlock( INT );
+	type = INT;
 	SET_VARIANT(int);
 	SET_VARIANT(int);
 }
 }
 
 
-void Variant::Set(const String& value) {
-	NewDataBlock(STRING);
-	((String*) data_block->data_ptr)->Assign( value );
+void Variant::Set(const String& value) 
+{
+	if (type == STRING)
+	{
+		((String*)data)->Assign(value);
+	}
+	else
+	{
+		type = STRING;
+		new(data) String(value);
+	}
 }
 }
 
 
 void Variant::Set(const word value)
 void Variant::Set(const word value)
 {
 {
-	NewDataBlock(WORD);
+	type = WORD;
 	SET_VARIANT(word);  
 	SET_VARIANT(word);  
 }
 }
 
 
@@ -121,38 +148,32 @@ void Variant::Set(const char* value)
 
 
 void Variant::Set(void* voidptr) 
 void Variant::Set(void* voidptr) 
 {
 {
-	NewDataBlock(VOIDPTR);
-	data_block->data_ptr = voidptr;
+	type = VOIDPTR;
+	memcpy(data, &voidptr, sizeof(void*));
 }
 }
 
 
-/*void Variant::Set(const Vector3f& value)
-{
-	NewDataBlock(VECTOR3);
-	SET_VARIANT(Vector3f);  
-}*/
-
 void Variant::Set(const Vector2f& value)
 void Variant::Set(const Vector2f& value)
 {
 {
-	NewDataBlock(VECTOR2);
+	type = VECTOR2;
 	SET_VARIANT(Vector2f);
 	SET_VARIANT(Vector2f);
 }
 }
 
 
 void Variant::Set(const Colourf& value)
 void Variant::Set(const Colourf& value)
 {
 {
-	NewDataBlock(COLOURF);
+	type = COLOURF;
 	SET_VARIANT(Colourf);
 	SET_VARIANT(Colourf);
 }
 }
 
 
 void Variant::Set(const Colourb& value)
 void Variant::Set(const Colourb& value)
 {
 {
-	NewDataBlock(COLOURB);
+	type = COLOURB;
 	SET_VARIANT(Colourb);
 	SET_VARIANT(Colourb);
 }
 }
 
 
 void Variant::Set(ScriptInterface* value) 
 void Variant::Set(ScriptInterface* value) 
 {
 {
-	NewDataBlock(SCRIPTINTERFACE);
-	data_block->data_ptr = value;
+	type = SCRIPTINTERFACE;
+	memcpy(data, &value, sizeof(ScriptInterface*));
 }
 }
 
 
 Variant& Variant::operator=(const Variant& copy)
 Variant& Variant::operator=(const Variant& copy)
@@ -161,70 +182,5 @@ Variant& Variant::operator=(const Variant& copy)
 	return *this;
 	return *this;
 }
 }
 
 
-void Variant::NewDataBlock(Type type) 
-{  
-	// Only actually have to make a new data block if 
-	// somebody else is referencing our existing one
-	if ( !data_block || data_block->reference_count > 1 )
-	{
-		ReleaseDataBlock();
-		data_block = new DataBlock();
-	}
-	if (data_block->type != STRING || type == STRING)
-		new(data_block->data_ptr) String();
-
-	data_block->type = type;
-}
-
-void Variant::ReleaseDataBlock() 
-{
-	if (!data_block)
-		return;
-
-	data_block->reference_count--;
-	ROCKET_ASSERT(data_block->reference_count >= 0);
-	if (data_block->reference_count == 0) 
-	{
-		delete data_block;
-	}  
-	data_block = NULL;
-}
-
-Variant::DataBlock::DataBlock() 
-{
-	type = NONE;
-	reference_count = 1;
-	data_ptr = data;
-}
-
-Variant::DataBlock::~DataBlock() 
-{
-	Clear();
-}
-
-// Clear allocated
-void Variant::DataBlock::Clear() 
-{
-	// Should only clear when we have no references
-	ROCKET_ASSERT(reference_count == 0);
-
-	// Free any allocated types.
-	switch (type) 
-	{      
-		case STRING:
-		{
-			// Clean up the string.
-			String* string = (String*)data_ptr;
-			string->~String();
-		}
-		break;
-
-		default:
-		break;
-	}
-	type = NONE;
-	data_ptr = data;
-}
-
 }
 }
 }
 }