world holds entity instances now

This commit is contained in:
2019-05-13 20:15:50 +07:00
parent 2eff98b639
commit 6ae2009430
5 changed files with 57 additions and 33 deletions

View File

@@ -13,23 +13,41 @@ namespace e2d
class gobject;
using gobject_iptr = intrusive_ptr<gobject>;
using const_gobject_iptr = intrusive_ptr<const gobject>;
class world_gobjects_ilist_tag;
using world_gobjects = intrusive_list<gobject, world_gobjects_ilist_tag>;
}
namespace e2d
{
class gobject final
: private noncopyable
, public ref_counter<gobject>
, public intrusive_list_hook<world_gobjects_ilist_tag> {
, public ref_counter<gobject> {
public:
gobject(ecs::registry& registry);
gobject(ecs::registry& registry, const gobject& source);
gobject(ecs::registry& registry, const ecs::prototype& proto);
~gobject() noexcept;
ecs::entity entity() noexcept;
ecs::const_entity entity() const noexcept;
ecs::entity_filler entity_filler() noexcept;
template < typename T >
ecs::component<T> get_component() noexcept;
template < typename T >
ecs::const_component<T> get_component() const noexcept;
private:
ecs::entity entity_;
};
}
namespace e2d
{
template < typename T >
ecs::component<T> gobject::get_component() noexcept {
return ecs::component<T>(entity_);
}
template < typename T >
ecs::const_component<T> gobject::get_component() const noexcept {
return ecs::const_component<T>(entity_);
}
}

View File

@@ -197,7 +197,7 @@ namespace e2d
inline asset_group& asset_group::add_asset(str_view address, const asset_ptr& asset) {
str main_address = address::parent(address);
auto iter = std::upper_bound(
const auto iter = std::upper_bound(
assets_.begin(), assets_.end(), main_address,
[](const str& l, const auto& r){
return l < r.first;

View File

@@ -8,8 +8,8 @@
#include "_high.hpp"
#include "prefab.hpp"
#include "gobject.hpp"
#include "assets/prefab_asset.hpp"
namespace e2d
{
@@ -29,17 +29,17 @@ namespace e2d
priority_render_section_end = 4500
};
public:
world();
world() = default;
~world() noexcept final;
ecs::registry& registry() noexcept;
const ecs::registry& registry() const noexcept;
gobject_iptr instantiate();
gobject_iptr instantiate(const prefab_asset::ptr& prefab);
gobject_iptr instantiate(const const_gobject_iptr& gobject);
gobject_iptr instantiate(const prefab& prefab);
void destroy_instance(const gobject_iptr& inst) noexcept;
private:
ecs::registry registry_;
world_gobjects gobjects_;
hash_map<ecs::entity_id, gobject_iptr> gobjects_;
};
}

View File

@@ -11,13 +11,22 @@ namespace e2d
gobject::gobject(ecs::registry& registry)
: entity_(registry.create_entity()) {}
gobject::gobject(ecs::registry& registry, const gobject& source)
: entity_(registry.create_entity(source.entity_)) {}
gobject::gobject(ecs::registry& registry, const ecs::prototype& proto)
: entity_(registry.create_entity(proto)) {}
gobject::~gobject() noexcept {
entity_.destroy();
}
ecs::entity gobject::entity() noexcept {
return entity_;
}
ecs::const_entity gobject::entity() const noexcept {
return entity_;
}
ecs::entity_filler gobject::entity_filler() noexcept {
return ecs::entity_filler(entity_);
}
}

View File

@@ -8,8 +8,11 @@
namespace e2d
{
world::world() = default;
world::~world() noexcept = default;
world::~world() noexcept {
while ( !gobjects_.empty() ) {
destroy_instance(gobjects_.begin()->second);
}
}
ecs::registry& world::registry() noexcept {
return registry_;
@@ -20,27 +23,21 @@ namespace e2d
}
gobject_iptr world::instantiate() {
auto instance = gobject_iptr(new gobject(registry_));
intrusive_ptr_add_ref(instance.get());
gobjects_.push_back(*instance);
auto instance = make_intrusive<gobject>(registry_);
gobjects_.emplace(instance->entity().id(), instance);
return instance;
}
gobject_iptr world::instantiate(const prefab_asset::ptr& prefab) {
auto instance = prefab
? gobject_iptr(new gobject(registry_, prefab->content().prototype()))
: gobject_iptr(new gobject(registry_));
intrusive_ptr_add_ref(instance.get());
gobjects_.push_back(*instance);
gobject_iptr world::instantiate(const prefab& prefab) {
auto instance = make_intrusive<gobject>(registry_, prefab.prototype());
gobjects_.emplace(instance->entity().id(), instance);
return instance;
}
gobject_iptr world::instantiate(const const_gobject_iptr& source) {
auto instance = source
? gobject_iptr(new gobject(registry_, *source))
: gobject_iptr(new gobject(registry_));
intrusive_ptr_add_ref(instance.get());
gobjects_.push_back(*instance);
return instance;
void world::destroy_instance(const gobject_iptr& inst) noexcept {
if ( inst ) {
inst->entity().remove_all_components();
gobjects_.erase(inst->entity().id());
}
}
}