mirror of
https://github.com/BlackMATov/ecs.hpp.git
synced 2025-12-16 22:19:21 +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 >
|
template < typename T >
|
||||||
class const_component;
|
class const_component;
|
||||||
|
|
||||||
|
class prototype;
|
||||||
|
|
||||||
class system;
|
class system;
|
||||||
class registry;
|
class registry;
|
||||||
|
|
||||||
|
class entity_filler;
|
||||||
|
class registry_filler;
|
||||||
|
|
||||||
using family_id = std::uint16_t;
|
using family_id = std::uint16_t;
|
||||||
using entity_id = std::uint32_t;
|
using entity_id = std::uint32_t;
|
||||||
using priority_t = std::int32_t;
|
using priority_t = std::int32_t;
|
||||||
@@ -427,8 +432,12 @@ namespace ecs_hpp
|
|||||||
std::vector<std::size_t> sparse_;
|
std::vector<std::size_t> sparse_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template < typename T, typename Indexer >
|
template < typename T
|
||||||
void swap(sparse_set<T,Indexer>& l, sparse_set<T,Indexer>& r) noexcept {
|
, typename Indexer >
|
||||||
|
void swap(
|
||||||
|
sparse_set<T, Indexer>& l,
|
||||||
|
sparse_set<T, Indexer>& r) noexcept
|
||||||
|
{
|
||||||
l.swap(r);
|
l.swap(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -591,8 +600,13 @@ namespace ecs_hpp
|
|||||||
std::vector<T> values_;
|
std::vector<T> values_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template < typename K, typename T, typename Indexer >
|
template < typename K
|
||||||
void swap(sparse_map<K,T,Indexer>& l, sparse_map<K,T,Indexer>& r) noexcept {
|
, typename T
|
||||||
|
, typename Indexer >
|
||||||
|
void swap(
|
||||||
|
sparse_map<K, T, Indexer>& l,
|
||||||
|
sparse_map<K, T, Indexer>& r) noexcept
|
||||||
|
{
|
||||||
l.swap(r);
|
l.swap(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -752,7 +766,7 @@ namespace ecs_hpp
|
|||||||
entity_id id() const noexcept;
|
entity_id id() const noexcept;
|
||||||
|
|
||||||
entity clone() const;
|
entity clone() const;
|
||||||
bool destroy() noexcept;
|
void destroy() noexcept;
|
||||||
bool valid() const noexcept;
|
bool valid() const noexcept;
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
@@ -1055,14 +1069,13 @@ namespace ecs_hpp
|
|||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
prototype& assign_component(Args&&... args) &;
|
prototype& assign_component(Args&&... args) &;
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
prototype&& assign_component(Args&&... args) &&;
|
prototype&& assign_component(Args&&... args) &&;
|
||||||
|
|
||||||
prototype& merge(const prototype& other, bool override) &;
|
prototype& merge(const prototype& other, bool override) &;
|
||||||
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:
|
private:
|
||||||
detail::sparse_map<
|
detail::sparse_map<
|
||||||
family_id,
|
family_id,
|
||||||
@@ -1157,9 +1170,10 @@ namespace ecs_hpp
|
|||||||
const_component<T> wrap_component(const const_uentity& ent) const noexcept;
|
const_component<T> wrap_component(const const_uentity& ent) const noexcept;
|
||||||
|
|
||||||
entity create_entity();
|
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;
|
bool valid_entity(const const_uentity& ent) const noexcept;
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
@@ -1366,8 +1380,8 @@ namespace ecs_hpp
|
|||||||
return (*owner_).create_entity(id_);
|
return (*owner_).create_entity(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool entity::destroy() noexcept {
|
inline void entity::destroy() noexcept {
|
||||||
return (*owner_).destroy_entity(id_);
|
(*owner_).destroy_entity(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool entity::valid() const noexcept {
|
inline bool entity::valid() const noexcept {
|
||||||
@@ -1799,17 +1813,10 @@ namespace ecs_hpp
|
|||||||
return std::move(*this);
|
return std::move(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entity prototype::create_entity(registry& owner) const {
|
inline void prototype::apply(entity& ent, bool override) const {
|
||||||
auto ent = owner.create_entity();
|
for ( const auto family_id : appliers_ ) {
|
||||||
try {
|
appliers_.get(family_id)->apply(ent, override);
|
||||||
for ( const auto family_id : appliers_ ) {
|
|
||||||
appliers_.get(family_id)->apply(ent, true);
|
|
||||||
}
|
|
||||||
} catch (...) {
|
|
||||||
owner.destroy_entity(ent);
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
return ent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void swap(prototype& l, prototype& r) noexcept {
|
inline void swap(prototype& l, prototype& r) noexcept {
|
||||||
@@ -1959,12 +1966,23 @@ namespace ecs_hpp
|
|||||||
return wrap_entity(++last_entity_id_);
|
return wrap_entity(++last_entity_id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entity registry::create_entity(const const_uentity& prototype) {
|
inline entity registry::create_entity(const prototype& proto) {
|
||||||
assert(valid_entity(prototype));
|
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();
|
entity ent = create_entity();
|
||||||
try {
|
try {
|
||||||
for ( const auto family_id : storages_ ) {
|
for ( const auto family_id : storages_ ) {
|
||||||
storages_.get(family_id)->clone(prototype, ent.id());
|
storages_.get(family_id)->clone(proto, ent.id());
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
destroy_entity(ent);
|
destroy_entity(ent);
|
||||||
@@ -1973,15 +1991,13 @@ namespace ecs_hpp
|
|||||||
return ent;
|
return ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool registry::destroy_entity(const uentity& ent) noexcept {
|
inline void registry::destroy_entity(const uentity& ent) noexcept {
|
||||||
assert(valid_entity(ent));
|
assert(valid_entity(ent));
|
||||||
remove_all_components(ent);
|
remove_all_components(ent);
|
||||||
if ( entity_ids_.unordered_erase(ent) ) {
|
if ( entity_ids_.unordered_erase(ent) ) {
|
||||||
assert(free_entity_ids_.size() < free_entity_ids_.capacity());
|
assert(free_entity_ids_.size() < free_entity_ids_.capacity());
|
||||||
free_entity_ids_.push_back(ent);
|
free_entity_ids_.push_back(ent);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool registry::valid_entity(const const_uentity& ent) const noexcept {
|
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_THROWS(s.get_dense_index(42u));
|
||||||
|
|
||||||
REQUIRE(s.insert(42u));
|
REQUIRE(s.insert(42u));
|
||||||
|
REQUIRE_FALSE(s.insert(42u));
|
||||||
|
|
||||||
REQUIRE_FALSE(s.empty());
|
REQUIRE_FALSE(s.empty());
|
||||||
REQUIRE(s.size() == 1u);
|
REQUIRE(s.size() == 1u);
|
||||||
@@ -355,15 +356,15 @@ TEST_CASE("registry") {
|
|||||||
REQUIRE(w.valid_entity(e3));
|
REQUIRE(w.valid_entity(e3));
|
||||||
REQUIRE(w.valid_entity(ee3));
|
REQUIRE(w.valid_entity(ee3));
|
||||||
|
|
||||||
REQUIRE(w.destroy_entity(e1));
|
w.destroy_entity(e1);
|
||||||
REQUIRE_FALSE(w.valid_entity(e1));
|
REQUIRE_FALSE(w.valid_entity(e1));
|
||||||
REQUIRE(w.valid_entity(e2));
|
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(e1));
|
||||||
REQUIRE_FALSE(w.valid_entity(e2));
|
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(e3));
|
||||||
REQUIRE_FALSE(w.valid_entity(ee3));
|
REQUIRE_FALSE(w.valid_entity(ee3));
|
||||||
}
|
}
|
||||||
@@ -520,8 +521,8 @@ TEST_CASE("registry") {
|
|||||||
p.assign_component<position_c>(1, 2);
|
p.assign_component<position_c>(1, 2);
|
||||||
|
|
||||||
ecs::registry w;
|
ecs::registry w;
|
||||||
const auto e1 = p.create_entity(w);
|
const auto e1 = w.create_entity(p);
|
||||||
const auto e2 = p.create_entity(w);
|
const auto e2 = w.create_entity(p);
|
||||||
|
|
||||||
REQUIRE(w.entity_count() == 2u);
|
REQUIRE(w.entity_count() == 2u);
|
||||||
REQUIRE(w.component_count<position_c>() == 2u);
|
REQUIRE(w.component_count<position_c>() == 2u);
|
||||||
@@ -539,8 +540,8 @@ TEST_CASE("registry") {
|
|||||||
.assign_component<velocity_c>(3,4);
|
.assign_component<velocity_c>(3,4);
|
||||||
|
|
||||||
ecs::registry w;
|
ecs::registry w;
|
||||||
const auto e1 = p.create_entity(w);
|
const auto e1 = w.create_entity(p);
|
||||||
const auto e2 = p.create_entity(w);
|
const auto e2 = w.create_entity(p);
|
||||||
|
|
||||||
REQUIRE(w.entity_count() == 2u);
|
REQUIRE(w.entity_count() == 2u);
|
||||||
REQUIRE(w.component_count<position_c>() == 2u);
|
REQUIRE(w.component_count<position_c>() == 2u);
|
||||||
@@ -564,7 +565,7 @@ TEST_CASE("registry") {
|
|||||||
p3 = p2;
|
p3 = p2;
|
||||||
|
|
||||||
ecs::registry w;
|
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<position_c>() == position_c(1,2));
|
||||||
REQUIRE(e3.get_component<velocity_c>() == velocity_c(3,4));
|
REQUIRE(e3.get_component<velocity_c>() == velocity_c(3,4));
|
||||||
}
|
}
|
||||||
@@ -587,15 +588,15 @@ TEST_CASE("registry") {
|
|||||||
|
|
||||||
ecs::registry w;
|
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));
|
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));
|
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<position_c>() == position_c(1,2));
|
||||||
REQUIRE(e3.get_component<velocity_c>() == velocity_c(3,4));
|
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<position_c>() == position_c(1,2));
|
||||||
REQUIRE(e4.get_component<velocity_c>() == velocity_c(3,4));
|
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<position_c>());
|
||||||
REQUIRE(e1.exists_component<velocity_c>());
|
REQUIRE(e1.exists_component<velocity_c>());
|
||||||
|
|
||||||
REQUIRE(e1.destroy());
|
e1.destroy();
|
||||||
|
|
||||||
REQUIRE_FALSE(w.component_count<position_c>());
|
REQUIRE_FALSE(w.component_count<position_c>());
|
||||||
REQUIRE_FALSE(w.component_count<velocity_c>());
|
REQUIRE_FALSE(w.component_count<velocity_c>());
|
||||||
@@ -672,7 +673,7 @@ TEST_CASE("registry") {
|
|||||||
w.assign_component<position_c>(e2);
|
w.assign_component<position_c>(e2);
|
||||||
w.assign_component<velocity_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<position_c>(e2));
|
||||||
REQUIRE(w.exists_component<velocity_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_pos == &w.get_component<position_c>(e2));
|
||||||
REQUIRE(&e2_vel == &w.get_component<velocity_c>(e2));
|
REQUIRE(&e2_vel == &w.get_component<velocity_c>(e2));
|
||||||
|
|
||||||
REQUIRE(e1.destroy());
|
e1.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SECTION("component_accessing") {
|
SECTION("component_accessing") {
|
||||||
|
|||||||
Reference in New Issue
Block a user