Rename ecs::entity_handle -> ecs::handle

This commit is contained in:
Nikita Lisitsa 2023-12-16 16:29:10 +03:00
parent d48bbc91a6
commit 95b26d890e
13 changed files with 80 additions and 71 deletions

View file

@ -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())

View file

@ -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>

View 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;
}

View file

@ -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_;

View file

@ -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

View file

@ -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");

View file

@ -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;
}
}

View 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;
}
}

View file

@ -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 {};

View file

@ -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];

View file

@ -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());

View file

@ -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)}));

View file

@ -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