mirror of
https://github.com/BlackMATov/ecs.hpp.git
synced 2025-12-13 10:35:39 +07:00
registry::create_entity from prototype
This commit is contained in:
70
ecs.hpp
70
ecs.hpp
@@ -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 {
|
||||
|
||||
@@ -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") {
|
||||
|
||||
Reference in New Issue
Block a user