Rename ecs::entity_handle -> ecs::handle
This commit is contained in:
parent
d48bbc91a6
commit
95b26d890e
13 changed files with 80 additions and 71 deletions
|
|
@ -16,9 +16,9 @@ namespace psemek::ecs::detail
|
|||
{
|
||||
|
||||
template <typename Function, typename ... Components>
|
||||
void invoke(Function && function, entity_container & parent, entity_handle const & handle, Components & ... components)
|
||||
void invoke(Function && function, entity_container & parent, handle const & handle, Components & ... components)
|
||||
{
|
||||
if constexpr (std::invocable<Function, entity_container &, entity_handle, Components & ...>)
|
||||
if constexpr (std::invocable<Function, entity_container &, ecs::handle, Components & ...>)
|
||||
{
|
||||
function(parent, handle, components...);
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ namespace psemek::ecs::detail
|
|||
{
|
||||
function(parent, components...);
|
||||
}
|
||||
else if constexpr (std::invocable<Function, entity_handle, Components & ...>)
|
||||
else if constexpr (std::invocable<Function, ecs::handle, Components & ...>)
|
||||
{
|
||||
function(handle, components...);
|
||||
}
|
||||
|
|
@ -37,15 +37,15 @@ namespace psemek::ecs::detail
|
|||
}
|
||||
|
||||
template <typename Function, typename ... Components>
|
||||
void batch_invoke(Function && function, entity_container & parent, std::size_t count, entity_handle const * handles, Components * ... components)
|
||||
void batch_invoke(Function && function, entity_container & parent, std::size_t count, handle const * handles, Components * ... components)
|
||||
{
|
||||
util::span<entity_handle const> handles_span{handles, count};
|
||||
util::span<handle const> handles_span{handles, count};
|
||||
|
||||
if constexpr (std::invocable<Function, entity_container &, util::span<entity_handle const>, util::span<Components> ...>)
|
||||
if constexpr (std::invocable<Function, entity_container &, util::span<handle const>, util::span<Components> ...>)
|
||||
{
|
||||
function(parent, handles_span, util::span<Components>{components, is_empty_v<Components> ? 1 : count} ...);
|
||||
}
|
||||
else if constexpr (std::invocable<Function, util::span<entity_handle const>, util::span<Components> ...>)
|
||||
else if constexpr (std::invocable<Function, util::span<handle const>, util::span<Components> ...>)
|
||||
{
|
||||
function(handles_span, util::span<Components>{components, is_empty_v<Components> ? 1 : count} ...);
|
||||
}
|
||||
|
|
@ -64,11 +64,11 @@ namespace psemek::ecs::detail
|
|||
{
|
||||
entity_container & parent;
|
||||
std::size_t row_count;
|
||||
entity_handle const * entity_handles_pointer;
|
||||
handle const * entity_handles_pointer;
|
||||
// (+1) to prevent zero-sized array
|
||||
std::uint8_t * pointers[sizeof...(Components) + 1];
|
||||
|
||||
static_apply_helper(entity_container & parent, util::span<entity_handle const> entity_handles)
|
||||
static_apply_helper(entity_container & parent, util::span<handle const> entity_handles)
|
||||
: parent(parent)
|
||||
, row_count(entity_handles.size())
|
||||
, entity_handles_pointer(entity_handles.data())
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/ecs/entity_handle.hpp>
|
||||
#include <psemek/ecs/detail/id.hpp>
|
||||
#include <psemek/util/span.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
|
|
|||
11
libs/ecs/include/psemek/ecs/detail/id.hpp
Normal file
11
libs/ecs/include/psemek/ecs/detail/id.hpp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace psemek::ecs::detail
|
||||
{
|
||||
|
||||
using entity_id = std::uint32_t;
|
||||
using entity_epoch = std::uint32_t;
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/ecs/entity_handle.hpp>
|
||||
#include <psemek/ecs/handle.hpp>
|
||||
#include <psemek/ecs/detail/component_hash.hpp>
|
||||
#include <psemek/ecs/detail/column.hpp>
|
||||
#include <psemek/util/uuid.hpp>
|
||||
|
|
@ -28,7 +28,7 @@ namespace psemek::ecs::detail
|
|||
|
||||
detail::column * column(util::uuid const & uuid) const;
|
||||
|
||||
util::span<entity_handle const> entity_handles() const
|
||||
util::span<handle const> entity_handles() const
|
||||
{
|
||||
return entity_handles_;
|
||||
}
|
||||
|
|
@ -48,8 +48,8 @@ namespace psemek::ecs::detail
|
|||
return entity_handles_.size();
|
||||
}
|
||||
|
||||
std::size_t push_row(entity_handle handle);
|
||||
std::size_t move_row(entity_handle handle, table * from, std::size_t from_row);
|
||||
std::size_t push_row(handle handle);
|
||||
std::size_t move_row(handle handle, table * from, std::size_t from_row);
|
||||
void swap_rows(std::size_t row1, std::size_t row2);
|
||||
void pop_row();
|
||||
void clear();
|
||||
|
|
@ -70,14 +70,14 @@ namespace psemek::ecs::detail
|
|||
std::unique_ptr<table> clone() const;
|
||||
|
||||
table * get_delayed_table();
|
||||
util::span<entity_handle const> flush_delayed();
|
||||
util::span<handle const> flush_delayed();
|
||||
|
||||
protected:
|
||||
std::size_t hash_;
|
||||
std::vector<std::unique_ptr<detail::column>> columns_;
|
||||
util::hash_map<util::uuid, detail::column *> component_uuid_to_column_;
|
||||
|
||||
std::vector<entity_handle> entity_handles_;
|
||||
std::vector<handle> entity_handles_;
|
||||
|
||||
std::optional<iteration_data> iteration_data_;
|
||||
std::vector<std::uint32_t> remove_queue_;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace psemek::ecs
|
|||
struct component_not_found_exception
|
||||
: util::exception
|
||||
{
|
||||
component_not_found_exception(std::type_info const & type, entity_handle const & handle, boost::stacktrace::stacktrace stacktrace = {})
|
||||
component_not_found_exception(std::type_info const & type, handle const & handle, boost::stacktrace::stacktrace stacktrace = {})
|
||||
: util::exception(util::to_string("Component ", util::type_name(type), " not found for entity ", handle), std::move(stacktrace))
|
||||
, type_(type)
|
||||
, handle_(handle)
|
||||
|
|
@ -27,14 +27,14 @@ namespace psemek::ecs
|
|||
return type_;
|
||||
}
|
||||
|
||||
entity_handle const & handle() const
|
||||
ecs::handle const & handle() const
|
||||
{
|
||||
return handle_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::type_info const & type_;
|
||||
entity_handle handle_;
|
||||
ecs::handle handle_;
|
||||
};
|
||||
|
||||
struct entity_accessor
|
||||
|
|
|
|||
|
|
@ -41,14 +41,14 @@ namespace psemek::ecs
|
|||
* whether the created entity will be visited by iteration or not.
|
||||
*/
|
||||
template <typename ... Components>
|
||||
entity_handle create(Components && ... components);
|
||||
handle create(Components && ... components);
|
||||
|
||||
/** Check if an entity handle refers to an alive entity (i.e. one that wasn't
|
||||
* destroyed yet).
|
||||
* If the handle wasn't previously obtained by a `create()` call, the
|
||||
* behavior is undefined.
|
||||
*/
|
||||
bool alive(entity_handle const & entity) const;
|
||||
bool alive(handle const & entity) const;
|
||||
|
||||
/** Destroy an entity specified by a handle. After the call, `alive()`
|
||||
* returns false for this handle.
|
||||
|
|
@ -58,7 +58,7 @@ namespace psemek::ecs
|
|||
* If the handle wasn't previously obtained by a `create()` call, or
|
||||
* the refered entity was already destroyed, the behavior is undefined.
|
||||
*/
|
||||
void destroy(entity_handle const & entity);
|
||||
void destroy(handle const & entity);
|
||||
|
||||
/** Get an entity accessor for an entity, which provides access to the entity's components.
|
||||
* It is designed to be a single-use object; it cannot be stored as a reference to
|
||||
|
|
@ -68,7 +68,7 @@ namespace psemek::ecs
|
|||
* If the handle wasn't previously obtained by a `create()` call, or
|
||||
* the referred entity was already destroyed, the behavior is undefined.
|
||||
*/
|
||||
entity_accessor get(entity_handle const & entity);
|
||||
entity_accessor get(handle const & entity);
|
||||
|
||||
/** Attach new components to an existing entity, or update existing
|
||||
* components with new values. Other components of this entity
|
||||
|
|
@ -82,7 +82,7 @@ namespace psemek::ecs
|
|||
* the refered entity was already destroyed, the behavior is undefined.
|
||||
*/
|
||||
template <typename ... Components>
|
||||
void attach(entity_handle const & entity, Components && ... components);
|
||||
void attach(handle const & entity, Components && ... components);
|
||||
|
||||
/** Detach (remove) components from an existing entity. Other components of this entity
|
||||
* are left untouched. Detaching a component that doesn't exist does nothing.
|
||||
|
|
@ -95,7 +95,7 @@ namespace psemek::ecs
|
|||
* the refered entity was already destroyed, the behavior is undefined.
|
||||
*/
|
||||
template <typename ... Components>
|
||||
void detach(entity_handle const & entity);
|
||||
void detach(handle const & entity);
|
||||
|
||||
/** Create a query cache that can be used to speed up `apply()` calls.
|
||||
*/
|
||||
|
|
@ -218,12 +218,12 @@ namespace psemek::ecs
|
|||
util::hash_set<util::uuid> uuid_set_helper_;
|
||||
|
||||
detail::table * insert_table(std::vector<std::unique_ptr<detail::column>> columns);
|
||||
void do_destroy(entity_handle const & entity);
|
||||
void do_destroy(handle const & entity);
|
||||
void remove_row(detail::table & table, std::uint32_t row, util::span<detail::entity_data> entities);
|
||||
};
|
||||
|
||||
template <typename ... Components>
|
||||
entity_handle entity_container::create(Components && ... components)
|
||||
handle entity_container::create(Components && ... components)
|
||||
{
|
||||
static_assert(detail::all_different_types_v<Components...>, "all component types must be different");
|
||||
|
||||
|
|
@ -243,7 +243,7 @@ namespace psemek::ecs
|
|||
table = table->get_delayed_table();
|
||||
|
||||
auto id = entity_list_.create(table, table->row_count());
|
||||
entity_handle handle{id, entity_list_.get_entities()[id].epoch};
|
||||
handle handle{id, entity_list_.get_entities()[id].epoch};
|
||||
[[maybe_unused]] entity_accessor accessor = get(handle);
|
||||
|
||||
table->push_row(handle);
|
||||
|
|
@ -253,7 +253,7 @@ namespace psemek::ecs
|
|||
}
|
||||
|
||||
template <typename ... Components>
|
||||
void entity_container::attach(entity_handle const & entity, Components && ... components)
|
||||
void entity_container::attach(handle const & entity, Components && ... components)
|
||||
{
|
||||
static_assert(detail::all_different_types_v<Components...>, "all component types must be different");
|
||||
|
||||
|
|
@ -295,7 +295,7 @@ namespace psemek::ecs
|
|||
}
|
||||
|
||||
template <typename ... Components>
|
||||
void entity_container::detach(entity_handle const & entity)
|
||||
void entity_container::detach(handle const & entity)
|
||||
{
|
||||
static_assert(detail::all_different_types_v<Components...>, "all component types must be different");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
|
||||
namespace psemek::ecs
|
||||
{
|
||||
|
||||
using entity_id = std::uint32_t;
|
||||
using entity_epoch = std::uint32_t;
|
||||
|
||||
struct entity_handle
|
||||
{
|
||||
entity_id id;
|
||||
entity_epoch epoch;
|
||||
};
|
||||
|
||||
inline std::ostream & operator << (std::ostream & out, entity_handle const & handle)
|
||||
{
|
||||
out << '(' << handle.id << ',' << handle.epoch << ')';
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
22
libs/ecs/include/psemek/ecs/handle.hpp
Normal file
22
libs/ecs/include/psemek/ecs/handle.hpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/ecs/detail/id.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace psemek::ecs
|
||||
{
|
||||
|
||||
struct handle
|
||||
{
|
||||
detail::entity_id id;
|
||||
detail::entity_epoch epoch;
|
||||
};
|
||||
|
||||
inline std::ostream & operator << (std::ostream & out, handle const & handle)
|
||||
{
|
||||
out << '(' << handle.id << ',' << handle.epoch << ')';
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ namespace psemek::ecs::detail
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
std::size_t table::push_row(entity_handle handle)
|
||||
std::size_t table::push_row(handle handle)
|
||||
{
|
||||
for (auto & column : columns_)
|
||||
column->push_row();
|
||||
|
|
@ -33,7 +33,7 @@ namespace psemek::ecs::detail
|
|||
return entity_handles_.size() - 1;
|
||||
}
|
||||
|
||||
std::size_t table::move_row(entity_handle handle, table * from, std::size_t from_row)
|
||||
std::size_t table::move_row(handle handle, table * from, std::size_t from_row)
|
||||
{
|
||||
for (auto & column : columns_)
|
||||
{
|
||||
|
|
@ -92,7 +92,7 @@ namespace psemek::ecs::detail
|
|||
return delayed_table_.get();
|
||||
}
|
||||
|
||||
util::span<entity_handle const> table::flush_delayed()
|
||||
util::span<handle const> table::flush_delayed()
|
||||
{
|
||||
if (!delayed_table_)
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -3,18 +3,18 @@
|
|||
namespace psemek::ecs
|
||||
{
|
||||
|
||||
bool entity_container::alive(entity_handle const & entity) const
|
||||
bool entity_container::alive(handle const & entity) const
|
||||
{
|
||||
return entity_list_.get_entities()[entity.id].epoch == entity.epoch;
|
||||
}
|
||||
|
||||
void entity_container::destroy(entity_handle const & entity)
|
||||
void entity_container::destroy(handle const & entity)
|
||||
{
|
||||
do_destroy(entity);
|
||||
entity_list_.destroy(entity.id);
|
||||
}
|
||||
|
||||
entity_accessor entity_container::get(entity_handle const & entity)
|
||||
entity_accessor entity_container::get(handle const & entity)
|
||||
{
|
||||
auto const data = entity_list_.get_entities()[entity.id];
|
||||
return {data.table, data.row};
|
||||
|
|
@ -31,7 +31,7 @@ namespace psemek::ecs
|
|||
return table;
|
||||
}
|
||||
|
||||
void entity_container::do_destroy(entity_handle const & entity)
|
||||
void entity_container::do_destroy(handle const & entity)
|
||||
{
|
||||
auto entities = entity_list_.get_entities();
|
||||
auto & data = entities[entity.id];
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@ test_case(ecs_apply_empty)
|
|||
container.create();
|
||||
|
||||
int call_count = 0;
|
||||
container.apply<>([&](entity_container &, entity_handle const &){ ++call_count; });
|
||||
container.apply<>([&](entity_container &, handle const &){ ++call_count; });
|
||||
container.apply<>([&](entity_container &){ ++call_count; });
|
||||
container.apply<>([&](entity_handle const &){ ++call_count; });
|
||||
container.apply<>([&](handle const &){ ++call_count; });
|
||||
container.apply<>([&]{ ++call_count; });
|
||||
expect_equal(count * 4, call_count);
|
||||
}
|
||||
|
|
@ -119,9 +119,9 @@ test_case(ecs_apply_batch_invoke)
|
|||
container.create(component_1{i});
|
||||
|
||||
int call_count = 0;
|
||||
container.batch_apply<component_1>([&](entity_container &, util::span<entity_handle const>, util::span<component_1> components){ call_count += components.size(); });
|
||||
container.batch_apply<component_1>([&](entity_container &, util::span<handle const>, util::span<component_1> components){ call_count += components.size(); });
|
||||
container.batch_apply<component_1>([&](entity_container &, util::span<component_1> components){ call_count += components.size(); });
|
||||
container.batch_apply<component_1>([&](util::span<entity_handle const>, util::span<component_1> components){ call_count += components.size(); });
|
||||
container.batch_apply<component_1>([&](util::span<handle const>, util::span<component_1> components){ call_count += components.size(); });
|
||||
container.batch_apply<component_1>([&](util::span<component_1> components){ call_count += components.size(); });
|
||||
expect_equal(count * 4, call_count);
|
||||
}
|
||||
|
|
@ -174,7 +174,7 @@ test_case(ecs_apply_remove_forward)
|
|||
{
|
||||
entity_container container;
|
||||
|
||||
std::vector<entity_handle> handles;
|
||||
std::vector<handle> handles;
|
||||
int const count = 1024 * 1024;
|
||||
for (int i = 0; i < count; ++i)
|
||||
handles.push_back(container.create());
|
||||
|
|
@ -195,7 +195,7 @@ test_case(ecs_apply_remove_reversed)
|
|||
{
|
||||
entity_container container;
|
||||
|
||||
std::vector<entity_handle> handles;
|
||||
std::vector<handle> handles;
|
||||
int const count = 1024 * 1024;
|
||||
for (int i = 0; i < count; ++i)
|
||||
handles.push_back(container.create());
|
||||
|
|
@ -220,7 +220,7 @@ test_case(ecs_apply_remove_random)
|
|||
entity_container container;
|
||||
random::generator rng;
|
||||
|
||||
std::vector<entity_handle> handles;
|
||||
std::vector<handle> handles;
|
||||
int const count = 1024 * 1024;
|
||||
for (int i = 0; i < count; ++i)
|
||||
handles.push_back(container.create());
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ test_case(ecs_component_lifetime)
|
|||
random::generator rng;
|
||||
entity_container container;
|
||||
|
||||
std::vector<entity_handle> entities;
|
||||
std::vector<handle> entities;
|
||||
|
||||
for (int i = 0; i < 1024 * 1024; ++i)
|
||||
entities.push_back(container.create(component_counter{std::make_shared<int>(42)}));
|
||||
|
|
|
|||
|
|
@ -114,12 +114,12 @@ test_case(ecs_entity_random)
|
|||
random::generator rng;
|
||||
entity_container container;
|
||||
|
||||
std::vector<std::pair<entity_handle, int>> entities;
|
||||
std::vector<std::pair<handle, int>> entities;
|
||||
|
||||
for (int i = 0; i < 1024 * 1024; ++i)
|
||||
{
|
||||
int value = random::uniform(rng, -1024, 1024);
|
||||
entity_handle handle;
|
||||
handle handle;
|
||||
if (random::uniform<bool>(rng))
|
||||
handle = container.create(component_1{value});
|
||||
else
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue