mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-15 00:11:55 +07:00
lazy layout update
This commit is contained in:
@@ -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:
|
||||
|
||||
9
samples/bin/library/prefabs/layout_prefab.json
Normal file
9
samples/bin/library/prefabs/layout_prefab.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "layout"
|
||||
},
|
||||
"layout" : {},
|
||||
"layout.dirty" : {}
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,7 @@
|
||||
},{
|
||||
"prototype" : "../prefabs/camera_prefab.json"
|
||||
},{
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "layout"
|
||||
},
|
||||
"layout" : {}
|
||||
},
|
||||
"prototype" : "../prefabs/layout_prefab.json",
|
||||
"children" : [{
|
||||
"components" : {
|
||||
"named" : {
|
||||
|
||||
@@ -12,6 +12,9 @@ local layout = {
|
||||
---@type boolean
|
||||
disabled = false,
|
||||
|
||||
---@type boolean
|
||||
dirty = false,
|
||||
|
||||
---@type layout_modes
|
||||
mode = layout.modes.horizontal,
|
||||
|
||||
|
||||
@@ -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);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user