Move ecs::entity_accessor to a separate header
This commit is contained in:
parent
8b1157c641
commit
bc63d98d51
2 changed files with 113 additions and 96 deletions
112
libs/ecs/include/psemek/ecs/entity_accessor.hpp
Normal file
112
libs/ecs/include/psemek/ecs/entity_accessor.hpp
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <psemek/ecs/detail/table.hpp>
|
||||||
|
#include <psemek/ecs/entity_accessor.hpp>
|
||||||
|
#include <psemek/util/span.hpp>
|
||||||
|
#include <psemek/util/range.hpp>
|
||||||
|
#include <psemek/util/exception.hpp>
|
||||||
|
#include <psemek/util/type_name.hpp>
|
||||||
|
#include <psemek/util/to_string.hpp>
|
||||||
|
|
||||||
|
#include <typeindex>
|
||||||
|
|
||||||
|
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 = {})
|
||||||
|
: util::exception(util::to_string("Component ", util::type_name(type), " not found for entity ", handle), std::move(stacktrace))
|
||||||
|
, type_(type)
|
||||||
|
, handle_(handle)
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::type_info const & type() const
|
||||||
|
{
|
||||||
|
return type_;
|
||||||
|
}
|
||||||
|
|
||||||
|
entity_handle const & handle() const
|
||||||
|
{
|
||||||
|
return handle_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::type_info const & type_;
|
||||||
|
entity_handle handle_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct entity_accessor
|
||||||
|
{
|
||||||
|
entity_accessor() = default;
|
||||||
|
entity_accessor(entity_accessor const &) = default;
|
||||||
|
|
||||||
|
explicit operator bool() const;
|
||||||
|
|
||||||
|
/** Obtain a pointer to the specified component type
|
||||||
|
* of the accessed entity, or a null pointer if
|
||||||
|
* the entity doesn't contain this component type.
|
||||||
|
*/
|
||||||
|
template <typename Component>
|
||||||
|
Component * get_if();
|
||||||
|
|
||||||
|
/** Obtain a reference to the specified component type
|
||||||
|
* of the accessed entity.
|
||||||
|
* If the entity doesn't contain this component type,
|
||||||
|
* an exception of type `component_not_found_exception` is thrown.
|
||||||
|
*/
|
||||||
|
template <typename Component>
|
||||||
|
Component & get();
|
||||||
|
|
||||||
|
/** Check if the entity contains this component type.
|
||||||
|
*/
|
||||||
|
template <typename Component>
|
||||||
|
bool contains() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
detail::table * table_ = nullptr;
|
||||||
|
std::uint32_t row_ = 0;
|
||||||
|
|
||||||
|
friend struct entity_container;
|
||||||
|
|
||||||
|
entity_accessor(detail::table * table, std::uint32_t row);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline entity_accessor::operator bool() const
|
||||||
|
{
|
||||||
|
return table_ != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Component>
|
||||||
|
Component * entity_accessor::get_if()
|
||||||
|
{
|
||||||
|
util::uuid const uuid = Component::uuid();
|
||||||
|
|
||||||
|
auto column = table_->column(uuid);
|
||||||
|
if (!column)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return reinterpret_cast<Component *>(column->data() + detail::stride<Component>() * row_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Component>
|
||||||
|
Component & entity_accessor::get()
|
||||||
|
{
|
||||||
|
if (auto ptr = get_if<Component>())
|
||||||
|
return *ptr;
|
||||||
|
throw component_not_found_exception(typeid(Component), table_->entity_handles()[row_]);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Component>
|
||||||
|
bool entity_accessor::contains() const
|
||||||
|
{
|
||||||
|
return get_if<Component>() != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline entity_accessor::entity_accessor(detail::table * table, std::uint32_t row)
|
||||||
|
: table_(table)
|
||||||
|
, row_(row)
|
||||||
|
{}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include <psemek/ecs/detail/apply_helper.hpp>
|
#include <psemek/ecs/detail/apply_helper.hpp>
|
||||||
#include <psemek/ecs/detail/all_different_types.hpp>
|
#include <psemek/ecs/detail/all_different_types.hpp>
|
||||||
#include <psemek/ecs/detail/component_uuid_helper.hpp>
|
#include <psemek/ecs/detail/component_uuid_helper.hpp>
|
||||||
|
#include <psemek/ecs/entity_accessor.hpp>
|
||||||
#include <psemek/util/span.hpp>
|
#include <psemek/util/span.hpp>
|
||||||
#include <psemek/util/range.hpp>
|
#include <psemek/util/range.hpp>
|
||||||
#include <psemek/util/exception.hpp>
|
#include <psemek/util/exception.hpp>
|
||||||
|
|
@ -19,66 +20,6 @@ namespace psemek::ecs
|
||||||
|
|
||||||
using query_cache = std::shared_ptr<detail::query_cache>;
|
using query_cache = std::shared_ptr<detail::query_cache>;
|
||||||
|
|
||||||
struct component_not_found_exception
|
|
||||||
: util::exception
|
|
||||||
{
|
|
||||||
component_not_found_exception(std::type_info const & type, entity_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)
|
|
||||||
{}
|
|
||||||
|
|
||||||
std::type_info const & type() const
|
|
||||||
{
|
|
||||||
return type_;
|
|
||||||
}
|
|
||||||
|
|
||||||
entity_handle const & handle() const
|
|
||||||
{
|
|
||||||
return handle_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::type_info const & type_;
|
|
||||||
entity_handle handle_;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct entity_accessor
|
|
||||||
{
|
|
||||||
entity_accessor() = default;
|
|
||||||
entity_accessor(entity_accessor const &) = default;
|
|
||||||
|
|
||||||
explicit operator bool() const;
|
|
||||||
|
|
||||||
/** Obtain a pointer to the specified component type
|
|
||||||
* of the accessed entity, or a null pointer if
|
|
||||||
* the entity doesn't contain this component type.
|
|
||||||
*/
|
|
||||||
template <typename Component>
|
|
||||||
Component * get_if();
|
|
||||||
|
|
||||||
/** Obtain a reference to the specified component type
|
|
||||||
* of the accessed entity.
|
|
||||||
* If the entity doesn't contain this component type,
|
|
||||||
* an exception of type `component_not_found_exception` is thrown.
|
|
||||||
*/
|
|
||||||
template <typename Component>
|
|
||||||
Component & get();
|
|
||||||
|
|
||||||
/** Check if the entity contains this component type.
|
|
||||||
*/
|
|
||||||
template <typename Component>
|
|
||||||
bool contains() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
detail::table * table_ = nullptr;
|
|
||||||
std::uint32_t row_ = 0;
|
|
||||||
|
|
||||||
friend struct entity_container;
|
|
||||||
|
|
||||||
entity_accessor(detail::table * table, std::uint32_t row);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct entity_container
|
struct entity_container
|
||||||
{
|
{
|
||||||
/** Create an entity with the specified components.
|
/** Create an entity with the specified components.
|
||||||
|
|
@ -390,40 +331,4 @@ namespace psemek::ecs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entity_accessor::operator bool() const
|
|
||||||
{
|
|
||||||
return table_ != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Component>
|
|
||||||
Component * entity_accessor::get_if()
|
|
||||||
{
|
|
||||||
util::uuid const uuid = Component::uuid();
|
|
||||||
|
|
||||||
auto column = table_->column(uuid);
|
|
||||||
if (!column)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return reinterpret_cast<Component *>(column->data() + detail::stride<Component>() * row_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Component>
|
|
||||||
Component & entity_accessor::get()
|
|
||||||
{
|
|
||||||
if (auto ptr = get_if<Component>())
|
|
||||||
return *ptr;
|
|
||||||
throw component_not_found_exception(typeid(Component), table_->entity_handles()[row_]);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Component>
|
|
||||||
bool entity_accessor::contains() const
|
|
||||||
{
|
|
||||||
return get_if<Component>() != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline entity_accessor::entity_accessor(detail::table * table, std::uint32_t row)
|
|
||||||
: table_(table)
|
|
||||||
, row_(row)
|
|
||||||
{}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue