Skip to content

Commit

Permalink
Fix defender decorator from being rendered in invader samples
Browse files Browse the repository at this point in the history
Add warning message when decorators generate invalid data handles
  • Loading branch information
mikke89 committed Feb 3, 2024
1 parent f0654d1 commit 8f5f8d7
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 35 deletions.
1 change: 1 addition & 0 deletions Include/RmlUi/Core/Decorator.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class RMLUICORE_API Decorator {
virtual void RenderElement(Element* element, DecoratorDataHandle element_data) const = 0;

/// 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;

protected:
Expand Down
2 changes: 1 addition & 1 deletion Samples/invaders/data/high_score.rml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
{{score.name}}
</td>
<td>
<defender data-style-color="score.colour"/>
<defender data-style-image-color="score.colour"/>
</td>
<td>
{{score.wave}}
Expand Down
48 changes: 32 additions & 16 deletions Samples/invaders/src/DecoratorDefender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
#include <RmlUi/Core/Texture.h>
#include <RmlUi/Core/Types.h>

struct DecoratorDefenderElementData {
Rml::Texture texture;
Rml::Geometry geometry;
};

DecoratorDefender::~DecoratorDefender() {}

bool DecoratorDefender::Initialise(const Rml::Texture& texture)
Expand All @@ -50,30 +55,41 @@ bool DecoratorDefender::Initialise(const Rml::Texture& texture)
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 size = element->GetBox().GetSize(Rml::BoxArea::Padding);
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()
Expand Down
2 changes: 1 addition & 1 deletion Samples/luainvaders/data/high_score.rml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ end
{{score.name}}
</td>
<td>
<defender data-style-color="score.colour"/>
<defender data-style-image-color="score.colour"/>
</td>
<td>
{{score.wave}}
Expand Down
50 changes: 33 additions & 17 deletions Samples/luainvaders/src/DecoratorDefender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,18 @@
#include <RmlUi/Core/Core.h>
#include <RmlUi/Core/Element.h>
#include <RmlUi/Core/Geometry.h>
#include <RmlUi/Core/MeshUtilities.h>
#include <RmlUi/Core/Math.h>
#include <RmlUi/Core/MeshUtilities.h>
#include <RmlUi/Core/PropertyDefinition.h>
#include <RmlUi/Core/RenderManager.h>
#include <RmlUi/Core/Texture.h>
#include <RmlUi/Core/Types.h>

struct DecoratorDefenderElementData {
Rml::Texture texture;
Rml::Geometry geometry;
};

DecoratorDefender::~DecoratorDefender() {}

bool DecoratorDefender::Initialise(const Rml::Texture& texture)
Expand All @@ -50,30 +55,41 @@ bool DecoratorDefender::Initialise(const Rml::Texture& texture)
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 size = element->GetBox().GetSize(Rml::BoxArea::Padding);
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()
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/ElementDecoration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ void ElementDecoration::ReloadDecoratorsData()
decorator.decorator->ReleaseElementData(decorator.decorator_data);

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());
}
}

Expand Down

0 comments on commit 8f5f8d7

Please sign in to comment.