lazy layout update

This commit is contained in:
BlackMATov
2020-02-07 11:53:34 +07:00
parent 1d3a00b15d
commit 4eb215353f
8 changed files with 134 additions and 15 deletions

View File

@@ -11,6 +11,8 @@
namespace e2d
{
class layout final {
public:
class dirty final {};
public:
ENUM_HPP_CLASS_DECL(modes, u8,
(horizontal)
@@ -77,6 +79,20 @@ namespace e2d
const collect_context& ctx) const;
};
template <>
class factory_loader<layout::dirty> final : factory_loader<> {
public:
static const char* schema_source;
bool operator()(
layout::dirty& component,
const fill_context& ctx) const;
bool operator()(
asset_dependencies& dependencies,
const collect_context& ctx) const;
};
template <>
class factory_loader<layout_item> final : factory_loader<> {
public:

View File

@@ -0,0 +1,9 @@
{
"components" : {
"named" : {
"name" : "layout"
},
"layout" : {},
"layout.dirty" : {}
}
}

View File

@@ -5,12 +5,7 @@
},{
"prototype" : "../prefabs/camera_prefab.json"
},{
"components" : {
"named" : {
"name" : "layout"
},
"layout" : {}
},
"prototype" : "../prefabs/layout_prefab.json",
"children" : [{
"components" : {
"named" : {

View File

@@ -12,6 +12,9 @@ local layout = {
---@type boolean
disabled = false,
---@type boolean
dirty = false,
---@type layout_modes
mode = layout.modes.horizontal,

View File

@@ -7,9 +7,24 @@
#include "../_high_binds.hpp"
#include <enduro2d/high/gobject.hpp>
#include <enduro2d/high/components/actor.hpp>
#include <enduro2d/high/components/disabled.hpp>
#include <enduro2d/high/components/layout.hpp>
namespace
{
using namespace e2d;
void mark_dirty_parent_layout(const const_gcomponent<layout_item>& item) {
if ( gcomponent<actor> item_actor = item.owner().component<actor>() ) {
gcomponent<layout> parent_layout = nodes::find_component_from_parents<layout>(item_actor->node());
if ( parent_layout ) {
parent_layout.owner().component<layout::dirty>().ensure();
}
}
}
}
namespace e2d::bindings::high
{
void bind_layout(sol::state& l) {
@@ -18,10 +33,12 @@ namespace e2d::bindings::high
"enable", [](gcomponent<layout>& c){
c.owner().component<disabled<layout>>().remove();
c.owner().component<layout::dirty>().ensure();
},
"disable", [](gcomponent<layout>& c){
c.owner().component<disabled<layout>>().ensure();
c.owner().component<layout::dirty>().ensure();
},
"enabled", sol::property(
@@ -34,6 +51,7 @@ namespace e2d::bindings::high
} else {
c.owner().component<disabled<layout>>().ensure();
}
c.owner().component<layout::dirty>().ensure();
}
),
@@ -47,6 +65,20 @@ namespace e2d::bindings::high
} else {
c.owner().component<disabled<layout>>().remove();
}
c.owner().component<layout::dirty>().ensure();
}
),
"dirty", sol::property(
[](const gcomponent<layout>& c) -> bool {
return c.owner().component<layout::dirty>().exists();
},
[](gcomponent<layout>& c, bool yesno){
if ( yesno ) {
c.owner().component<layout::dirty>().ensure();
} else {
c.owner().component<layout::dirty>().remove();
}
}
),
@@ -56,6 +88,7 @@ namespace e2d::bindings::high
},
[](gcomponent<layout>& c, layout::modes v){
c->mode(v);
c.owner().component<layout::dirty>().ensure();
}),
"halign", sol::property(
@@ -64,6 +97,7 @@ namespace e2d::bindings::high
},
[](gcomponent<layout>& c, layout::haligns v){
c->halign(v);
c.owner().component<layout::dirty>().ensure();
}),
"valign", sol::property(
@@ -72,6 +106,7 @@ namespace e2d::bindings::high
},
[](gcomponent<layout>& c, layout::valigns v){
c->valign(v);
c.owner().component<layout::dirty>().ensure();
}),
"spacing", sol::property(
@@ -80,6 +115,7 @@ namespace e2d::bindings::high
},
[](gcomponent<layout>& c, f32 v){
c->spacing(v);
c.owner().component<layout::dirty>().ensure();
})
);
@@ -114,10 +150,12 @@ namespace e2d::bindings::high
"enable", [](gcomponent<layout_item>& c){
c.owner().component<disabled<layout_item>>().remove();
mark_dirty_parent_layout(c);
},
"disable", [](gcomponent<layout_item>& c){
c.owner().component<disabled<layout_item>>().ensure();
mark_dirty_parent_layout(c);
},
"enabled", sol::property(
@@ -130,6 +168,7 @@ namespace e2d::bindings::high
} else {
c.owner().component<disabled<layout_item>>().ensure();
}
mark_dirty_parent_layout(c);
}
),
@@ -143,6 +182,7 @@ namespace e2d::bindings::high
} else {
c.owner().component<disabled<layout_item>>().remove();
}
mark_dirty_parent_layout(c);
}
),
@@ -152,6 +192,7 @@ namespace e2d::bindings::high
},
[](gcomponent<layout_item>& c, const v2f& v){
c->size(v);
mark_dirty_parent_layout(c);
})
);
}

