poking around the scenegraph pattern implemented with EnTT
This commit is contained in:
parent
cea83d06e8
commit
1f390f5a4d
5 changed files with 86 additions and 27 deletions
|
@ -16,7 +16,10 @@ void register_scene_function(sol::state&,sol::table &ns)
|
||||||
|
|
||||||
|
|
||||||
ns.new_usertype<entity>("entity",
|
ns.new_usertype<entity>("entity",
|
||||||
sol::constructors<entity>());
|
sol::constructors<entity(),entity(scene&)>(),
|
||||||
|
"add_child",&entity::add_child,
|
||||||
|
"child_count",sol::readonly_property(&entity::child_count)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
ns.new_usertype<node>("node",
|
ns.new_usertype<node>("node",
|
||||||
|
|
|
@ -54,12 +54,17 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T& get_component() {
|
T& get_component() const {
|
||||||
return _registry->get<T>(_entity);
|
return _registry->get<T>(_entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T,typename... Args>
|
||||||
|
T& get_or_create_component(Args&&... args) {
|
||||||
|
return _registry->get_or_emplace<T>(this->_entity,std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool has_component(){ return _registry->valid(_entity);}
|
bool has_component() const { return _registry->valid(_entity);}
|
||||||
|
|
||||||
void destroy();
|
void destroy();
|
||||||
|
|
||||||
|
@ -69,6 +74,14 @@ public:
|
||||||
|
|
||||||
bool valid() const { return _registry->valid(_entity); }
|
bool valid() const { return _registry->valid(_entity); }
|
||||||
|
|
||||||
|
|
||||||
|
void add_child(entity &child);
|
||||||
|
|
||||||
|
void remove_child(entity &child);
|
||||||
|
|
||||||
|
size_t child_count() const;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<entt::registry> _registry;
|
std::shared_ptr<entt::registry> _registry;
|
||||||
|
|
|
@ -1,42 +1,68 @@
|
||||||
#include "pw/scene/entity.hpp"
|
#include "pw/scene/entity.hpp"
|
||||||
#include "pw/scene/scene.hpp"
|
#include "pw/scene/scene.hpp"
|
||||||
|
|
||||||
namespace pw {
|
#include "pw/core/debug.hpp"
|
||||||
|
|
||||||
namespace test {
|
namespace pw {
|
||||||
|
|
||||||
struct relationship {
|
struct relationship {
|
||||||
std::vector<entt::entity> children;
|
std::vector<entt::entity> children;
|
||||||
entt::entity parent { entt::null };
|
entt::entity parent { entt::null };
|
||||||
|
|
||||||
static void add_child(entt::registry& r,entt::entity p,entt::entity c)
|
|
||||||
{
|
|
||||||
// auto child_rels = r.view<relationship>(c);
|
|
||||||
// remove potential parents
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void testbed()
|
|
||||||
{
|
|
||||||
using namespace entt;
|
|
||||||
|
|
||||||
registry r;
|
|
||||||
|
|
||||||
auto e = r.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
entity::entity(scene &s)
|
entity::entity(scene &s)
|
||||||
: _registry(s._registry)
|
: _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<relationship>();
|
||||||
|
r.children.push_back(child._entity);
|
||||||
|
|
||||||
|
// declare parent
|
||||||
|
auto p_r = child.get_or_create_component<relationship>();
|
||||||
|
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<relationship>() && child.has_component<relationship>())
|
||||||
|
{
|
||||||
|
// we need to check if the child is related to the parent
|
||||||
|
auto r_p = child.get_component<relationship>();
|
||||||
|
if (r_p.parent == _entity)
|
||||||
|
{
|
||||||
|
// now go ahead
|
||||||
|
r_p.parent = entt::null;
|
||||||
|
|
||||||
|
auto r = get_component<relationship>();
|
||||||
|
std::remove(r.children.begin(),r.children.end(),child._entity);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t entity::child_count() const
|
||||||
|
{
|
||||||
|
return has_component<relationship>() ? get_component<relationship>().children.size() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
entity::~entity()
|
entity::~entity()
|
||||||
{
|
{
|
||||||
this->destroy();
|
this->destroy();
|
||||||
|
|
|
@ -29,6 +29,14 @@ void test_stack()
|
||||||
|
|
||||||
std::cout << t.val << std::endl;
|
std::cout << t.val << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
auto e2 = entity(s);
|
||||||
|
|
||||||
|
e.add_child(e2);
|
||||||
|
|
||||||
|
std::cout << e.child_count() << std::endl;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_heap()
|
void test_heap()
|
||||||
|
|
|
@ -9,4 +9,13 @@ print("hello pixwerx!")
|
||||||
|
|
||||||
local s = pw.scene.new()
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue