mirror of
https://github.com/BlackMATov/ecs.hpp.git
synced 2025-12-16 22:19:21 +07:00
universal function argument for entity id
This commit is contained in:
@@ -35,15 +35,15 @@
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
struct position_component {
|
struct position_component {
|
||||||
float x{0};
|
float x;
|
||||||
float y{0};
|
float y;
|
||||||
position_component(float nx, float ny)
|
position_component(float nx, float ny)
|
||||||
: x(nx), y(ny) {}
|
: x(nx), y(ny) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct velocity_component {
|
struct velocity_component {
|
||||||
float dx{0};
|
float dx;
|
||||||
float dy{0};
|
float dy;
|
||||||
velocity_component(float ndx, float ndy)
|
velocity_component(float ndx, float ndy)
|
||||||
: dx(ndx), dy(ndy) {}
|
: dx(ndx), dy(ndy) {}
|
||||||
};
|
};
|
||||||
|
|||||||
430
ecs.hpp
430
ecs.hpp
@@ -197,7 +197,7 @@ namespace ecs_hpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
class type_family : public type_family_base<> {
|
class type_family final : public type_family_base<> {
|
||||||
public:
|
public:
|
||||||
static family_id id() noexcept {
|
static family_id id() noexcept {
|
||||||
static family_id self_id = ++last_id_;
|
static family_id self_id = ++last_id_;
|
||||||
@@ -234,7 +234,7 @@ namespace ecs_hpp
|
|||||||
struct sparse_unsigned_indexer<T, false> {};
|
struct sparse_unsigned_indexer<T, false> {};
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
struct sparse_indexer
|
struct sparse_indexer final
|
||||||
: public sparse_unsigned_indexer<T> {};
|
: public sparse_unsigned_indexer<T> {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -474,7 +474,9 @@ namespace ecs_hpp
|
|||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
std::is_nothrow_move_assignable<K>::value,
|
std::is_nothrow_move_assignable<K>::value,
|
||||||
bool>
|
bool>
|
||||||
unordered_erase(const K& k) {
|
unordered_erase(const K& k)
|
||||||
|
noexcept(std::is_nothrow_move_assignable<T>::value)
|
||||||
|
{
|
||||||
if ( !keys_.has(k) ) {
|
if ( !keys_.has(k) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -540,7 +542,7 @@ namespace ecs_hpp
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
struct entity_id_indexer {
|
struct entity_id_indexer final {
|
||||||
std::size_t operator()(entity_id id) const noexcept {
|
std::size_t operator()(entity_id id) const noexcept {
|
||||||
return entity_id_index(id);
|
return entity_id_index(id);
|
||||||
}
|
}
|
||||||
@@ -562,6 +564,7 @@ namespace ecs_hpp
|
|||||||
public:
|
public:
|
||||||
virtual ~component_storage_base() = default;
|
virtual ~component_storage_base() = default;
|
||||||
virtual bool remove(entity_id id) noexcept = 0;
|
virtual bool remove(entity_id id) noexcept = 0;
|
||||||
|
virtual bool has(entity_id id) const noexcept = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
@@ -577,6 +580,9 @@ namespace ecs_hpp
|
|||||||
T* find(entity_id id) noexcept;
|
T* find(entity_id id) noexcept;
|
||||||
const T* find(entity_id id) const noexcept;
|
const T* find(entity_id id) const noexcept;
|
||||||
|
|
||||||
|
std::size_t count() const noexcept;
|
||||||
|
bool has(entity_id id) const noexcept override;
|
||||||
|
|
||||||
template < typename F >
|
template < typename F >
|
||||||
void for_each_component(F&& f) noexcept;
|
void for_each_component(F&& f) noexcept;
|
||||||
template < typename F >
|
template < typename F >
|
||||||
@@ -618,11 +624,21 @@ namespace ecs_hpp
|
|||||||
return components_.find(id);
|
return components_.find(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
std::size_t component_storage<T>::count() const noexcept {
|
||||||
|
return components_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
bool component_storage<T>::has(entity_id id) const noexcept {
|
||||||
|
return components_.has(id);
|
||||||
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
template < typename F >
|
template < typename F >
|
||||||
void component_storage<T>::for_each_component(F&& f) noexcept {
|
void component_storage<T>::for_each_component(F&& f) noexcept {
|
||||||
for ( const auto id : components_ ) {
|
for ( const auto id : components_ ) {
|
||||||
f(entity(owner_, id), components_.get(id));
|
f(id, components_.get(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,7 +646,7 @@ namespace ecs_hpp
|
|||||||
template < typename F >
|
template < typename F >
|
||||||
void component_storage<T>::for_each_component(F&& f) const noexcept {
|
void component_storage<T>::for_each_component(F&& f) const noexcept {
|
||||||
for ( const auto id : components_ ) {
|
for ( const auto id : components_ ) {
|
||||||
f(const_entity(owner_, id), components_.get(id));
|
f(id, components_.get(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -690,7 +706,7 @@ namespace ecs_hpp
|
|||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<const Ts*...> find_components() const noexcept;
|
std::tuple<const Ts*...> find_components() const noexcept;
|
||||||
private:
|
private:
|
||||||
registry* owner_;
|
registry* owner_{nullptr};
|
||||||
entity_id id_{0u};
|
entity_id id_{0u};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -701,7 +717,7 @@ namespace ecs_hpp
|
|||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
template <>
|
template <>
|
||||||
struct hash<ecs_hpp::entity>
|
struct hash<ecs_hpp::entity> final
|
||||||
: std::unary_function<const ecs_hpp::entity&, std::size_t>
|
: std::unary_function<const ecs_hpp::entity&, std::size_t>
|
||||||
{
|
{
|
||||||
std::size_t operator()(const ecs_hpp::entity& ent) const noexcept {
|
std::size_t operator()(const ecs_hpp::entity& ent) const noexcept {
|
||||||
@@ -747,7 +763,7 @@ namespace ecs_hpp
|
|||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<const Ts*...> find_components() const noexcept;
|
std::tuple<const Ts*...> find_components() const noexcept;
|
||||||
private:
|
private:
|
||||||
const registry* owner_;
|
const registry* owner_{nullptr};
|
||||||
entity_id id_{0u};
|
entity_id id_{0u};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -758,7 +774,7 @@ namespace ecs_hpp
|
|||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
template <>
|
template <>
|
||||||
struct hash<ecs_hpp::const_entity>
|
struct hash<ecs_hpp::const_entity> final
|
||||||
: std::unary_function<const ecs_hpp::const_entity&, std::size_t>
|
: std::unary_function<const ecs_hpp::const_entity&, std::size_t>
|
||||||
{
|
{
|
||||||
std::size_t operator()(const ecs_hpp::const_entity& ent) const noexcept {
|
std::size_t operator()(const ecs_hpp::const_entity& ent) const noexcept {
|
||||||
@@ -793,44 +809,92 @@ namespace ecs_hpp
|
|||||||
namespace ecs_hpp
|
namespace ecs_hpp
|
||||||
{
|
{
|
||||||
class registry final {
|
class registry final {
|
||||||
|
private:
|
||||||
|
class uentity {
|
||||||
|
public:
|
||||||
|
uentity(registry& owner, entity_id id) noexcept;
|
||||||
|
|
||||||
|
uentity(entity_id ent) noexcept;
|
||||||
|
uentity(entity ent) noexcept;
|
||||||
|
|
||||||
|
operator entity_id() const noexcept;
|
||||||
|
operator entity() const noexcept;
|
||||||
|
operator const_entity() const noexcept;
|
||||||
|
|
||||||
|
entity_id id() const noexcept;
|
||||||
|
registry* owner() noexcept;
|
||||||
|
const registry* owner() const noexcept;
|
||||||
|
|
||||||
|
bool check_owner(const registry* owner) const noexcept;
|
||||||
|
private:
|
||||||
|
entity_id id_{0u};
|
||||||
|
registry* owner_{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
class const_uentity {
|
||||||
|
public:
|
||||||
|
const_uentity(const registry& owner, entity_id id) noexcept;
|
||||||
|
|
||||||
|
const_uentity(entity_id ent) noexcept;
|
||||||
|
const_uentity(entity ent) noexcept;
|
||||||
|
const_uentity(const_entity ent) noexcept;
|
||||||
|
const_uentity(const uentity& ent) noexcept;
|
||||||
|
|
||||||
|
operator entity_id() const noexcept;
|
||||||
|
operator const_entity() const noexcept;
|
||||||
|
|
||||||
|
entity_id id() const noexcept;
|
||||||
|
const registry* owner() const noexcept;
|
||||||
|
|
||||||
|
bool check_owner(const registry* owner) const noexcept;
|
||||||
|
private:
|
||||||
|
entity_id id_{0u};
|
||||||
|
const registry* owner_{nullptr};
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
registry() = default;
|
registry() = default;
|
||||||
~registry() noexcept = default;
|
~registry() noexcept = default;
|
||||||
|
|
||||||
entity create_entity();
|
entity create_entity();
|
||||||
bool destroy_entity(const entity& ent);
|
|
||||||
bool alive_entity(const const_entity& ent) const noexcept;
|
bool destroy_entity(const uentity& ent);
|
||||||
|
bool alive_entity(const const_uentity& ent) const noexcept;
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
bool assign_component(const entity& ent, Args&&... args);
|
bool assign_component(const uentity& ent, Args&&... args);
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool remove_component(const entity& ent);
|
bool remove_component(const uentity& ent);
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool exists_component(const const_entity& ent) const noexcept;
|
bool exists_component(const const_uentity& ent) const noexcept;
|
||||||
|
|
||||||
std::size_t remove_all_components(const entity& ent) noexcept;
|
std::size_t remove_all_components(const uentity& ent) noexcept;
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
T& get_component(const entity& ent);
|
T& get_component(const uentity& ent);
|
||||||
template < typename T >
|
template < typename T >
|
||||||
const T& get_component(const const_entity& ent) const;
|
const T& get_component(const const_uentity& ent) const;
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
T* find_component(const entity& ent) noexcept;
|
T* find_component(const uentity& ent) noexcept;
|
||||||
template < typename T >
|
template < typename T >
|
||||||
const T* find_component(const const_entity& ent) const noexcept;
|
const T* find_component(const const_uentity& ent) const noexcept;
|
||||||
|
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<Ts&...> get_components(const entity& ent);
|
std::tuple<Ts&...> get_components(const uentity& ent);
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<const Ts&...> get_components(const const_entity& ent) const;
|
std::tuple<const Ts&...> get_components(const const_uentity& ent) const;
|
||||||
|
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<Ts*...> find_components(const entity& ent) noexcept;
|
std::tuple<Ts*...> find_components(const uentity& ent) noexcept;
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<const Ts*...> find_components(const const_entity& ent) const noexcept;
|
std::tuple<const Ts*...> find_components(const const_uentity& ent) const noexcept;
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
std::size_t component_count() const noexcept;
|
||||||
|
template < typename T >
|
||||||
|
std::size_t entity_component_count(const const_uentity& ent) const noexcept;
|
||||||
|
|
||||||
template < typename F >
|
template < typename F >
|
||||||
void for_each_entity(F&& f);
|
void for_each_entity(F&& f);
|
||||||
@@ -853,22 +917,30 @@ namespace ecs_hpp
|
|||||||
private:
|
private:
|
||||||
template < typename T >
|
template < typename T >
|
||||||
detail::component_storage<T>* find_storage_() noexcept;
|
detail::component_storage<T>* find_storage_() noexcept;
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
const detail::component_storage<T>* find_storage_() const noexcept;
|
const detail::component_storage<T>* find_storage_() const noexcept;
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
detail::component_storage<T>& get_or_create_storage_();
|
detail::component_storage<T>& get_or_create_storage_();
|
||||||
|
|
||||||
template < typename T >
|
template < typename T
|
||||||
T* find_component_impl_(const entity& ent) noexcept;
|
, typename... Ts
|
||||||
template < typename T >
|
, typename F
|
||||||
const T* find_component_impl_(const const_entity& ent) const noexcept;
|
, std::size_t I
|
||||||
|
, std::size_t... Is >
|
||||||
|
void for_joined_components_impl_(
|
||||||
|
F&& f,
|
||||||
|
std::index_sequence<I, Is...> iseq);
|
||||||
|
|
||||||
template < typename T, typename... Ts, typename F, std::size_t I, std::size_t... Is >
|
template < typename T
|
||||||
void for_joined_components_impl_(F&& f, std::index_sequence<I, Is...> iseq);
|
, typename... Ts
|
||||||
|
, typename F
|
||||||
template < typename T, typename... Ts, typename F, std::size_t I, std::size_t... Is >
|
, std::size_t I
|
||||||
void for_joined_components_impl_(F&& f, std::index_sequence<I, Is...> iseq) const;
|
, std::size_t... Is >
|
||||||
|
void for_joined_components_impl_(
|
||||||
|
F&& f,
|
||||||
|
std::index_sequence<I, Is...> iseq) const;
|
||||||
|
|
||||||
template < typename T
|
template < typename T
|
||||||
, typename... Ts
|
, typename... Ts
|
||||||
@@ -876,7 +948,7 @@ namespace ecs_hpp
|
|||||||
, typename Ss
|
, typename Ss
|
||||||
, typename... Cs >
|
, typename... Cs >
|
||||||
void for_joined_components_impl_(
|
void for_joined_components_impl_(
|
||||||
const entity& e,
|
const uentity& e,
|
||||||
const F& f,
|
const F& f,
|
||||||
const Ss& ss,
|
const Ss& ss,
|
||||||
Cs&... cs);
|
Cs&... cs);
|
||||||
@@ -887,21 +959,21 @@ namespace ecs_hpp
|
|||||||
, typename Ss
|
, typename Ss
|
||||||
, typename... Cs >
|
, typename... Cs >
|
||||||
void for_joined_components_impl_(
|
void for_joined_components_impl_(
|
||||||
const const_entity& e,
|
const const_uentity& e,
|
||||||
const F& f,
|
const F& f,
|
||||||
const Ss& ss,
|
const Ss& ss,
|
||||||
const Cs&... cs) const;
|
const Cs&... cs) const;
|
||||||
|
|
||||||
template < typename F, typename... Cs >
|
template < typename F, typename... Cs >
|
||||||
void for_joined_components_impl_(
|
void for_joined_components_impl_(
|
||||||
const entity& e,
|
const uentity& e,
|
||||||
const F& f,
|
const F& f,
|
||||||
const std::tuple<>& ss,
|
const std::tuple<>& ss,
|
||||||
Cs&... cs);
|
Cs&... cs);
|
||||||
|
|
||||||
template < typename F, typename... Cs >
|
template < typename F, typename... Cs >
|
||||||
void for_joined_components_impl_(
|
void for_joined_components_impl_(
|
||||||
const const_entity& e,
|
const const_uentity& e,
|
||||||
const F& f,
|
const F& f,
|
||||||
const std::tuple<>& ss,
|
const std::tuple<>& ss,
|
||||||
const Cs&... cs) const;
|
const Cs&... cs) const;
|
||||||
@@ -946,72 +1018,72 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool entity::destroy() {
|
inline bool entity::destroy() {
|
||||||
return (*owner_).destroy_entity(*this);
|
return (*owner_).destroy_entity(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool entity::alive() const noexcept {
|
inline bool entity::alive() const noexcept {
|
||||||
return detail::as_const(*owner_).alive_entity(*this);
|
return detail::as_const(*owner_).alive_entity(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
bool entity::assign_component(Args&&... args) {
|
bool entity::assign_component(Args&&... args) {
|
||||||
return (*owner_).assign_component<T>(
|
return (*owner_).assign_component<T>(
|
||||||
*this,
|
id_,
|
||||||
std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool entity::remove_component() {
|
bool entity::remove_component() {
|
||||||
return (*owner_).remove_component<T>(*this);
|
return (*owner_).remove_component<T>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool entity::exists_component() const noexcept {
|
bool entity::exists_component() const noexcept {
|
||||||
return detail::as_const(*owner_).exists_component<T>(*this);
|
return detail::as_const(*owner_).exists_component<T>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::size_t entity::remove_all_components() noexcept {
|
inline std::size_t entity::remove_all_components() noexcept {
|
||||||
return (*owner_).remove_all_components(*this);
|
return (*owner_).remove_all_components(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
T& entity::get_component() {
|
T& entity::get_component() {
|
||||||
return (*owner_).get_component<T>(*this);
|
return (*owner_).get_component<T>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
const T& entity::get_component() const {
|
const T& entity::get_component() const {
|
||||||
return detail::as_const(*owner_).get_component<T>(*this);
|
return detail::as_const(*owner_).get_component<T>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
T* entity::find_component() noexcept {
|
T* entity::find_component() noexcept {
|
||||||
return (*owner_).find_component<T>(*this);
|
return (*owner_).find_component<T>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
const T* entity::find_component() const noexcept {
|
const T* entity::find_component() const noexcept {
|
||||||
return detail::as_const(*owner_).find_component<T>(*this);
|
return detail::as_const(*owner_).find_component<T>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<Ts&...> entity::get_components() {
|
std::tuple<Ts&...> entity::get_components() {
|
||||||
return (*owner_).get_components<Ts...>(*this);
|
return (*owner_).get_components<Ts...>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<const Ts&...> entity::get_components() const {
|
std::tuple<const Ts&...> entity::get_components() const {
|
||||||
return detail::as_const(*owner_).get_components<Ts...>(*this);
|
return detail::as_const(*owner_).get_components<Ts...>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<Ts*...> entity::find_components() noexcept {
|
std::tuple<Ts*...> entity::find_components() noexcept {
|
||||||
return (*owner_).find_components<Ts...>(*this);
|
return (*owner_).find_components<Ts...>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<const Ts*...> entity::find_components() const noexcept {
|
std::tuple<const Ts*...> entity::find_components() const noexcept {
|
||||||
return detail::as_const(*owner_).find_components<Ts...>(*this);
|
return detail::as_const(*owner_).find_components<Ts...>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator==(const entity& l, const entity& r) noexcept {
|
inline bool operator==(const entity& l, const entity& r) noexcept {
|
||||||
@@ -1052,32 +1124,32 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool const_entity::alive() const noexcept {
|
inline bool const_entity::alive() const noexcept {
|
||||||
return (*owner_).alive_entity(*this);
|
return (*owner_).alive_entity(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool const_entity::exists_component() const noexcept {
|
bool const_entity::exists_component() const noexcept {
|
||||||
return (*owner_).exists_component<T>(*this);
|
return (*owner_).exists_component<T>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
const T& const_entity::get_component() const {
|
const T& const_entity::get_component() const {
|
||||||
return (*owner_).get_component<T>(*this);
|
return (*owner_).get_component<T>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
const T* const_entity::find_component() const noexcept {
|
const T* const_entity::find_component() const noexcept {
|
||||||
return (*owner_).find_component<T>(*this);
|
return (*owner_).find_component<T>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<const Ts&...> const_entity::get_components() const {
|
std::tuple<const Ts&...> const_entity::get_components() const {
|
||||||
return (*owner_).get_components<Ts...>(*this);
|
return (*owner_).get_components<Ts...>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<const Ts*...> const_entity::find_components() const noexcept {
|
std::tuple<const Ts*...> const_entity::find_components() const noexcept {
|
||||||
return (*owner_).find_components<Ts...>(*this);
|
return (*owner_).find_components<Ts...>(id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator==(const const_entity& l, const const_entity& r) noexcept {
|
inline bool operator==(const const_entity& l, const const_entity& r) noexcept {
|
||||||
@@ -1098,86 +1170,184 @@ namespace ecs_hpp
|
|||||||
|
|
||||||
namespace ecs_hpp
|
namespace ecs_hpp
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// registry::uentity
|
||||||
|
//
|
||||||
|
|
||||||
|
inline registry::uentity::uentity(registry& owner, entity_id id) noexcept
|
||||||
|
: id_(id)
|
||||||
|
, owner_(&owner) {}
|
||||||
|
|
||||||
|
inline registry::uentity::uentity(entity_id ent) noexcept
|
||||||
|
: id_(ent) {}
|
||||||
|
|
||||||
|
inline registry::uentity::uentity(entity ent) noexcept
|
||||||
|
: id_(ent.id())
|
||||||
|
, owner_(&ent.owner()) {}
|
||||||
|
|
||||||
|
inline registry::uentity::operator entity_id() const noexcept {
|
||||||
|
return id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline registry::uentity::operator entity() const noexcept {
|
||||||
|
assert(owner_);
|
||||||
|
return {*owner_, id_};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline registry::uentity::operator const_entity() const noexcept {
|
||||||
|
assert(owner_);
|
||||||
|
return {*owner_, id_};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline entity_id registry::uentity::id() const noexcept {
|
||||||
|
return id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline registry* registry::uentity::owner() noexcept {
|
||||||
|
return owner_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const registry* registry::uentity::owner() const noexcept {
|
||||||
|
return owner_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool registry::uentity::check_owner(const registry* owner) const noexcept {
|
||||||
|
return !owner_ || owner_ == owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// registry::const_uentity
|
||||||
|
//
|
||||||
|
|
||||||
|
inline registry::const_uentity::const_uentity(const registry& owner, entity_id id) noexcept
|
||||||
|
: id_(id)
|
||||||
|
, owner_(&owner) {}
|
||||||
|
|
||||||
|
inline registry::const_uentity::const_uentity(entity_id ent) noexcept
|
||||||
|
: id_(ent) {}
|
||||||
|
|
||||||
|
inline registry::const_uentity::const_uentity(entity ent) noexcept
|
||||||
|
: id_(ent.id())
|
||||||
|
, owner_(&ent.owner()) {}
|
||||||
|
|
||||||
|
inline registry::const_uentity::const_uentity(const_entity ent) noexcept
|
||||||
|
: id_(ent.id())
|
||||||
|
, owner_(&ent.owner()) {}
|
||||||
|
|
||||||
|
inline registry::const_uentity::const_uentity(const uentity& ent) noexcept
|
||||||
|
: id_(ent.id())
|
||||||
|
, owner_(ent.owner()) {}
|
||||||
|
|
||||||
|
inline registry::const_uentity::operator entity_id() const noexcept {
|
||||||
|
return id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline registry::const_uentity::operator const_entity() const noexcept {
|
||||||
|
assert(owner_);
|
||||||
|
return {*owner_, id_};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline entity_id registry::const_uentity::id() const noexcept {
|
||||||
|
return id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const registry* registry::const_uentity::owner() const noexcept {
|
||||||
|
return owner_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool registry::const_uentity::check_owner(const registry* owner) const noexcept {
|
||||||
|
return !owner_ || owner_ == owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// registry
|
||||||
|
//
|
||||||
|
|
||||||
inline entity registry::create_entity() {
|
inline entity registry::create_entity() {
|
||||||
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);
|
||||||
auto ent = entity(*this, new_ent_id);
|
|
||||||
entity_ids_.insert(new_ent_id);
|
entity_ids_.insert(new_ent_id);
|
||||||
free_entity_ids_.pop_back();
|
free_entity_ids_.pop_back();
|
||||||
return ent;
|
return {*this, new_ent_id};
|
||||||
|
|
||||||
}
|
}
|
||||||
if ( last_entity_id_ < detail::entity_id_index_mask ) {
|
if ( last_entity_id_ < detail::entity_id_index_mask ) {
|
||||||
auto ent = entity(*this, ++last_entity_id_);
|
entity_ids_.insert(last_entity_id_ + 1);
|
||||||
entity_ids_.insert(ent.id());
|
return {*this, ++last_entity_id_};
|
||||||
return ent;
|
|
||||||
}
|
}
|
||||||
throw std::logic_error("ecs_hpp::registry (entity index overlow)");
|
throw std::logic_error("ecs_hpp::registry (entity index overlow)");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool registry::destroy_entity(const entity& ent) {
|
inline bool registry::destroy_entity(const uentity& ent) {
|
||||||
|
assert(ent.check_owner(this));
|
||||||
remove_all_components(ent);
|
remove_all_components(ent);
|
||||||
if ( entity_ids_.unordered_erase(ent.id()) ) {
|
if ( entity_ids_.unordered_erase(ent) ) {
|
||||||
free_entity_ids_.push_back(ent.id());
|
free_entity_ids_.push_back(ent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool registry::alive_entity(const const_entity& ent) const noexcept {
|
inline bool registry::alive_entity(const const_uentity& ent) const noexcept {
|
||||||
return entity_ids_.has(ent.id());
|
assert(ent.check_owner(this));
|
||||||
|
return entity_ids_.has(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
bool registry::assign_component(const entity& ent, Args&&... args) {
|
bool registry::assign_component(const uentity& ent, Args&&... args) {
|
||||||
|
assert(ent.check_owner(this));
|
||||||
if ( !alive_entity(ent) ) {
|
if ( !alive_entity(ent) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
get_or_create_storage_<T>().assign(
|
get_or_create_storage_<T>().assign(
|
||||||
ent.id(),
|
ent,
|
||||||
std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool registry::remove_component(const entity& ent) {
|
bool registry::remove_component(const uentity& ent) {
|
||||||
|
assert(ent.check_owner(this));
|
||||||
if ( !alive_entity(ent) ) {
|
if ( !alive_entity(ent) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
detail::component_storage<T>* storage = find_storage_<T>();
|
detail::component_storage<T>* storage = find_storage_<T>();
|
||||||
return storage
|
return storage
|
||||||
? storage->remove(ent.id())
|
? storage->remove(ent)
|
||||||
: false;
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
bool registry::exists_component(const const_entity& ent) const noexcept {
|
bool registry::exists_component(const const_uentity& ent) const noexcept {
|
||||||
|
assert(ent.check_owner(this));
|
||||||
if ( !alive_entity(ent) ) {
|
if ( !alive_entity(ent) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const detail::component_storage<T>* storage = find_storage_<T>();
|
const detail::component_storage<T>* storage = find_storage_<T>();
|
||||||
return storage
|
return storage
|
||||||
? storage->exists(ent.id())
|
? storage->exists(ent)
|
||||||
: false;
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::size_t registry::remove_all_components(const entity& ent) noexcept {
|
inline std::size_t registry::remove_all_components(const uentity& ent) noexcept {
|
||||||
|
assert(ent.check_owner(this));
|
||||||
if ( !alive_entity(ent) ) {
|
if ( !alive_entity(ent) ) {
|
||||||
return 0u;
|
return 0u;
|
||||||
}
|
}
|
||||||
std::size_t removed_components = 0u;
|
std::size_t removed_count = 0u;
|
||||||
for ( const auto family_id : storages_ ) {
|
for ( const auto family_id : storages_ ) {
|
||||||
if ( storages_.get(family_id)->remove(ent.id()) ) {
|
if ( storages_.get(family_id)->remove(ent) ) {
|
||||||
++removed_components;
|
++removed_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return removed_components;
|
return removed_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
T& registry::get_component(const entity& ent) {
|
T& registry::get_component(const uentity& ent) {
|
||||||
T* component = find_component_impl_<T>(ent);
|
assert(ent.check_owner(this));
|
||||||
|
T* component = find_component<T>(ent);
|
||||||
if ( component ) {
|
if ( component ) {
|
||||||
return *component;
|
return *component;
|
||||||
}
|
}
|
||||||
@@ -1185,8 +1355,9 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
const T& registry::get_component(const const_entity& ent) const {
|
const T& registry::get_component(const const_uentity& ent) const {
|
||||||
const T* component = find_component_impl_<T>(ent);
|
assert(ent.check_owner(this));
|
||||||
|
const T* component = find_component<T>(ent);
|
||||||
if ( component ) {
|
if ( component ) {
|
||||||
return *component;
|
return *component;
|
||||||
}
|
}
|
||||||
@@ -1194,46 +1365,81 @@ namespace ecs_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
T* registry::find_component(const entity& ent) noexcept {
|
T* registry::find_component(const uentity& ent) noexcept {
|
||||||
return find_component_impl_<T>(ent);
|
assert(ent.check_owner(this));
|
||||||
|
detail::component_storage<T>* storage = find_storage_<T>();
|
||||||
|
return storage
|
||||||
|
? storage->find(ent)
|
||||||
|
: nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
const T* registry::find_component(const const_entity& ent) const noexcept {
|
const T* registry::find_component(const const_uentity& ent) const noexcept {
|
||||||
return find_component_impl_<T>(ent);
|
assert(ent.check_owner(this));
|
||||||
|
const detail::component_storage<T>* storage = find_storage_<T>();
|
||||||
|
return storage
|
||||||
|
? storage->find(ent)
|
||||||
|
: nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Ts >
|
template < typename... Ts >
|
||||||
std::tuple<Ts&...> registry::get_components(const entity& ent) {
|
std::tuple<Ts&...> registry::get_components(const uentity& ent) {
|
||||||
|
assert(ent.check_owner(this));
|
||||||
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_entity& ent) const {
|
std::tuple<const Ts&...> registry::get_components(const const_uentity& ent) const {
|
||||||
|
assert(ent.check_owner(this));
|
||||||
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 entity& ent) noexcept {
|
std::tuple<Ts*...> registry::find_components(const uentity& ent) noexcept {
|
||||||
|
assert(ent.check_owner(this));
|
||||||
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_entity& ent) const noexcept {
|
std::tuple<const Ts*...> registry::find_components(const const_uentity& ent) const noexcept {
|
||||||
|
assert(ent.check_owner(this));
|
||||||
return std::make_tuple(find_component<Ts>(ent)...);
|
return std::make_tuple(find_component<Ts>(ent)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
std::size_t registry::component_count() const noexcept {
|
||||||
|
const detail::component_storage<T>* storage = find_storage_<T>();
|
||||||
|
return storage
|
||||||
|
? storage->count()
|
||||||
|
: 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T >
|
||||||
|
std::size_t registry::entity_component_count(const const_uentity& ent) const noexcept {
|
||||||
|
assert(ent.check_owner(this));
|
||||||
|
if ( !alive_entity(ent) ) {
|
||||||
|
return 0u;
|
||||||
|
}
|
||||||
|
std::size_t component_count = 0u;
|
||||||
|
for ( const auto family_id : storages_ ) {
|
||||||
|
if ( storages_.get(family_id)->has(ent) ) {
|
||||||
|
++component_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return component_count;
|
||||||
|
}
|
||||||
|
|
||||||
template < typename F >
|
template < typename F >
|
||||||
void registry::for_each_entity(F&& f) {
|
void registry::for_each_entity(F&& f) {
|
||||||
for ( const auto id : entity_ids_ ) {
|
for ( const auto id : entity_ids_ ) {
|
||||||
f(entity(*this, id));
|
f({*this, id});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename F >
|
template < typename F >
|
||||||
void registry::for_each_entity(F&& f) const {
|
void registry::for_each_entity(F&& f) const {
|
||||||
for ( const auto id : entity_ids_ ) {
|
for ( const auto id : entity_ids_ ) {
|
||||||
f(const_entity(*this, id));
|
f({*this, id});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1241,7 +1447,9 @@ namespace ecs_hpp
|
|||||||
void registry::for_each_component(F&& f) {
|
void registry::for_each_component(F&& f) {
|
||||||
detail::component_storage<T>* storage = find_storage_<T>();
|
detail::component_storage<T>* storage = find_storage_<T>();
|
||||||
if ( storage ) {
|
if ( storage ) {
|
||||||
storage->for_each_component(std::forward<F>(f));
|
storage->for_each_component([this, &f](const entity_id e, T& t){
|
||||||
|
f(uentity{*this, e}, t);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1249,7 +1457,9 @@ namespace ecs_hpp
|
|||||||
void registry::for_each_component(F&& f) const {
|
void registry::for_each_component(F&& f) const {
|
||||||
const detail::component_storage<T>* storage = find_storage_<T>();
|
const detail::component_storage<T>* storage = find_storage_<T>();
|
||||||
if ( storage ) {
|
if ( storage ) {
|
||||||
storage->for_each_component(std::forward<F>(f));
|
storage->for_each_component([this, &f](const entity_id e, const T& t){
|
||||||
|
f(const_uentity{*this, e}, t);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1313,22 +1523,6 @@ namespace ecs_hpp
|
|||||||
storages_.get(family).get());
|
storages_.get(family).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
T* registry::find_component_impl_(const entity& ent) noexcept {
|
|
||||||
detail::component_storage<T>* storage = find_storage_<T>();
|
|
||||||
return storage
|
|
||||||
? storage->find(ent.id())
|
|
||||||
: nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
const T* registry::find_component_impl_(const const_entity& ent) const noexcept {
|
|
||||||
const detail::component_storage<T>* storage = find_storage_<T>();
|
|
||||||
return storage
|
|
||||||
? storage->find(ent.id())
|
|
||||||
: nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T
|
template < typename T
|
||||||
, typename... Ts
|
, typename... Ts
|
||||||
, typename F
|
, typename F
|
||||||
@@ -1341,7 +1535,7 @@ namespace ecs_hpp
|
|||||||
(void)iseq;
|
(void)iseq;
|
||||||
const auto ss = std::make_tuple(find_storage_<Ts>()...);
|
const auto ss = std::make_tuple(find_storage_<Ts>()...);
|
||||||
if ( !detail::tuple_contains(ss, nullptr) ) {
|
if ( !detail::tuple_contains(ss, nullptr) ) {
|
||||||
for_each_component<T>([this, &f, &ss](const entity& e, T& t) {
|
for_each_component<T>([this, &f, &ss](const uentity& e, T& t) {
|
||||||
for_joined_components_impl_<Ts...>(e, f, ss, t);
|
for_joined_components_impl_<Ts...>(e, f, ss, t);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1359,7 +1553,7 @@ namespace ecs_hpp
|
|||||||
(void)iseq;
|
(void)iseq;
|
||||||
const auto ss = std::make_tuple(find_storage_<Ts>()...);
|
const auto ss = std::make_tuple(find_storage_<Ts>()...);
|
||||||
if ( !detail::tuple_contains(ss, nullptr) ) {
|
if ( !detail::tuple_contains(ss, nullptr) ) {
|
||||||
for_each_component<T>([this, &f, &ss](const const_entity& e, const T& t) {
|
for_each_component<T>([this, &f, &ss](const const_uentity& e, const T& t) {
|
||||||
detail::as_const(*this).for_joined_components_impl_<Ts...>(e, f, ss, t);
|
detail::as_const(*this).for_joined_components_impl_<Ts...>(e, f, ss, t);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1371,12 +1565,12 @@ namespace ecs_hpp
|
|||||||
, typename Ss
|
, typename Ss
|
||||||
, typename... Cs >
|
, typename... Cs >
|
||||||
void registry::for_joined_components_impl_(
|
void registry::for_joined_components_impl_(
|
||||||
const entity& e,
|
const uentity& e,
|
||||||
const F& f,
|
const F& f,
|
||||||
const Ss& ss,
|
const Ss& ss,
|
||||||
Cs&... cs)
|
Cs&... cs)
|
||||||
{
|
{
|
||||||
T* c = std::get<0>(ss)->find(e.id());
|
T* c = std::get<0>(ss)->find(e);
|
||||||
if ( c ) {
|
if ( c ) {
|
||||||
for_joined_components_impl_<Ts...>(
|
for_joined_components_impl_<Ts...>(
|
||||||
e,
|
e,
|
||||||
@@ -1393,12 +1587,12 @@ namespace ecs_hpp
|
|||||||
, typename Ss
|
, typename Ss
|
||||||
, typename... Cs >
|
, typename... Cs >
|
||||||
void registry::for_joined_components_impl_(
|
void registry::for_joined_components_impl_(
|
||||||
const const_entity& e,
|
const const_uentity& e,
|
||||||
const F& f,
|
const F& f,
|
||||||
const Ss& ss,
|
const Ss& ss,
|
||||||
const Cs&... cs) const
|
const Cs&... cs) const
|
||||||
{
|
{
|
||||||
const T* c = std::get<0>(ss)->find(e.id());
|
const T* c = std::get<0>(ss)->find(e);
|
||||||
if ( c ) {
|
if ( c ) {
|
||||||
for_joined_components_impl_<Ts...>(
|
for_joined_components_impl_<Ts...>(
|
||||||
e,
|
e,
|
||||||
@@ -1411,7 +1605,7 @@ namespace ecs_hpp
|
|||||||
|
|
||||||
template < typename F, typename... Cs >
|
template < typename F, typename... Cs >
|
||||||
void registry::for_joined_components_impl_(
|
void registry::for_joined_components_impl_(
|
||||||
const entity& e,
|
const uentity& e,
|
||||||
const F& f,
|
const F& f,
|
||||||
const std::tuple<>& ss,
|
const std::tuple<>& ss,
|
||||||
Cs&... cs)
|
Cs&... cs)
|
||||||
@@ -1422,7 +1616,7 @@ namespace ecs_hpp
|
|||||||
|
|
||||||
template < typename F, typename... Cs >
|
template < typename F, typename... Cs >
|
||||||
void registry::for_joined_components_impl_(
|
void registry::for_joined_components_impl_(
|
||||||
const const_entity& e,
|
const const_uentity& e,
|
||||||
const F& f,
|
const F& f,
|
||||||
const std::tuple<>& ss,
|
const std::tuple<>& ss,
|
||||||
const Cs&... cs) const
|
const Cs&... cs) const
|
||||||
|
|||||||
@@ -372,13 +372,21 @@ TEST_CASE("registry") {
|
|||||||
{
|
{
|
||||||
REQUIRE_FALSE(w.exists_component<position_c>(e1));
|
REQUIRE_FALSE(w.exists_component<position_c>(e1));
|
||||||
REQUIRE_FALSE(w.exists_component<velocity_c>(e1));
|
REQUIRE_FALSE(w.exists_component<velocity_c>(e1));
|
||||||
|
REQUIRE_FALSE(w.component_count<position_c>());
|
||||||
|
REQUIRE_FALSE(w.entity_component_count<position_c>(e1));
|
||||||
|
|
||||||
REQUIRE(w.assign_component<position_c>(e1));
|
REQUIRE(w.assign_component<position_c>(e1));
|
||||||
|
|
||||||
REQUIRE(w.exists_component<position_c>(e1));
|
REQUIRE(w.exists_component<position_c>(e1));
|
||||||
REQUIRE_FALSE(w.exists_component<velocity_c>(e1));
|
REQUIRE_FALSE(w.exists_component<velocity_c>(e1));
|
||||||
|
REQUIRE(w.component_count<position_c>() == 1u);
|
||||||
|
REQUIRE(w.component_count<velocity_c>() == 0u);
|
||||||
|
REQUIRE(w.entity_component_count<position_c>(e1) == 1u);
|
||||||
|
|
||||||
REQUIRE(w.assign_component<velocity_c>(e1));
|
REQUIRE(w.assign_component<velocity_c>(e1));
|
||||||
|
REQUIRE(w.component_count<position_c>() == 1u);
|
||||||
|
REQUIRE(w.component_count<velocity_c>() == 1u);
|
||||||
|
REQUIRE(w.entity_component_count<position_c>(e1) == 2u);
|
||||||
|
|
||||||
REQUIRE(w.exists_component<position_c>(e1));
|
REQUIRE(w.exists_component<position_c>(e1));
|
||||||
REQUIRE(w.exists_component<velocity_c>(e1));
|
REQUIRE(w.exists_component<velocity_c>(e1));
|
||||||
@@ -387,6 +395,9 @@ TEST_CASE("registry") {
|
|||||||
|
|
||||||
REQUIRE_FALSE(w.exists_component<position_c>(e1));
|
REQUIRE_FALSE(w.exists_component<position_c>(e1));
|
||||||
REQUIRE_FALSE(w.exists_component<velocity_c>(e1));
|
REQUIRE_FALSE(w.exists_component<velocity_c>(e1));
|
||||||
|
REQUIRE_FALSE(w.component_count<position_c>());
|
||||||
|
REQUIRE_FALSE(w.component_count<velocity_c>());
|
||||||
|
REQUIRE_FALSE(w.entity_component_count<position_c>(e1));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -402,6 +413,11 @@ 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());
|
||||||
|
|
||||||
|
REQUIRE_FALSE(e1.exists_component<position_c>());
|
||||||
|
REQUIRE_FALSE(e1.exists_component<velocity_c>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -608,6 +624,17 @@ TEST_CASE("registry") {
|
|||||||
e2.assign_component<position_c>(5, 6);
|
e2.assign_component<position_c>(5, 6);
|
||||||
e2.assign_component<velocity_c>(7, 8);
|
e2.assign_component<velocity_c>(7, 8);
|
||||||
|
|
||||||
|
{
|
||||||
|
ecs::entity_id acc1 = 0;
|
||||||
|
int acc2 = 0;
|
||||||
|
w.for_each_component<position_c>([&acc1, &acc2](ecs::entity_id id, position_c& p){
|
||||||
|
acc1 += id;
|
||||||
|
acc2 += p.x;
|
||||||
|
});
|
||||||
|
REQUIRE(acc1 == e1.id() + e2.id());
|
||||||
|
REQUIRE(acc2 == 6);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ecs::entity_id acc1 = 0;
|
ecs::entity_id acc1 = 0;
|
||||||
int acc2 = 0;
|
int acc2 = 0;
|
||||||
@@ -678,6 +705,19 @@ TEST_CASE("registry") {
|
|||||||
e3.assign_component<position_c>(100, 500);
|
e3.assign_component<position_c>(100, 500);
|
||||||
e4.assign_component<velocity_c>(500, 100);
|
e4.assign_component<velocity_c>(500, 100);
|
||||||
|
|
||||||
|
{
|
||||||
|
ecs::entity_id acc1 = 0;
|
||||||
|
int acc2 = 0;
|
||||||
|
w.for_joined_components<position_c, velocity_c>([&acc1, &acc2](
|
||||||
|
ecs::entity_id id, const position_c& p, const velocity_c& v)
|
||||||
|
{
|
||||||
|
acc1 += id;
|
||||||
|
acc2 += p.x + v.x;
|
||||||
|
});
|
||||||
|
REQUIRE(acc1 == e1.id() + e2.id());
|
||||||
|
REQUIRE(acc2 == 16);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ecs::entity_id acc1 = 0;
|
ecs::entity_id acc1 = 0;
|
||||||
int acc2 = 0;
|
int acc2 = 0;
|
||||||
@@ -693,6 +733,19 @@ TEST_CASE("registry") {
|
|||||||
|
|
||||||
{
|
{
|
||||||
const ecs::registry& ww = w;
|
const ecs::registry& ww = w;
|
||||||
|
{
|
||||||
|
ecs::entity_id acc1 = 0;
|
||||||
|
int acc2 = 0;
|
||||||
|
ww.for_joined_components<position_c, velocity_c>([&acc1, &acc2](
|
||||||
|
ecs::entity_id id, const position_c& p, const velocity_c& v)
|
||||||
|
{
|
||||||
|
acc1 += id;
|
||||||
|
acc2 += p.x + v.x;
|
||||||
|
});
|
||||||
|
REQUIRE(acc1 == e1.id() + e2.id());
|
||||||
|
REQUIRE(acc2 == 16);
|
||||||
|
}
|
||||||
|
{
|
||||||
ecs::entity_id acc1 = 0;
|
ecs::entity_id acc1 = 0;
|
||||||
int acc2 = 0;
|
int acc2 = 0;
|
||||||
ww.for_joined_components<position_c, velocity_c>([&acc1, &acc2](
|
ww.for_joined_components<position_c, velocity_c>([&acc1, &acc2](
|
||||||
@@ -705,6 +758,7 @@ TEST_CASE("registry") {
|
|||||||
REQUIRE(acc2 == 16);
|
REQUIRE(acc2 == 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
{
|
{
|
||||||
ecs::registry w;
|
ecs::registry w;
|
||||||
auto e1 = w.create_entity();
|
auto e1 = w.create_entity();
|
||||||
@@ -753,15 +807,15 @@ TEST_CASE("registry") {
|
|||||||
|
|
||||||
TEST_CASE("example") {
|
TEST_CASE("example") {
|
||||||
struct position_component {
|
struct position_component {
|
||||||
float x{0};
|
float x;
|
||||||
float y{0};
|
float y;
|
||||||
position_component(float nx, float ny)
|
position_component(float nx, float ny)
|
||||||
: x(nx), y(ny) {}
|
: x(nx), y(ny) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct velocity_component {
|
struct velocity_component {
|
||||||
float dx{0};
|
float dx;
|
||||||
float dy{0};
|
float dy;
|
||||||
velocity_component(float ndx, float ndy)
|
velocity_component(float ndx, float ndy)
|
||||||
: dx(ndx), dy(ndy) {}
|
: dx(ndx), dy(ndy) {}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user