-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce AStorage to refactor common code for storages
Linked: #144
- Loading branch information
1 parent
ad04dca
commit 331c583
Showing
9 changed files
with
241 additions
and
429 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
/// | ||
/// @file IStorage.hpp | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @brief | ||
/// @version 1.0.0 | ||
/// @date 2022-10-19 | ||
/// | ||
/// @copyright Copyright (c) ECSTASY 2022 - 2024 | ||
/// | ||
/// | ||
|
||
#ifndef ECSTASY_STORAGE_ASTORAGE_HPP_ | ||
#define ECSTASY_STORAGE_ASTORAGE_HPP_ | ||
|
||
#include <span> | ||
|
||
#include "ecstasy/config.hpp" | ||
#include "ecstasy/resources/entity/Entity.hpp" | ||
#include "ecstasy/storages/IStorage.hpp" | ||
#include "util/BitSet.hpp" | ||
|
||
namespace ecstasy | ||
{ | ||
|
||
/// | ||
/// @brief Abstract class for all components storage. | ||
/// | ||
/// @tparam C Component type. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2024-04-23) | ||
/// | ||
template <typename C> | ||
class AStorage : public IStorage { | ||
public: | ||
/// @brief IsStorage constraint | ||
using Component = C; | ||
|
||
/// @brief @ref ecstasy::query::QueryableObject constraint. | ||
using QueryData = C &; | ||
/// @brief @ref ecstasy::query::ConstQueryableObject constraint. | ||
using ConstQueryData = const C &; | ||
|
||
/// | ||
/// @brief Erase the @b Component instance associated to the given entity. | ||
/// | ||
/// @note Does nothing if the index doesn't match with any component (ie if the entity doesn't have a component | ||
/// @b Component) | ||
/// | ||
/// @param[in] index Index of the entity. | ||
/// | ||
/// @return bool True if the component was erased, false otherwise. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2022-10-19) | ||
/// | ||
virtual bool erase(Entity::Index index) = 0; | ||
|
||
/// | ||
/// @brief Erase multiple @b Component instances associated to the given @p entities. | ||
/// | ||
/// @note Does nothing for entity without attached component (ie if the entity doesn't have a component | ||
/// @b Component) | ||
/// | ||
/// @param[in] entities target entities. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2022-10-21) | ||
/// | ||
void erase(std::span<Entity> entities) override final | ||
{ | ||
for (Entity entity : entities) | ||
erase(entity.getIndex()); | ||
} | ||
|
||
/// | ||
/// @brief Test if the entity index match a @b Component instance. | ||
/// | ||
/// @param[in] index Index of the entity. | ||
/// | ||
/// @return bool True if the entity has a component, false otherwise. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2022-10-19) | ||
/// | ||
constexpr bool contains(Entity::Index index) const noexcept | ||
{ | ||
return (index < getMask().size()) && getMask()[index]; | ||
} | ||
|
||
/// | ||
/// @brief Retrieve the @b Component instance associated to the given entity and perform bound checking. | ||
/// | ||
/// @param[in] index Index of the entity. | ||
/// | ||
/// @return QueryData Reference to the associated component. | ||
/// | ||
/// @throw std::out_of_range If the entity doesn't have the component. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2024-04-23) | ||
/// | ||
Component &at(Entity::Index index) | ||
{ | ||
if (!contains(index)) | ||
throw std::out_of_range("Entity doesn't have the component"); | ||
return (*this)[index]; | ||
} | ||
|
||
/// | ||
/// @brief Retrieve the @b Component instance associated to the given entity and perform bound checking. | ||
/// | ||
/// @param[in] index Index of the entity. | ||
/// | ||
/// @return QueryData Reference to the associated component. | ||
/// | ||
/// @throw std::out_of_range If the entity doesn't have the component. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2024-04-23) | ||
/// | ||
const Component &at(Entity::Index index) const | ||
{ | ||
if (!contains(index)) | ||
throw std::out_of_range("Entity doesn't have the component"); | ||
return (*this)[index]; | ||
} | ||
|
||
/// | ||
/// @brief Retrieve the @b Component instance associated to the given entity. | ||
/// | ||
/// @warning This function may not perform bound checking. For @ref VectorStorage or @ref MarkerStorage it is | ||
/// noexcept but not for @ref MapStorage for example. | ||
/// | ||
/// @param[in] index Index of the entity. | ||
/// | ||
/// @return Component& Reference to the associated component. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2022-10-19) | ||
/// | ||
virtual Component &operator[](Entity::Index index) = 0; | ||
|
||
/// @copydoc operator[](Entity::Index) | ||
/// | ||
/// @note @ref ecstasy::query::QueryableObject constraint. | ||
QueryData getQueryData(Entity::Index index) | ||
{ | ||
return (*this)[index]; | ||
}; | ||
|
||
/// | ||
/// @brief Retrieve the const @b Component instance associated to the given entity. | ||
/// | ||
/// @warning This function may not perform bound checking. For @ref VectorStorage or @ref MarkerStorage it is | ||
/// noexcept but not for @ref MapStorage for example. | ||
/// | ||
/// @param[in] index Index of the entity. | ||
/// | ||
/// @return const Component& Const reference to the associated component. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2022-10-19) | ||
/// | ||
virtual const Component &operator[](Entity::Index index) const = 0; | ||
|
||
/// @copydoc operator[](Entity::Index) | ||
/// | ||
/// @note @ref ecstasy::query::ConstQueryableObject constraint. | ||
ConstQueryData getQueryData(Entity::Index index) const | ||
{ | ||
return (*this)[index]; | ||
}; | ||
}; | ||
|
||
} // namespace ecstasy | ||
|
||
#endif /* !ECSTASY_STORAGE_ASTORAGE_HPP_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,9 +14,7 @@ | |
|
||
#include <unordered_map> | ||
|
||
#include "IStorage.hpp" | ||
#include "ecstasy/resources/entity/Entity.hpp" | ||
#include "util/BitSet.hpp" | ||
#include "AStorage.hpp" | ||
|
||
namespace ecstasy | ||
{ | ||
|
@@ -30,16 +28,9 @@ namespace ecstasy | |
/// @since 1.0.0 (2022-10-19) | ||
/// | ||
template <typename C> | ||
class MapStorage : public IStorage { | ||
class MapStorage : public AStorage<C> { | ||
public: | ||
/// @brief IsStorage constraint | ||
using Component = C; | ||
|
||
/// @brief @ref ecstasy::query::QueryableObject constraint. | ||
using QueryData = C &; | ||
/// @brief @ref ecstasy::query::ConstQueryableObject constraint. | ||
using ConstQueryData = const C &; | ||
|
||
using Component = typename AStorage<C>::Component; | ||
/// | ||
/// @brief Construct a new Map Storage for a given Component type. | ||
/// | ||
|
@@ -81,18 +72,8 @@ namespace ecstasy | |
return _components.emplace(std::make_pair(index, Component(std::forward<Args>(args)...))).first->second; | ||
} | ||
|
||
/// | ||
/// @brief Erase the @b Component instance associated to the given entity. | ||
/// | ||
/// @note Does nothing if the index doesn't match with any component (ie if the entity doesn't have a component | ||
/// @b Component) | ||
/// | ||
/// @param[in] index Index of the entity. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2022-10-19) | ||
/// | ||
bool erase(Entity::Index index) | ||
/// @copydoc AStorage::erase(Entity::Index) | ||
bool erase(Entity::Index index) override final | ||
{ | ||
auto it = _components.find(index); | ||
|
||
|
@@ -104,110 +85,18 @@ namespace ecstasy | |
return false; | ||
} | ||
|
||
/// | ||
/// @brief Erase multiple @b Component instances associated to the given @p entities. | ||
/// | ||
/// @note Does nothing for entity without attached component (ie if the entity doesn't have a component | ||
/// @b Component) | ||
/// | ||
/// @param[in] entities target entities. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2022-10-21) | ||
/// | ||
void erase(std::span<Entity> entities) override final | ||
{ | ||
for (Entity entity : entities) | ||
erase(entity.getIndex()); | ||
} | ||
|
||
/// | ||
/// @brief Retrieve the @b Component instance associated to the given entity. | ||
/// | ||
/// @param[in] index Index of the entity. | ||
/// | ||
/// @return const Component& Const reference to the associated component. | ||
/// | ||
/// @throw std::out_of_range If the entity doesn't have the component. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2022-10-19) | ||
/// | ||
const Component &operator[](Entity::Index index) const | ||
/// @copydoc AStorage::operator[] | ||
Component &operator[](Entity::Index index) override final | ||
{ | ||
return _components.at(index); | ||
} | ||
|
||
/// | ||
/// @brief Retrieve the @b Component instance associated to the given entity. | ||
/// | ||
/// @param[in] index Index of the entity. | ||
/// | ||
/// @return Component& Reference to the associated component. | ||
/// | ||
/// @throw std::out_of_range If the entity doesn't have the component. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2022-10-19) | ||
/// | ||
Component &operator[](Entity::Index index) | ||
/// @copydoc AStorage::operator[] | ||
const Component &operator[](Entity::Index index) const override final | ||
{ | ||
return _components.at(index); | ||
} | ||
|
||
/// | ||
/// @brief Retrieve the @b Component instance associated to the given entity. | ||
/// | ||
/// @note @ref ecstasy::query::QueryableObject constraint. | ||
/// | ||
/// @param[in] index Index of the entity. | ||
/// | ||
/// @return Component& Reference to the associated component. | ||
/// | ||
/// @throw std::out_of_range If the entity doesn't have the component. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2022-10-19) | ||
/// | ||
Component &getQueryData(Entity::Index index) | ||
{ | ||
return _components.at(index); | ||
} | ||
|
||
/// | ||
/// @brief Retrieve the const @b Component instance associated to the given entity. | ||
/// | ||
/// @note @ref ecstasy::query::ConstQueryableObject constraint. | ||
/// | ||
/// @param[in] index Index of the entity. | ||
/// | ||
/// @return const Component& Const reference to the associated component. | ||
/// | ||
/// @throw std::out_of_range If the entity doesn't have the component. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2024-04-03) | ||
/// | ||
const Component &getQueryData(Entity::Index index) const | ||
{ | ||
return _components.at(index); | ||
} | ||
|
||
/// | ||
/// @brief Test if the entity index match a @b Component instance. | ||
/// | ||
/// @param[in] index Index of the entity. | ||
/// | ||
/// @return bool True if the entity has a component, false otherwise. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2022-10-19) | ||
/// | ||
bool contains(Entity::Index index) const | ||
{ | ||
return _components.find(index) != _components.end(); | ||
} | ||
|
||
/// | ||
/// @brief Get the number of @b Component instances. | ||
/// | ||
|
@@ -221,18 +110,7 @@ namespace ecstasy | |
return _components.size(); | ||
} | ||
|
||
/// | ||
/// @brief Get the Component Mask. | ||
/// | ||
/// @note Each bit set to true mean the entity at the bit index has a component @b C. | ||
/// @note @ref ecstasy::query::QueryableObject constraint. | ||
/// @warning The mask might be smaller than the entity count. | ||
/// | ||
/// @return const util::BitSet& Component mask. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2022-10-20) | ||
/// | ||
/// @copydoc IStorage::getMask | ||
constexpr const util::BitSet &getMask() const override final | ||
{ | ||
return _mask; | ||
|
Oops, something went wrong.