Browse Source

Fix defender decorator from being rendered in invader samples

Add warning message when decorators generate invalid data handles
Michael Ragazzon 1 year ago
parent
commit
144212b677

+ 1 - 0
Include/RmlUi/Core/Decorator.h

@@ -71,6 +71,7 @@ public:
 	virtual void RenderElement(Element* element, DecoratorDataHandle element_data) const = 0;
 	virtual void RenderElement(Element* element, DecoratorDataHandle element_data) const = 0;
 
 
 	/// Value specifying an invalid or non-existent Decorator data handle.
 	/// Value specifying an invalid or non-existent Decorator data handle.
+	/// @note This value will prevent the decorator from being rendered on the given element.
 	static const DecoratorDataHandle INVALID_DECORATORDATAHANDLE = 0;
 	static const DecoratorDataHandle INVALID_DECORATORDATAHANDLE = 0;
 
 
 protected:
 protected:

+ 1 - 1
Samples/invaders/data/high_score.rml

@@ -63,7 +63,7 @@
 					{{score.name}}
 					{{score.name}}
 				</td>
 				</td>
 				<td>
 				<td>
-					<defender data-style-color="score.colour"/>
+					<defender data-style-image-color="score.colour"/>
 				</td>
 				</td>
 				<td>
 				<td>
 					{{score.wave}}
 					{{score.wave}}

+ 32 - 16
Samples/invaders/src/DecoratorDefender.cpp

@@ -37,6 +37,11 @@
 #include <RmlUi/Core/Texture.h>
 #include <RmlUi/Core/Texture.h>
 #include <RmlUi/Core/Types.h>
 #include <RmlUi/Core/Types.h>
 
 
+struct DecoratorDefenderElementData {
+	Rml::Texture texture;
+	Rml::Geometry geometry;
+};
+
 DecoratorDefender::~DecoratorDefender() {}
 DecoratorDefender::~DecoratorDefender() {}
 
 
 bool DecoratorDefender::Initialise(const Rml::Texture& texture)
 bool DecoratorDefender::Initialise(const Rml::Texture& texture)
@@ -50,30 +55,41 @@ bool DecoratorDefender::Initialise(const Rml::Texture& texture)
 	return true;
 	return true;
 }
 }
 
 
-Rml::DecoratorDataHandle DecoratorDefender::GenerateElementData(Rml::Element* /*element*/, Rml::BoxArea /*paint_area*/) const
+Rml::DecoratorDataHandle DecoratorDefender::GenerateElementData(Rml::Element* element, Rml::BoxArea /*paint_area*/) const
 {
 {
-	return Rml::Decorator::INVALID_DECORATORDATAHANDLE;
-}
+	Rml::RenderManager* render_manager = element->GetRenderManager();
+	if (!render_manager)
+		return Rml::Decorator::INVALID_DECORATORDATAHANDLE;
 
 
-void DecoratorDefender::ReleaseElementData(Rml::DecoratorDataHandle /*element_data*/) const {}
-
-void DecoratorDefender::RenderElement(Rml::Element* element, Rml::DecoratorDataHandle /*element_data*/) const
-{
 	Rml::Vector2f position = element->GetAbsoluteOffset(Rml::BoxArea::Padding);
 	Rml::Vector2f position = element->GetAbsoluteOffset(Rml::BoxArea::Padding);
 	Rml::Vector2f size = element->GetBox().GetSize(Rml::BoxArea::Padding);
 	Rml::Vector2f size = element->GetBox().GetSize(Rml::BoxArea::Padding);
 	Rml::Math::SnapToPixelGrid(position, size);
 	Rml::Math::SnapToPixelGrid(position, size);
 
 
-	if (Rml::RenderManager* render_manager = element->GetRenderManager())
-	{
-		Rml::Texture texture = GetTexture(image_index);
-		Rml::ColourbPremultiplied color = element->GetProperty<Rml::Colourb>("color").ToPremultiplied();
+	Rml::ColourbPremultiplied color = element->GetProperty<Rml::Colourb>("image-color").ToPremultiplied();
+	Rml::Mesh mesh;
+	Rml::MeshUtilities::GenerateQuad(mesh, Rml::Vector2f(0.f), size, color);
 
 
-		Rml::Mesh mesh;
-		Rml::MeshUtilities::GenerateQuad(mesh, Rml::Vector2f(0.f), size, color);
+	DecoratorDefenderElementData* element_data = new DecoratorDefenderElementData{
+		GetTexture(image_index),
+		render_manager->MakeGeometry(std::move(mesh)),
+	};
 
 
-		Rml::Geometry geometry = render_manager->MakeGeometry(std::move(mesh));
-		geometry.Render(position, texture);
-	}
+	if (!element_data->texture || !element_data->geometry)
+		return Rml::Decorator::INVALID_DECORATORDATAHANDLE;
+
+	return reinterpret_cast<Rml::DecoratorDataHandle>(element_data);
+}
+
+void DecoratorDefender::ReleaseElementData(Rml::DecoratorDataHandle element_data_handle) const
+{
+	delete reinterpret_cast<DecoratorDefenderElementData*>(element_data_handle);
+}
+
+void DecoratorDefender::RenderElement(Rml::Element* element, Rml::DecoratorDataHandle element_data_handle) const
+{
+	Rml::Vector2f position = element->GetAbsoluteOffset(Rml::BoxArea::Padding).Round();
+	DecoratorDefenderElementData* element_data = reinterpret_cast<DecoratorDefenderElementData*>(element_data_handle);
+	element_data->geometry.Render(position, element_data->texture);
 }
 }
 
 
 DecoratorInstancerDefender::DecoratorInstancerDefender()
 DecoratorInstancerDefender::DecoratorInstancerDefender()

