From 1f390f5a4d8c52a8b1c528d5166f8d831a4e6e15 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Wed, 9 Dec 2020 00:16:08 +0100 Subject: [PATCH] poking around the scenegraph pattern implemented with EnTT --- src/binding/src/script_scene.cpp | 5 +- src/scene/include/pw/scene/entity.hpp | 17 +++++- src/scene/src/entity.cpp | 74 +++++++++++++++++--------- src/scene/tests/pwscene_test_scene.cpp | 8 +++ src/scripts/demos/simple_001.lua | 9 ++++ 5 files changed, 86 insertions(+), 27 deletions(-) diff --git a/src/binding/src/script_scene.cpp b/src/binding/src/script_scene.cpp index a5448bb..261dc34 100644 --- a/src/binding/src/script_scene.cpp +++ b/src/binding/src/script_scene.cpp @@ -16,7 +16,10 @@ void register_scene_function(sol::state&,sol::table &ns) ns.new_usertype("entity", - sol::constructors()); + sol::constructors(), + "add_child",&entity::add_child, + "child_count",sol::readonly_property(&entity::child_count) + ); ns.new_usertype("node", diff --git a/src/scene/include/pw/scene/entity.hpp b/src/scene/include/pw/scene/entity.hpp index fc02ba1..50cb9af 100644 --- a/src/scene/include/pw/scene/entity.hpp +++ b/src/scene/include/pw/scene/entity.hpp @@ -54,12 +54,17 @@ public: } template - T& get_component() { + T& get_component() const { return _registry->get(_entity); } + template + T& get_or_create_component(Args&&... args) { + return _registry->get_or_emplace(this->_entity,std::forward(args)...); + } + template - bool has_component(){ return _registry->valid(_entity);} + bool has_component() const { return _registry->valid(_entity);} void destroy(); @@ -69,6 +74,14 @@ public: bool valid() const { return _registry->valid(_entity); } + + void add_child(entity &child); + + void remove_child(entity &child); + + size_t child_count() const; + + private: std::shared_ptr _registry; diff --git a/src/scene/src/entity.cpp b/src/scene/src/entity.cpp index 771d1f8..bf03ddd 100644 --- a/src/scene/src/entity.cpp +++ b/src/scene/src/entity.cpp @@ -1,42 +1,68 @@ #include "pw/scene/entity.hpp" #include "pw/scene/scene.hpp" -namespace pw { +#include "pw/core/debug.hpp" -namespace test { +namespace pw { struct relationship { std::vector children; entt::entity parent { entt::null }; - - static void add_child(entt::registry& r,entt::entity p,entt::entity c) - { -// auto child_rels = r.view(c); - // remove potential parents - - - - } }; - -void testbed() -{ - using namespace entt; - - registry r; - - auto e = r.create(); -} - -} - entity::entity(scene &s) : _registry(s._registry) - , _entity(s._registry->create()) + , _entity(s._registry ? _registry->create() : entt::null) { } +void entity::add_child(entity& child) +{ + if (child._registry != this->_registry) { + debug::e() << "Cannot mix entities from different scenes"; + return; + } + + // TODO: check circular dependencies + + // declare child relationship + auto r = get_or_create_component(); + r.children.push_back(child._entity); + + // declare parent + auto p_r = child.get_or_create_component(); + p_r.parent = _entity; +} + +void entity::remove_child(entity& child) +{ + if (child._registry != this->_registry) { + debug::e() << "Cannot mix entities from different scenes"; + return; + } + + // both need to have a relationship component + if (has_component() && child.has_component()) + { + // we need to check if the child is related to the parent + auto r_p = child.get_component(); + if (r_p.parent == _entity) + { + // now go ahead + r_p.parent = entt::null; + + auto r = get_component(); + std::remove(r.children.begin(),r.children.end(),child._entity); + + } + } +} + +size_t entity::child_count() const +{ + return has_component() ? get_component().children.size() : 0; +} + entity::~entity() { this->destroy(); diff --git a/src/scene/tests/pwscene_test_scene.cpp b/src/scene/tests/pwscene_test_scene.cpp index aad9aa9..14a3275 100644 --- a/src/scene/tests/pwscene_test_scene.cpp +++ b/src/scene/tests/pwscene_test_scene.cpp @@ -29,6 +29,14 @@ void test_stack() std::cout << t.val << std::endl; + + auto e2 = entity(s); + + e.add_child(e2); + + std::cout << e.child_count() << std::endl; + + } void test_heap() diff --git a/src/scripts/demos/simple_001.lua b/src/scripts/demos/simple_001.lua index e6e5993..34931a4 100644 --- a/src/scripts/demos/simple_001.lua +++ b/src/scripts/demos/simple_001.lua @@ -9,4 +9,13 @@ print("hello pixwerx!") local s = pw.scene.new() +local e = pw.entity.new(s) + +local e2 = pw.entity.new(s) + +e.add_child(e2) + +print(s) +print(e.child_count) +