registry::create_entity from prototype

This commit is contained in:
2019-04-12 04:22:02 +07:00
parent b7bbd986a0
commit 73896bdd24
2 changed files with 59 additions and 42 deletions

70
ecs.hpp
View File

@@ -37,9 +37,14 @@ namespace ecs_hpp
template < typename T >
class const_component;
class prototype;
class system;
class registry;
class entity_filler;
class registry_filler;
using family_id = std::uint16_t;
using entity_id = std::uint32_t;
using priority_t = std::int32_t;
@@ -427,8 +432,12 @@ namespace ecs_hpp
std::vector<std::size_t> sparse_;
};
template < typename T, typename Indexer >
void swap(sparse_set<T,Indexer>& l, sparse_set<T,Indexer>& r) noexcept {
template < typename T
, typename Indexer >
void swap(
sparse_set<T, Indexer>& l,
sparse_set<T, Indexer>& r) noexcept
{
l.swap(r);
}
}
@@ -591,8 +600,13 @@ namespace ecs_hpp
std::vector<T> values_;
};
template < typename K, typename T, typename Indexer >
void swap(sparse_map<K,T,Indexer>& l, sparse_map<K,T,Indexer>& r) noexcept {
template < typename K
, typename T
, typename Indexer >
void swap(
sparse_map<K, T, Indexer>& l,
sparse_map<K, T, Indexer>& r) noexcept
{
l.swap(r);
}
}
@@ -752,7 +766,7 @@ namespace ecs_hpp
entity_id id() const noexcept;
entity clone() const;
bool destroy() noexcept;
void destroy() noexcept;
bool valid() const noexcept;
template < typename T, typename... Args >
@@ -1055,14 +1069,13 @@ namespace ecs_hpp
template < typename T, typename... Args >
prototype& assign_component(Args&&... args) &;
template < typename T, typename... Args >
prototype&& assign_component(Args&&... args) &&;
prototype& merge(const prototype& other, bool override) &;
prototype&& merge(const prototype& other, bool override) &&;
entity create_entity(registry& owner) const;
void apply(entity& ent, bool override) const;
private:
detail::sparse_map<
family_id,
@@ -1157,9 +1170,10 @@ namespace ecs_hpp
const_component<T> wrap_component(const const_uentity& ent) const noexcept;
entity create_entity();
entity create_entity(const const_uentity& prototype);
entity create_entity(const prototype& proto);
entity create_entity(const const_uentity& proto);
bool destroy_entity(const uentity& ent) noexcept;
void destroy_entity(const uentity& ent) noexcept;
bool valid_entity(const const_uentity& ent) const noexcept;
template < typename T, typename... Args >
@@ -1366,8 +1380,8 @@ namespace ecs_hpp
return (*owner_).create_entity(id_);
}
inline bool entity::destroy() noexcept {
return (*owner_).destroy_entity(id_);
inline void entity::destroy() noexcept {
(*owner_).destroy_entity(id_);
}
inline bool entity::valid() const noexcept {
@@ -1799,17 +1813,10 @@ namespace ecs_hpp
return std::move(*this);
}
inline entity prototype::create_entity(registry& owner) const {
auto ent = owner.create_entity();
try {
for ( const auto family_id : appliers_ ) {
appliers_.get(family_id)->apply(ent, true);
}
} catch (...) {
owner.destroy_entity(ent);
throw;
inline void prototype::apply(entity& ent, bool override) const {
for ( const auto family_id : appliers_ ) {
appliers_.get(family_id)->apply(ent, override);
}
return ent;
}
inline void swap(prototype& l, prototype& r) noexcept {
@@ -1959,12 +1966,23 @@ namespace ecs_hpp
return wrap_entity(++last_entity_id_);
}
inline entity registry::create_entity(const const_uentity& prototype) {
assert(valid_entity(prototype));
inline entity registry::create_entity(const prototype& proto) {
auto ent = create_entity();
try {
proto.apply(ent, true);
} catch (...) {
destroy_entity(ent);
throw;
}
return ent;
}
inline entity registry::create_entity(const const_uentity& proto) {
assert(valid_entity(proto));
entity ent = create_entity();
try {
for ( const auto family_id : storages_ ) {
storages_.get(family_id)->clone(prototype, ent.id());
storages_.get(family_id)->clone(proto, ent.id());
}
} catch (...) {
destroy_entity(ent);
@@ -1973,15 +1991,13 @@ namespace ecs_hpp
return ent;
}
inline bool registry::destroy_entity(const uentity& ent) noexcept {
inline void registry::destroy_entity(const uentity& ent) noexcept {
assert(valid_entity(ent));
remove_all_components(ent);
if ( entity_ids_.unordered_erase(ent) ) {
assert(free_entity_ids_.size() < free_entity_ids_.capacity());
free_entity_ids_.push_back(ent);
return true;
}
return false;
}
inline bool registry::valid_entity(const const_uentity& ent) const noexcept {

View File

@@ -118,6 +118,7 @@ TEST_CASE("detail") {
REQUIRE_THROWS(s.get_dense_index(42u));
REQUIRE(s.insert(42u));
REQUIRE_FALSE(s.insert(42u));
REQUIRE_FALSE(s.empty());
REQUIRE(s.size() == 1u);
@@ -355,15 +356,15 @@ TEST_CASE("registry") {
REQUIRE(w.valid_entity(e3));
REQUIRE(w.valid_entity(ee3));
REQUIRE(w.destroy_entity(e1));
w.destroy_entity(e1);
REQUIRE_FALSE(w.valid_entity(e1));
REQUIRE(w.valid_entity(e2));
REQUIRE(w.destroy_entity(e2));
w.destroy_entity(e2);
REQUIRE_FALSE(w.valid_entity(e1));
REQUIRE_FALSE(w.valid_entity(e2));
REQUIRE(w.destroy_entity(ee3));
w.destroy_entity(ee3);
REQUIRE_FALSE(w.valid_entity(e3));
REQUIRE_FALSE(w.valid_entity(ee3));
}
@@ -520,8 +521,8 @@ TEST_CASE("registry") {
p.assign_component<position_c>(1, 2);
ecs::registry w;
const auto e1 = p.create_entity(w);
const auto e2 = p.create_entity(w);
const auto e1 = w.create_entity(p);
const auto e2 = w.create_entity(p);
REQUIRE(w.entity_count() == 2u);
REQUIRE(w.component_count<position_c>() == 2u);
@@ -539,8 +540,8 @@ TEST_CASE("registry") {
.assign_component<velocity_c>(3,4);
ecs::registry w;
const auto e1 = p.create_entity(w);
const auto e2 = p.create_entity(w);
const auto e1 = w.create_entity(p);
const auto e2 = w.create_entity(p);
REQUIRE(w.entity_count() == 2u);
REQUIRE(w.component_count<position_c>() == 2u);
@@ -564,7 +565,7 @@ TEST_CASE("registry") {
p3 = p2;
ecs::registry w;
const auto e3 = p3.create_entity(w);
const auto e3 = w.create_entity(p3);
REQUIRE(e3.get_component<position_c>() == position_c(1,2));
REQUIRE(e3.get_component<velocity_c>() == velocity_c(3,4));
}
@@ -587,15 +588,15 @@ TEST_CASE("registry") {
ecs::registry w;
const auto e1 = p1.create_entity(w);
const auto e1 = w.create_entity(p1);
REQUIRE(e1.get_component<position_c>() == position_c(1,2));
const auto e2 = p2.create_entity(w);
const auto e2 = w.create_entity(p2);
REQUIRE(e2.get_component<position_c>() == position_c(3,4));
const auto e3 = p3.create_entity(w);
const auto e3 = w.create_entity(p3);
REQUIRE(e3.get_component<position_c>() == position_c(1,2));
REQUIRE(e3.get_component<velocity_c>() == velocity_c(3,4));
const auto e4 = p4.create_entity(w);
const auto e4 = w.create_entity(p4);
REQUIRE(e4.get_component<position_c>() == position_c(1,2));
REQUIRE(e4.get_component<velocity_c>() == velocity_c(3,4));
}
@@ -654,7 +655,7 @@ TEST_CASE("registry") {
REQUIRE(e1.exists_component<position_c>());
REQUIRE(e1.exists_component<velocity_c>());
REQUIRE(e1.destroy());
e1.destroy();
REQUIRE_FALSE(w.component_count<position_c>());
REQUIRE_FALSE(w.component_count<velocity_c>());
@@ -672,7 +673,7 @@ TEST_CASE("registry") {
w.assign_component<position_c>(e2);
w.assign_component<velocity_c>(e2);
REQUIRE(w.destroy_entity(e1));
w.destroy_entity(e1);
REQUIRE(w.exists_component<position_c>(e2));
REQUIRE(w.exists_component<velocity_c>(e2));
@@ -691,7 +692,7 @@ TEST_CASE("registry") {
REQUIRE(&e2_pos == &w.get_component<position_c>(e2));
REQUIRE(&e2_vel == &w.get_component<velocity_c>(e2));
REQUIRE(e1.destroy());
e1.destroy();
}
}
SECTION("component_accessing") {