mirror of
https://github.com/BlackMATov/ecs.hpp.git
synced 2025-12-15 11:53:51 +07:00
@@ -105,6 +105,7 @@ namespace ecs_hpp
|
|||||||
std::tuple<T, Ts...>&& t,
|
std::tuple<T, Ts...>&& t,
|
||||||
std::index_sequence<Is...> iseq)
|
std::index_sequence<Is...> iseq)
|
||||||
{
|
{
|
||||||
|
(void)t;
|
||||||
(void)iseq;
|
(void)iseq;
|
||||||
return std::make_tuple(std::move(std::get<Is + 1u>(t))...);
|
return std::make_tuple(std::move(std::get<Is + 1u>(t))...);
|
||||||
}
|
}
|
||||||
@@ -114,6 +115,7 @@ namespace ecs_hpp
|
|||||||
const std::tuple<T, Ts...>& t,
|
const std::tuple<T, Ts...>& t,
|
||||||
std::index_sequence<Is...> iseq)
|
std::index_sequence<Is...> iseq)
|
||||||
{
|
{
|
||||||
|
(void)t;
|
||||||
(void)iseq;
|
(void)iseq;
|
||||||
return std::make_tuple(std::get<Is + 1u>(t)...);
|
return std::make_tuple(std::get<Is + 1u>(t)...);
|
||||||
}
|
}
|
||||||
@@ -289,6 +291,40 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace ecs_hpp
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template < typename Tag >
|
||||||
|
class incremental_locker final {
|
||||||
|
public:
|
||||||
|
incremental_locker() noexcept {
|
||||||
|
++lock_count_;
|
||||||
|
}
|
||||||
|
|
||||||
|
~incremental_locker() noexcept {
|
||||||
|
assert(lock_count_);
|
||||||
|
--lock_count_;
|
||||||
|
}
|
||||||
|
|
||||||
|
incremental_locker(incremental_locker&&) = delete;
|
||||||
|
incremental_locker& operator=(incremental_locker&&) = delete;
|
||||||
|
|
||||||
|
incremental_locker(const incremental_locker&) = delete;
|
||||||
|
incremental_locker& operator=(const incremental_locker&) = delete;
|
||||||
|
|
||||||
|
static bool is_locked() noexcept {
|
||||||
|
return !!lock_count_;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static std::size_t lock_count_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template < typename Tag >
|
||||||
|
std::size_t incremental_locker<Tag>::lock_count_ = 0u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// detail::sparse_set
|
// detail::sparse_set
|
||||||
@@ -368,11 +404,6 @@ namespace ecs_hpp
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Args >
|
|
||||||
bool emplace(Args&&... args) {
|
|
||||||
return insert(T(std::forward<Args>(args)...));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool unordered_erase(const T& v) noexcept {
|
bool unordered_erase(const T& v) noexcept {
|
||||||
if ( !has(v) ) {
|
if ( !has(v) ) {
|
||||||
return false;
|
return false;
|
||||||
@@ -509,27 +540,14 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename UK, typename UT >
|
template < typename UK, typename UT >
|
||||||
bool insert(UK&& k, UT&& v) {
|
std::pair<T*, bool> insert(UK&& k, UT&& v) {
|
||||||
if ( keys_.has(k) ) {
|
if ( T* value = find(k) ) {
|
||||||
return false;
|
return std::make_pair(value, false);
|
||||||
}
|
}
|
||||||
values_.push_back(std::forward<UT>(v));
|
values_.push_back(std::forward<UT>(v));
|
||||||
try {
|
try {
|
||||||
return keys_.insert(std::forward<UK>(k));
|
keys_.insert(std::forward<UK>(k));
|
||||||
} catch (...) {
|
return std::make_pair(&values_.back(), true);
|
||||||
values_.pop_back();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename UK, typename... Args >
|
|
||||||
bool emplace(UK&& k, Args&&... args) {
|
|
||||||
if ( keys_.has(k) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
values_.emplace_back(std::forward<Args>(args)...);
|
|
||||||
try {
|
|
||||||
return keys_.insert(std::forward<UK>(k));
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
values_.pop_back();
|
values_.pop_back();
|
||||||
throw;
|
throw;
|
||||||
@@ -537,13 +555,18 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename UK, typename UT >
|
template < typename UK, typename UT >
|
||||||
bool insert_or_assign(UK&& k, UT&& v) {
|
std::pair<T*, bool> insert_or_assign(UK&& k, UT&& v) {
|
||||||
if ( keys_.has(k) ) {
|
if ( T* value = find(k) ) {
|
||||||
get(k) = std::forward<UT>(v);
|
*value = std::forward<UT>(v);
|
||||||
return false;
|
return std::make_pair(value, false);
|
||||||
} else {
|
}
|
||||||
insert(std::forward<UK>(k), std::forward<UT>(v));
|
values_.push_back(std::forward<UT>(v));
|
||||||
return true;
|
try {
|
||||||
|
keys_.insert(std::forward<UK>(k));
|
||||||
|
return std::make_pair(&values_.back(), true);
|
||||||
|
} catch (...) {
|
||||||
|
values_.pop_back();
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -665,8 +688,21 @@ namespace ecs_hpp
|
|||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
T& assign(entity_id id, Args&&... args) {
|
T& assign(entity_id id, Args&&... args) {
|
||||||
components_.insert_or_assign(id, T(std::forward<Args>(args)...));
|
if ( T* value = components_.find(id) ) {
|
||||||
return components_.get(id);
|
*value = T(std::forward<Args>(args)...);
|
||||||
|
return *value;
|
||||||
|
}
|
||||||
|
assert(!components_locker::is_locked());
|
||||||
|
return *components_.insert(id, T(std::forward<Args>(args)...)).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename... Args >
|
||||||
|
T& ensure(entity_id id, Args&&... args) {
|
||||||
|
if ( T* value = components_.find(id) ) {
|
||||||
|
return *value;
|
||||||
|
}
|
||||||
|
assert(!components_locker::is_locked());
|
||||||
|
return *components_.insert(id, T(std::forward<Args>(args)...)).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool exists(entity_id id) const noexcept {
|
bool exists(entity_id id) const noexcept {
|
||||||
@@ -674,10 +710,12 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool remove(entity_id id) noexcept override {
|
bool remove(entity_id id) noexcept override {
|
||||||
|
assert(!components_locker::is_locked());
|
||||||
return components_.unordered_erase(id);
|
return components_.unordered_erase(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t remove_all() noexcept {
|
std::size_t remove_all() noexcept {
|
||||||
|
assert(!components_locker::is_locked());
|
||||||
const std::size_t count = components_.size();
|
const std::size_t count = components_.size();
|
||||||
components_.clear();
|
components_.clear();
|
||||||
return count;
|
return count;
|
||||||
@@ -700,14 +738,15 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
void clone(entity_id from, entity_id to) override {
|
void clone(entity_id from, entity_id to) override {
|
||||||
const T* c = components_.find(from);
|
const T* c = find(from);
|
||||||
if ( c ) {
|
if ( c ) {
|
||||||
components_.insert_or_assign(to, *c);
|
assign(to, *c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename F >
|
template < typename F >
|
||||||
void for_each_component(F&& f) {
|
void for_each_component(F&& f) {
|
||||||
|
components_locker lock;
|
||||||
for ( const entity_id id : components_ ) {
|
for ( const entity_id id : components_ ) {
|
||||||
f(id, components_.get(id));
|
f(id, components_.get(id));
|
||||||
}
|
}
|
||||||
@@ -715,6 +754,7 @@ namespace ecs_hpp
|
|||||||
|
|
||||||
template < typename F >
|
template < typename F >
|
||||||
void for_each_component(F&& f) const {
|
void for_each_component(F&& f) const {
|
||||||
|
components_locker lock;
|
||||||
for ( const entity_id id : components_ ) {
|
for ( const entity_id id : components_ ) {
|
||||||
f(id, components_.get(id));
|
f(id, components_.get(id));
|
||||||
}
|
}
|
||||||
@@ -726,6 +766,7 @@ namespace ecs_hpp
|
|||||||
private:
|
private:
|
||||||
registry& owner_;
|
registry& owner_;
|
||||||
detail::sparse_map<entity_id, T, entity_id_indexer> components_;
|
detail::sparse_map<entity_id, T, entity_id_indexer> components_;
|
||||||
|
using components_locker = detail::incremental_locker<struct components_tag>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
@@ -736,6 +777,20 @@ namespace ecs_hpp
|
|||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
T& assign(entity_id id, Args&&...) {
|
T& assign(entity_id id, Args&&...) {
|
||||||
|
if ( components_.has(id) ) {
|
||||||
|
return empty_value_;
|
||||||
|
}
|
||||||
|
assert(!components_locker::is_locked());
|
||||||
|
components_.insert(id);
|
||||||
|
return empty_value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename... Args >
|
||||||
|
T& ensure(entity_id id, Args&&...) {
|
||||||
|
if ( components_.has(id) ) {
|
||||||
|
return empty_value_;
|
||||||
|
}
|
||||||
|
assert(!components_locker::is_locked());
|
||||||
components_.insert(id);
|
components_.insert(id);
|
||||||
return empty_value_;
|
return empty_value_;
|
||||||
}
|
}
|
||||||
@@ -745,10 +800,12 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool remove(entity_id id) noexcept override {
|
bool remove(entity_id id) noexcept override {
|
||||||
|
assert(!components_locker::is_locked());
|
||||||
return components_.unordered_erase(id);
|
return components_.unordered_erase(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t remove_all() noexcept {
|
std::size_t remove_all() noexcept {
|
||||||
|
assert(!components_locker::is_locked());
|
||||||
const std::size_t count = components_.size();
|
const std::size_t count = components_.size();
|
||||||
components_.clear();
|
components_.clear();
|
||||||
return count;
|
return count;
|
||||||
@@ -775,13 +832,15 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
void clone(entity_id from, entity_id to) override {
|
void clone(entity_id from, entity_id to) override {
|
||||||
if ( components_.has(from) ) {
|
const T* c = find(from);
|
||||||
components_.insert(to);
|
if ( c ) {
|
||||||
|
assign(to, *c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename F >
|
template < typename F >
|
||||||
void for_each_component(F&& f) {
|
void for_each_component(F&& f) {
|
||||||
|
components_locker lock;
|
||||||
for ( const entity_id id : components_ ) {
|
for ( const entity_id id : components_ ) {
|
||||||
f(id, empty_value_);
|
f(id, empty_value_);
|
||||||
}
|
}
|
||||||
@@ -789,6 +848,7 @@ namespace ecs_hpp
|
|||||||
|
|
||||||
template < typename F >
|
template < typename F >
|
||||||
void for_each_component(F&& f) const {
|
void for_each_component(F&& f) const {
|
||||||
|
components_locker lock;
|
||||||
for ( const entity_id id : components_ ) {
|
for ( const entity_id id : components_ ) {
|
||||||
f(id, empty_value_);
|
f(id, empty_value_);
|
||||||
}
|
}
|
||||||
@@ -801,6 +861,7 @@ namespace ecs_hpp
|
|||||||
registry& owner_;
|
registry& owner_;
|
||||||
static T empty_value_;
|
static T empty_value_;
|
||||||
detail::sparse_set<entity_id, entity_id_indexer> components_;
|
detail::sparse_set<entity_id, entity_id_indexer> components_;
|
||||||
|
using components_locker = detail::incremental_locker<struct components_tag>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
@@ -839,6 +900,9 @@ namespace ecs_hpp
|
|||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
T& assign_component(Args&&... args);
|
T& assign_component(Args&&... args);
|
||||||
|
|
||||||
|
template < typename T, typename... Args >
|
||||||
|
T& ensure_component(Args&&... args);
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool remove_component();
|
bool remove_component();
|
||||||
|
|
||||||
@@ -992,6 +1056,9 @@ namespace ecs_hpp
|
|||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
T& assign(Args&&... args);
|
T& assign(Args&&... args);
|
||||||
|
|
||||||
|
template < typename... Args >
|
||||||
|
T& ensure(Args&&... args);
|
||||||
|
|
||||||
T& get();
|
T& get();
|
||||||
const T& get() const;
|
const T& get() const;
|
||||||
|
|
||||||
@@ -1262,6 +1329,9 @@ namespace ecs_hpp
|
|||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
T& assign_component(const uentity& ent, Args&&... args);
|
T& assign_component(const uentity& ent, Args&&... args);
|
||||||
|
|
||||||
|
template < typename T, typename... Args >
|
||||||
|
T& ensure_component(const uentity& ent, Args&&... args);
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool remove_component(const uentity& ent);
|
bool remove_component(const uentity& ent);
|
||||||
|
|
||||||
@@ -1396,6 +1466,7 @@ namespace ecs_hpp
|
|||||||
entity_id last_entity_id_{0u};
|
entity_id last_entity_id_{0u};
|
||||||
std::vector<entity_id> free_entity_ids_;
|
std::vector<entity_id> free_entity_ids_;
|
||||||
detail::sparse_set<entity_id, detail::entity_id_indexer> entity_ids_;
|
detail::sparse_set<entity_id, detail::entity_id_indexer> entity_ids_;
|
||||||
|
using entity_ids_locker = detail::incremental_locker<struct entity_ids_tag>;
|
||||||
|
|
||||||
using storage_uptr = std::unique_ptr<detail::component_storage_base>;
|
using storage_uptr = std::unique_ptr<detail::component_storage_base>;
|
||||||
detail::sparse_map<family_id, storage_uptr> storages_;
|
detail::sparse_map<family_id, storage_uptr> storages_;
|
||||||
@@ -1490,6 +1561,13 @@ namespace ecs_hpp
|
|||||||
std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename T, typename... Args >
|
||||||
|
T& entity::ensure_component(Args&&... args) {
|
||||||
|
return (*owner_).ensure_component<T>(
|
||||||
|
id_,
|
||||||
|
std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool entity::remove_component() {
|
bool entity::remove_component() {
|
||||||
return (*owner_).remove_component<T>(id_);
|
return (*owner_).remove_component<T>(id_);
|
||||||
@@ -1695,6 +1773,13 @@ namespace ecs_hpp
|
|||||||
std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
template < typename... Args >
|
||||||
|
T& component<T>::ensure(Args&&... args) {
|
||||||
|
return owner_.ensure_component<T>(
|
||||||
|
std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
T& component<T>::get() {
|
T& component<T>::get() {
|
||||||
return owner_.get_component<T>();
|
return owner_.get_component<T>();
|
||||||
@@ -2105,6 +2190,7 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline entity registry::create_entity() {
|
inline entity registry::create_entity() {
|
||||||
|
assert(!entity_ids_locker::is_locked());
|
||||||
if ( !free_entity_ids_.empty() ) {
|
if ( !free_entity_ids_.empty() ) {
|
||||||
const auto free_ent_id = free_entity_ids_.back();
|
const auto free_ent_id = free_entity_ids_.back();
|
||||||
const auto new_ent_id = detail::upgrade_entity_id(free_ent_id);
|
const auto new_ent_id = detail::upgrade_entity_id(free_ent_id);
|
||||||
@@ -2153,6 +2239,7 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void registry::destroy_entity(const uentity& ent) noexcept {
|
inline void registry::destroy_entity(const uentity& ent) noexcept {
|
||||||
|
assert(!entity_ids_locker::is_locked());
|
||||||
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) ) {
|
||||||
@@ -2174,6 +2261,14 @@ namespace ecs_hpp
|
|||||||
std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename T, typename... Args >
|
||||||
|
T& registry::ensure_component(const uentity& ent, Args&&... args) {
|
||||||
|
assert(valid_entity(ent));
|
||||||
|
return get_or_create_storage_<T>().ensure(
|
||||||
|
ent,
|
||||||
|
std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool registry::remove_component(const uentity& ent) {
|
bool registry::remove_component(const uentity& ent) {
|
||||||
assert(valid_entity(ent));
|
assert(valid_entity(ent));
|
||||||
@@ -2251,24 +2346,28 @@ namespace ecs_hpp
|
|||||||
|
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<Ts&...> registry::get_components(const uentity& ent) {
|
std::tuple<Ts&...> registry::get_components(const uentity& ent) {
|
||||||
|
(void)ent;
|
||||||
assert(valid_entity(ent));
|
assert(valid_entity(ent));
|
||||||
return std::make_tuple(std::ref(get_component<Ts>(ent))...);
|
return std::make_tuple(std::ref(get_component<Ts>(ent))...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<const Ts&...> registry::get_components(const const_uentity& ent) const {
|
std::tuple<const Ts&...> registry::get_components(const const_uentity& ent) const {
|
||||||
|
(void)ent;
|
||||||
assert(valid_entity(ent));
|
assert(valid_entity(ent));
|
||||||
return std::make_tuple(std::cref(get_component<Ts>(ent))...);
|
return std::make_tuple(std::cref(get_component<Ts>(ent))...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<Ts*...> registry::find_components(const uentity& ent) noexcept {
|
std::tuple<Ts*...> registry::find_components(const uentity& ent) noexcept {
|
||||||
|
(void)ent;
|
||||||
assert(valid_entity(ent));
|
assert(valid_entity(ent));
|
||||||
return std::make_tuple(find_component<Ts>(ent)...);
|
return std::make_tuple(find_component<Ts>(ent)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<const Ts*...> registry::find_components(const const_uentity& ent) const noexcept {
|
std::tuple<const Ts*...> registry::find_components(const const_uentity& ent) const noexcept {
|
||||||
|
(void)ent;
|
||||||
assert(valid_entity(ent));
|
assert(valid_entity(ent));
|
||||||
return std::make_tuple(find_component<Ts>(ent)...);
|
return std::make_tuple(find_component<Ts>(ent)...);
|
||||||
}
|
}
|
||||||
@@ -2298,6 +2397,7 @@ namespace ecs_hpp
|
|||||||
|
|
||||||
template < typename F >
|
template < typename F >
|
||||||
void registry::for_each_entity(F&& f) {
|
void registry::for_each_entity(F&& f) {
|
||||||
|
entity_ids_locker lock;
|
||||||
for ( const auto id : entity_ids_ ) {
|
for ( const auto id : entity_ids_ ) {
|
||||||
f({*this, id});
|
f({*this, id});
|
||||||
}
|
}
|
||||||
@@ -2305,6 +2405,7 @@ namespace ecs_hpp
|
|||||||
|
|
||||||
template < typename F >
|
template < typename F >
|
||||||
void registry::for_each_entity(F&& f) const {
|
void registry::for_each_entity(F&& f) const {
|
||||||
|
entity_ids_locker lock;
|
||||||
for ( const auto id : entity_ids_ ) {
|
for ( const auto id : entity_ids_ ) {
|
||||||
f({*this, id});
|
f({*this, id});
|
||||||
}
|
}
|
||||||
@@ -2351,10 +2452,9 @@ namespace ecs_hpp
|
|||||||
[](priority_t pr, const auto& r){
|
[](priority_t pr, const auto& r){
|
||||||
return pr < r.first;
|
return pr < r.first;
|
||||||
});
|
});
|
||||||
systems_.emplace(
|
systems_.insert(
|
||||||
iter,
|
iter,
|
||||||
priority,
|
std::make_pair(priority, std::make_unique<T>(std::forward<Args>(args)...)));
|
||||||
std::make_unique<T>(std::forward<Args>(args)...));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void registry::process_all_systems() {
|
inline void registry::process_all_systems() {
|
||||||
@@ -2431,7 +2531,7 @@ namespace ecs_hpp
|
|||||||
return *storage;
|
return *storage;
|
||||||
}
|
}
|
||||||
const auto family = detail::type_family<T>::id();
|
const auto family = detail::type_family<T>::id();
|
||||||
storages_.emplace(
|
storages_.insert(
|
||||||
family,
|
family,
|
||||||
std::make_unique<detail::component_storage<T>>(*this));
|
std::make_unique<detail::component_storage<T>>(*this));
|
||||||
return *static_cast<detail::component_storage<T>*>(
|
return *static_cast<detail::component_storage<T>*>(
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ TEST_CASE("detail") {
|
|||||||
REQUIRE(s.insert(position_c(1,2)));
|
REQUIRE(s.insert(position_c(1,2)));
|
||||||
REQUIRE_FALSE(s.insert(position_c(1,2)));
|
REQUIRE_FALSE(s.insert(position_c(1,2)));
|
||||||
REQUIRE(s.has(position_c(1,2)));
|
REQUIRE(s.has(position_c(1,2)));
|
||||||
REQUIRE(s.emplace(3,4));
|
REQUIRE(s.insert(position_c(3,4)));
|
||||||
REQUIRE(s.has(position_c(3,4)));
|
REQUIRE(s.has(position_c(3,4)));
|
||||||
REQUIRE(s.get_dense_index(position_c(1,2)) == 0);
|
REQUIRE(s.get_dense_index(position_c(1,2)) == 0);
|
||||||
REQUIRE(s.get_dense_index(position_c(3,4)) == 1);
|
REQUIRE(s.get_dense_index(position_c(3,4)) == 1);
|
||||||
@@ -209,16 +209,16 @@ TEST_CASE("detail") {
|
|||||||
|
|
||||||
{
|
{
|
||||||
obj_t o{21u};
|
obj_t o{21u};
|
||||||
REQUIRE(m.insert(21u, o));
|
REQUIRE(m.insert(21u, o).second);
|
||||||
REQUIRE(m.insert(42u, obj_t{42u}));
|
REQUIRE(m.insert(42u, obj_t{42u}).second);
|
||||||
REQUIRE(m.emplace(84u, 84u));
|
REQUIRE(m.insert(84u, obj_t(84u)).second);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
obj_t o{21u};
|
obj_t o{21u};
|
||||||
REQUIRE_FALSE(m.insert(21u, o));
|
REQUIRE_FALSE(m.insert(21u, o).second);
|
||||||
REQUIRE_FALSE(m.insert(42u, obj_t{42u}));
|
REQUIRE_FALSE(m.insert(42u, obj_t{42u}).second);
|
||||||
REQUIRE_FALSE(m.emplace(84u, 84u));
|
REQUIRE_FALSE(m.insert(84u, obj_t(84u)).second);
|
||||||
}
|
}
|
||||||
|
|
||||||
REQUIRE_FALSE(m.empty());
|
REQUIRE_FALSE(m.empty());
|
||||||
@@ -270,10 +270,10 @@ TEST_CASE("detail") {
|
|||||||
};
|
};
|
||||||
|
|
||||||
sparse_map<position_c, obj_t, position_c_indexer> s{position_c_indexer()};
|
sparse_map<position_c, obj_t, position_c_indexer> s{position_c_indexer()};
|
||||||
REQUIRE(s.insert(position_c(1,2), obj_t{1}));
|
REQUIRE(s.insert(position_c(1,2), obj_t{1}).second);
|
||||||
REQUIRE_FALSE(s.insert(position_c(1,2), obj_t{1}));
|
REQUIRE_FALSE(s.insert(position_c(1,2), obj_t{1}).second);
|
||||||
REQUIRE(s.has(position_c(1,2)));
|
REQUIRE(s.has(position_c(1,2)));
|
||||||
REQUIRE(s.emplace(position_c(3,4), obj_t{3}));
|
REQUIRE(s.insert(position_c(3,4), obj_t{3}).second);
|
||||||
REQUIRE(s.has(position_c(3,4)));
|
REQUIRE(s.has(position_c(3,4)));
|
||||||
REQUIRE(s.get(position_c(1,2)).x == 1);
|
REQUIRE(s.get(position_c(1,2)).x == 1);
|
||||||
REQUIRE(s.get(position_c(3,4)).x == 3);
|
REQUIRE(s.get(position_c(3,4)).x == 3);
|
||||||
@@ -291,14 +291,14 @@ TEST_CASE("detail") {
|
|||||||
};
|
};
|
||||||
|
|
||||||
sparse_map<unsigned, obj_t> m;
|
sparse_map<unsigned, obj_t> m;
|
||||||
REQUIRE(m.insert_or_assign(42, obj_t(42)));
|
REQUIRE(m.insert_or_assign(42, obj_t(42)).second);
|
||||||
REQUIRE(m.has(42));
|
REQUIRE(m.has(42));
|
||||||
REQUIRE(m.get(42).x == 42);
|
REQUIRE(m.get(42).x == 42);
|
||||||
REQUIRE_FALSE(m.insert_or_assign(42, obj_t(21)));
|
REQUIRE_FALSE(m.insert_or_assign(42, obj_t(21)).second);
|
||||||
REQUIRE(m.has(42));
|
REQUIRE(m.has(42));
|
||||||
REQUIRE(m.get(42).x == 21);
|
REQUIRE(m.get(42).x == 21);
|
||||||
REQUIRE(m.size() == 1);
|
REQUIRE(m.size() == 1);
|
||||||
REQUIRE(m.insert_or_assign(84, obj_t(84)));
|
REQUIRE(m.insert_or_assign(84, obj_t(84)).second);
|
||||||
REQUIRE(m.has(84));
|
REQUIRE(m.has(84));
|
||||||
REQUIRE(m.get(84).x == 84);
|
REQUIRE(m.get(84).x == 84);
|
||||||
REQUIRE(m.size() == 2);
|
REQUIRE(m.size() == 2);
|
||||||
@@ -813,6 +813,31 @@ TEST_CASE("registry") {
|
|||||||
e1.destroy();
|
e1.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SECTION("component_ensuring") {
|
||||||
|
{
|
||||||
|
ecs::registry w;
|
||||||
|
ecs::entity e1 = w.create_entity();
|
||||||
|
|
||||||
|
e1.ensure_component<position_c>(1,2);
|
||||||
|
e1.ensure_component<movable_c>();
|
||||||
|
|
||||||
|
REQUIRE(e1.get_component<position_c>() == position_c(1,2));
|
||||||
|
REQUIRE(e1.exists_component<movable_c>());
|
||||||
|
|
||||||
|
e1.ensure_component<position_c>(10,20).x = 15;
|
||||||
|
e1.ensure_component<movable_c>();
|
||||||
|
|
||||||
|
REQUIRE(e1.get_component<position_c>() == position_c(15,2));
|
||||||
|
REQUIRE(e1.exists_component<movable_c>());
|
||||||
|
|
||||||
|
ecs::component<velocity_c> c1 = w.wrap_component<velocity_c>(e1);
|
||||||
|
REQUIRE_FALSE(c1.exists());
|
||||||
|
c1.ensure(2, 1).y = 10;
|
||||||
|
REQUIRE(c1.get() == velocity_c(2, 10));
|
||||||
|
c1.ensure(10, 20).x = 20;
|
||||||
|
REQUIRE(c1.get() == velocity_c(20, 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
SECTION("component_accessing") {
|
SECTION("component_accessing") {
|
||||||
{
|
{
|
||||||
ecs::registry w;
|
ecs::registry w;
|
||||||
|
|||||||
Reference in New Issue
Block a user