+ 1 - 1
Samples/luainvaders/data/high_score.rml

@@ -72,7 +72,7 @@ end
 					{{score.name}}
 					{{score.name}}
 				</td>
 				</td>
 				<td>
 				<td>
-					<defender data-style-color="score.colour"/>
+					<defender data-style-image-color="score.colour"/>
 				</td>
 				</td>
 				<td>
 				<td>
 					{{score.wave}}
 					{{score.wave}}

+ 33 - 17
Samples/luainvaders/src/DecoratorDefender.cpp

@@ -30,13 +30,18 @@
 #include <RmlUi/Core/Core.h>
 #include <RmlUi/Core/Core.h>
 #include <RmlUi/Core/Element.h>
 #include <RmlUi/Core/Element.h>
 #include <RmlUi/Core/Geometry.h>
 #include <RmlUi/Core/Geometry.h>
-#include <RmlUi/Core/MeshUtilities.h>
 #include <RmlUi/Core/Math.h>
 #include <RmlUi/Core/Math.h>
+#include <RmlUi/Core/MeshUtilities.h>
 #include <RmlUi/Core/PropertyDefinition.h>
 #include <RmlUi/Core/PropertyDefinition.h>
 #include <RmlUi/Core/RenderManager.h>
 #include <RmlUi/Core/RenderManager.h>
 #include <RmlUi/Core/Texture.h>
 #include <RmlUi/Core/Texture.h>
 #include <RmlUi/Core/Types.h>
 #include <RmlUi/Core/Types.h>
 
 
+struct DecoratorDefenderElementData {
+	Rml::Texture texture;
+	Rml::Geometry geometry;
+};
+
 DecoratorDefender::~DecoratorDefender() {}
 DecoratorDefender::~DecoratorDefender() {}
 
 
 bool DecoratorDefender::Initialise(const Rml::Texture& texture)
 bool DecoratorDefender::Initialise(const Rml::Texture& texture)
@@ -50,30 +55,41 @@ bool DecoratorDefender::Initialise(const Rml::Texture& texture)
 	return true;
 	return true;
 }
 }
 
 