View File

@@ -6,6 +6,22 @@
#include <enduro2d/high/components/layout.hpp>
#include <enduro2d/high/components/actor.hpp>
namespace
{
using namespace e2d;
void mark_dirty_parent_layout(const const_gcomponent<layout_item>& item) {
if ( gcomponent<actor> item_actor = item.owner().component<actor>() ) {
gcomponent<layout> parent_layout = nodes::find_component_from_parents<layout>(item_actor->node());
if ( parent_layout ) {
parent_layout.owner().component<layout::dirty>().ensure();
}
}
}
}
namespace e2d
{
const char* factory_loader<layout>::schema_source = R"json({
@@ -97,6 +113,32 @@ namespace e2d
}
}
namespace e2d
{
const char* factory_loader<layout::dirty>::schema_source = R"json({
"type" : "object",
"required" : [],
"additionalProperties" : false,
"properties" : {}
})json";
bool factory_loader<layout::dirty>::operator()(
layout::dirty& component,
const fill_context& ctx) const
{
E2D_UNUSED(component, ctx);
return true;
}
bool factory_loader<layout::dirty>::operator()(
asset_dependencies& dependencies,
const collect_context& ctx) const
{
E2D_UNUSED(dependencies, ctx);
return true;
}
}
namespace e2d
{
const char* factory_loader<layout_item>::schema_source = R"json({
@@ -142,24 +184,28 @@ namespace e2d
imgui_utils::show_enum_combo_box("mode", &mode) )
{
c->mode(mode);
c.owner().component<layout::dirty>().ensure();
}
if ( layout::haligns halign = c->halign();
imgui_utils::show_enum_combo_box("halign", &halign) )
{
c->halign(halign);
c.owner().component<layout::dirty>().ensure();
}
if ( layout::valigns valign = c->valign();
imgui_utils::show_enum_combo_box("valign", &valign) )
{
c->valign(valign);
c.owner().component<layout::dirty>().ensure();
}
if ( f32 spacing = c->spacing();
ImGui::DragFloat("spacing", &spacing, 1.f) )
{
c->spacing(spacing);
c.owner().component<layout::dirty>().ensure();
}
}
}
@@ -173,6 +219,7 @@ namespace e2d
ImGui::DragFloat2("size", size.data(), 1.f) )
{
c->size(size);
mark_dirty_parent_layout(c);
}
}

View File

@@ -198,6 +198,7 @@ namespace e2d
.register_component<label>("label")
.register_component<label::dirty>("label.dirty")
.register_component<layout>("layout")
.register_component<layout::dirty>("layout.dirty")
.register_component<layout_item>("layout_item")
.register_component<model_renderer>("model_renderer")
.register_component<named>("named")
@@ -224,6 +225,7 @@ namespace e2d
.register_component<label>("label")
//.register_component<label::dirty>("label.dirty")
.register_component<layout>("layout")
//.register_component<layout::dirty>("layout.dirty")
.register_component<layout_item>("layout_item")
.register_component<model_renderer>("model_renderer")
.register_component<named>("named")

View File

@@ -139,6 +139,20 @@ namespace
item_cursor += (item->size() + layout.spacing()) * cursor_offset_mul;
}
}
void update_dirty_layouts(ecs::registry& owner) {
owner.for_joined_components<layout::dirty, layout, actor>([](
const ecs::const_entity&,
const layout::dirty&,
const layout& layout,
const actor& layout_actor)
{
update_layout_items(layout, layout_actor.node());
}, !ecs::exists_any<
disabled<actor>,
disabled<layout>>());
owner.remove_all_components<layout::dirty>();
}
}
namespace e2d
@@ -153,15 +167,7 @@ namespace e2d
~internal_state() noexcept = default;
void process_update(ecs::registry& owner) {
owner.for_joined_components<layout, actor>([](
const ecs::const_entity&,
const layout& layout,
const actor& layout_actor)
{
update_layout_items(layout, layout_actor.node());
}, !ecs::exists_any<
disabled<actor>,
disabled<layout>>());
update_dirty_layouts(owner);
}
};