Browse Source

Variant: Fix an issue where the current type's destructor may not be called.

Michael Ragazzon 6 years ago
parent
commit
27dd812581

+ 11 - 12
Include/RmlUi/Core/Variant.h

@@ -89,16 +89,6 @@ public:
 	/// Gets the current internal representation type.
 	/// Gets the current internal representation type.
 	/// @return The type of data stored in the variant internally.
 	/// @return The type of data stored in the variant internally.
 	inline Type GetType() const;
 	inline Type GetType() const;
-
-	/// Shares another variant's data with this variant.
-	/// @param[in] copy Variant to share data.
-	void Set(const Variant& copy);
-
-	/// Clear and set a new value to this variant.
-	/// @param[in] t New value to set.
-	template<typename T>
-	void Reset(const T& t);
-
 	/// Templatised data accessor. TypeConverters will be used to attempt to convert from the
 	/// Templatised data accessor. TypeConverters will be used to attempt to convert from the
 	/// internal representation to the requested representation.
 	/// internal representation to the requested representation.
 	/// @param[in] default_value The value returned if the conversion failed.
 	/// @param[in] default_value The value returned if the conversion failed.
@@ -113,15 +103,24 @@ public:
 	template< typename T >
 	template< typename T >
 	bool GetInto(T& value) const;
 	bool GetInto(T& value) const;
 
 
-	/// Assigns another variant's internal data to this variant.
-	/// @param[in] copy Variant to share data.
+	/// Copy another variant.
+	/// @param[in] copy Variant to copy.
 	Variant& operator=(const Variant& copy);
 	Variant& operator=(const Variant& copy);
 
 
+	/// Clear and set a new value to this variant.
+	/// @param[in] t New value to set.
+	template<typename T>
+	Variant& operator=(const T& t);
+
 	bool operator==(const Variant& other) const;
 	bool operator==(const Variant& other) const;
 	bool operator!=(const Variant& other) const { return !(*this == other); }
 	bool operator!=(const Variant& other) const { return !(*this == other); }
 
 
 private:
 private:
 
 
+	/// Copy another variant's data to this variant.
+	/// @warning Does not clear existing data.
+	void Set(const Variant& copy);
+
 	void Set(const byte value);
 	void Set(const byte value);
 	void Set(const char value);
 	void Set(const char value);
 	void Set(const float value);
 	void Set(const float value);

+ 2 - 1
Include/RmlUi/Core/Variant.inl

@@ -43,10 +43,11 @@ Variant::Variant(const T& t) : type(NONE)
 
 
 // Clear and set new value
 // Clear and set new value
 template< typename T >
 template< typename T >
-void Variant::Reset(const T& t)
+Variant& Variant::operator=(const T& t)
 {
 {
 	Clear();
 	Clear();
 	Set(t);
 	Set(t);
+	return *this;
 }
 }
 
 
 // Templatised data accessor.
 // Templatised data accessor.

+ 1 - 1
Source/Controls/ElementForm.cpp

@@ -82,7 +82,7 @@ void ElementForm::Submit(const Rml::Core::String& name, const Rml::Core::String&
 		// If the item already exists, append to it.
 		// If the item already exists, append to it.
 		Rml::Core::Variant* value = GetIf(values, control_name);
 		Rml::Core::Variant* value = GetIf(values, control_name);
 		if (value != NULL)
 		if (value != NULL)
-			value->Reset(value->Get< Rml::Core::String >() + ", " + control_value);
+			*value = value->Get< Rml::Core::String >() + ", " + control_value;
 		else
 		else
 			values[control_name] = control_value;
 			values[control_name] = control_value;
 	}
 	}

+ 1 - 1
Source/Core/ElementAnimation.cpp

@@ -374,7 +374,7 @@ bool ElementAnimation::InternalAddKey(float time, const Property& property, Twee
 	if (key.property.unit == Property::TRANSFORM)
 	if (key.property.unit == Property::TRANSFORM)
 	{
 	{
 		if (!key.property.value.Get<TransformRef>())
 		if (!key.property.value.Get<TransformRef>())
-			key.property.value.Reset(TransformRef(new Transform));
+			key.property.value = std::make_shared<Transform>();
 	}
 	}
 
 
 	return true;
 	return true;

+ 2 - 2
Source/Core/Event.cpp

@@ -164,8 +164,8 @@ void Event::ProjectMouse(Element* element)
 		}
 		}
 
 
 		Vector2f new_pos = element->Project(mouse_screen_position);
 		Vector2f new_pos = element->Project(mouse_screen_position);
-		mouse_x->Reset(new_pos.x);
-		mouse_y->Reset(new_pos.y);
+		*mouse_x = new_pos.x;
+		*mouse_y = new_pos.y;
 	}
 	}
 }
 }
 
 

+ 1 - 1
Source/Core/PropertyDefinition.cpp

@@ -81,7 +81,7 @@ PropertyDefinition& PropertyDefinition::AddParser(const String& parser_name, con
 		}
 		}
 		else
 		else
 		{
 		{
-			default_value.value.Reset(unparsed_value);
+			default_value.value = unparsed_value;
 			default_value.unit = Property::UNKNOWN;
 			default_value.unit = Property::UNKNOWN;
 		}
 		}
 	}
 	}

+ 1 - 1
Source/Core/StyleSheetNode.cpp

@@ -197,7 +197,7 @@ void StyleSheetNode::BuildIndexAndOptimizeProperties(StyleSheet::NodeIndex& styl
 				DecoratorList decorator_list = style_sheet.InstanceDecoratorsFromString(string_value, property->source, property->source_line_number);
 				DecoratorList decorator_list = style_sheet.InstanceDecoratorsFromString(string_value, property->source, property->source_line_number);
 
 
 				Property new_property = *property;
 				Property new_property = *property;
-				new_property.value.Reset(std::move(decorator_list));
+				new_property.value = std::move(decorator_list);
 				new_property.unit = Property::DECORATOR;
 				new_property.unit = Property::DECORATOR;
 				properties.SetProperty(PropertyId::Decorator, new_property);
 				properties.SetProperty(PropertyId::Decorator, new_property);
 			}
 			}

+ 2 - 1
Source/Core/Variant.cpp

@@ -132,7 +132,6 @@ void Variant::Set(const Variant& copy)
 		break;
 		break;
 
 
 	default:
 	default:
-		Clear();
 		memcpy(data, copy.data, LOCAL_DATA_SIZE);
 		memcpy(data, copy.data, LOCAL_DATA_SIZE);
 		break;
 		break;
 	}
 	}
@@ -282,6 +281,8 @@ void Variant::Set(ScriptInterface* value)
 
 
 Variant& Variant::operator=(const Variant& copy)
 Variant& Variant::operator=(const Variant& copy)
 {
 {
+	if (copy.type != type)
+		Clear();
 	Set(copy);
 	Set(copy);
 	return *this;
 	return *this;
 }
 }