-Rml::DecoratorDataHandle DecoratorDefender::GenerateElementData(Rml::Element* /*element*/, Rml::BoxArea /*paint_area*/) const
+Rml::DecoratorDataHandle DecoratorDefender::GenerateElementData(Rml::Element* element, Rml::BoxArea /*paint_area*/) const
 {
 {
-	return Rml::Decorator::INVALID_DECORATORDATAHANDLE;
-}
+	Rml::RenderManager* render_manager = element->GetRenderManager();
+	if (!render_manager)
+		return Rml::Decorator::INVALID_DECORATORDATAHANDLE;
 
 
-void DecoratorDefender::ReleaseElementData(Rml::DecoratorDataHandle /*element_data*/) const {}
-
-void DecoratorDefender::RenderElement(Rml::Element* element, Rml::DecoratorDataHandle /*element_data*/) const
-{
 	Rml::Vector2f position = element->GetAbsoluteOffset(Rml::BoxArea::Padding);
 	Rml::Vector2f position = element->GetAbsoluteOffset(Rml::BoxArea::Padding);
 	Rml::Vector2f size = element->GetBox().GetSize(Rml::BoxArea::Padding);
 	Rml::Vector2f size = element->GetBox().GetSize(Rml::BoxArea::Padding);
 	Rml::Math::SnapToPixelGrid(position, size);
 	Rml::Math::SnapToPixelGrid(position, size);
 
 
-	if (Rml::RenderManager* render_manager = element->GetRenderManager())
-	{
-		Rml::Texture texture = GetTexture(image_index);
-		Rml::ColourbPremultiplied color = element->GetProperty<Rml::Colourb>("color").ToPremultiplied();
+	Rml::ColourbPremultiplied color = element->GetProperty<Rml::Colourb>("image-color").ToPremultiplied();
+	Rml::Mesh mesh;
+	Rml::MeshUtilities::GenerateQuad(mesh, Rml::Vector2f(0.f), size, color);
 
 
-		Rml::Mesh mesh;
-		Rml::MeshUtilities::GenerateQuad(mesh, Rml::Vector2f(0.f), size, color);
+	DecoratorDefenderElementData* element_data = new DecoratorDefenderElementData{
+		GetTexture(image_index),
+		render_manager->MakeGeometry(std::move(mesh)),
+	};
 
 
-		Rml::Geometry geometry = render_manager->MakeGeometry(std::move(mesh));
-		geometry.Render(position, texture);
-	}
+	if (!element_data->texture || !element_data->geometry)
+		return Rml::Decorator::INVALID_DECORATORDATAHANDLE;
+
+	return reinterpret_cast<Rml::DecoratorDataHandle>(element_data);
+}
+
+void DecoratorDefender::ReleaseElementData(Rml::DecoratorDataHandle element_data_handle) const
+{
+	delete reinterpret_cast<DecoratorDefenderElementData*>(element_data_handle);
+}
+
+void DecoratorDefender::RenderElement(Rml::Element* element, Rml::DecoratorDataHandle element_data_handle) const
+{
+	Rml::Vector2f position = element->GetAbsoluteOffset(Rml::BoxArea::Padding).Round();
+	DecoratorDefenderElementData* element_data = reinterpret_cast<DecoratorDefenderElementData*>(element_data_handle);
+	element_data->geometry.Render(position, element_data->texture);
 }
 }
 
 
 DecoratorInstancerDefender::DecoratorInstancerDefender()
 DecoratorInstancerDefender::DecoratorInstancerDefender()

+ 3 - 0
Source/Core/ElementDecoration.cpp

@@ -165,6 +165,9 @@ void ElementDecoration::ReloadDecoratorsData()
 					decorator.decorator->ReleaseElementData(decorator.decorator_data);
 					decorator.decorator->ReleaseElementData(decorator.decorator_data);
 
 
 				decorator.decorator_data = decorator.decorator->GenerateElementData(element, decorator.paint_area);
 				decorator.decorator_data = decorator.decorator->GenerateElementData(element, decorator.paint_area);
+
+				if (!decorator.decorator_data)
+					Log::Message(Log::LT_WARNING, "Could not load decorator data on element: %s", element->GetAddress().c_str());
 			}
 			}
 		}
 		}