-
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 Serializer.saveEntity method iterating through all entity c…
…omponents Linked: #150
- Loading branch information
1 parent
f2065b5
commit 36502ba
Showing
9 changed files
with
277 additions
and
4 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 |
---|---|---|
|
@@ -1090,6 +1090,19 @@ namespace ecstasy | |
/// | ||
void runSystems(size_t group, size_t mask); | ||
|
||
/// | ||
/// @brief Get a reference to the storages instances. | ||
/// | ||
/// @return constexpr const Instances<IStorage>& Const reference to the storages instance. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2024-06-11) | ||
/// | ||
constexpr const Instances<IStorage> &getStorages() const | ||
{ | ||
return _storages; | ||
} | ||
|
||
private: | ||
Instances<ResourceBase> _resources; | ||
Instances<IStorage> _storages; | ||
|
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 |
---|---|---|
@@ -0,0 +1,125 @@ | ||
/// | ||
/// @file ComponentSerializers.hpp | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @brief | ||
/// @version 1.0.0 | ||
/// @date 2022-10-19 | ||
/// | ||
/// @copyright Copyright (c) ECSTASY 2022 - 2024 | ||
/// | ||
/// | ||
|
||
#ifndef ECSTASY_SERIALIZATION_COMPONENT_SERIALIZERS_HPP_ | ||
#define ECSTASY_SERIALIZATION_COMPONENT_SERIALIZERS_HPP_ | ||
|
||
#include "ecstasy/config.hpp" | ||
#include "ecstasy/serialization/RawSerializer.hpp" | ||
#include "util/meta/Traits.hpp" | ||
#include "ecstasy/serialization/is_serializable.hpp" | ||
|
||
#ifndef ECSTASY_SERIALIZERS | ||
#define ECSTASY_SERIALIZERS util::meta::Traits<ecstasy::serialization::RawSerializer> | ||
#endif | ||
|
||
namespace ecstasy::serialization | ||
{ | ||
class ISerializer; | ||
|
||
using Serializers = ECSTASY_SERIALIZERS; | ||
|
||
/// | ||
/// @brief Serialize a component with the given serializer. Serializer is passed as an ISerializer but with its | ||
/// type_info. | ||
/// | ||
/// @note This struct is used to counter the limit of the C++ language that doesn't allow to have a virtual | ||
/// template. | ||
/// | ||
/// @tparam S Registered serializer types wrapped inside an @ref util::meta::Traits. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2024-06-11) | ||
/// | ||
template <typename S> | ||
struct ComponentSerializer { | ||
static_assert(!std::is_same_v<S, util::meta::Traits<>>, "No serializer registered"); | ||
}; | ||
|
||
/// @copydoc ComponentSerializer | ||
template <typename S1, typename... Ss> | ||
struct ComponentSerializer<util::meta::Traits<S1, Ss...>> { | ||
/// | ||
/// @brief Serialize a component with the given serializer. | ||
/// | ||
/// @note This function will try to serialize the component with each serializer in the list, stopping when the | ||
/// targeted serializer is found (using @p stype). | ||
/// | ||
/// @tparam Comp Component type. | ||
/// | ||
/// @param[in] serializer Serializer to use. | ||
/// @param[in] stype Type of the serializer. | ||
/// @param[in] component Component to serialize. | ||
/// | ||
/// @return ISerializer& The serializer. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2024-06-11) | ||
/// | ||
template <typename Comp> | ||
static ISerializer &serialize(ISerializer &serializer, const std::type_info &stype, const Comp &component) | ||
{ | ||
(trySerialize<S1>(serializer, stype, component) || ... || trySerialize<Ss>(serializer, stype, component)); | ||
return serializer; | ||
} | ||
|
||
/// | ||
/// @brief Try to serialize a component with the given serializer. The serialization is done if S is the same as | ||
/// @p stype. | ||
/// | ||
/// @tparam S Serializer type. | ||
/// @tparam Comp Component type. | ||
/// | ||
/// @param[in] serializer Serializer to use. | ||
/// @param[in] stype Type of the serializer searched. | ||
/// @param[in] component Component to serialize. | ||
/// | ||
/// @return bool True if the component was serialized, false otherwise. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2024-06-11) | ||
/// | ||
template <typename S, typename Comp> | ||
static bool trySerialize(ISerializer &serializer, const std::type_info &stype, const Comp &component) | ||
{ | ||
if constexpr (is_serializable_v<S, Comp>) { | ||
if (stype == typeid(S)) { | ||
dynamic_cast<S &>(serializer).saveEntityComponent(component); | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
}; | ||
|
||
/// | ||
/// @brief Serialize a component with the given serializer if possible. | ||
/// | ||
/// @tparam C Component type. | ||
/// | ||
/// @param[in] serializer Serializer to use. | ||
/// @param[in] stype Type of the serializer. | ||
/// @param[in] component Component to serialize. | ||
/// | ||
/// @return ISerializer& The serializer. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2024-06-11) | ||
/// | ||
template <typename C> | ||
ISerializer &serialize(ISerializer &serializer, const std::type_info &stype, const C &component) | ||
{ | ||
return ComponentSerializer<Serializers>::serialize(serializer, stype, component); | ||
} | ||
|
||
} // namespace ecstasy::serialization | ||
|
||
#endif /* !ECSTASY_SERIALIZATION_COMPONENT_SERIALIZERS_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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,6 +94,25 @@ namespace ecstasy::serialization | |
return object >> inner(); | ||
} | ||
|
||
/// | ||
/// @brief Save an entity component to the serializer. This includes the component type before the component | ||
/// data. | ||
/// | ||
/// @tparam C Component type. | ||
/// | ||
/// @param[in] component Component to save. | ||
/// | ||
/// @return S& Reference to @b this for chain calls. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2024-06-11) | ||
/// | ||
template <typename C> | ||
S &saveEntityComponent(const C &component) | ||
{ | ||
return inner() << typeid(C) << component; | ||
} | ||
|
||
/// | ||
/// @brief Save an entity to the serializer with explicit components. | ||
/// | ||
|
@@ -112,10 +131,34 @@ namespace ecstasy::serialization | |
S &saveEntity(const RegistryEntity &entity) | ||
{ | ||
S &s = inner(); | ||
((s << typeid(Cs) << entity.get<Cs>()), ...); | ||
(saveEntityComponent(entity.get<Cs>()), ...); | ||
return s; | ||
} | ||
|
||
/// | ||
/// @brief Save an entity to the serializer. | ||
/// | ||
/// @warning This will try to save all the components of the entity, but not the entity ID. | ||
/// | ||
/// @param[in] entity Entity to save. | ||
/// | ||
/// @return S& Reference to @b this for chain calls. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2024-06-11) | ||
/// | ||
S &saveEntity(RegistryEntity &entity) | ||
{ | ||
auto storages = entity.getRegistry().getEntityStorages(entity); | ||
|
||
for (auto &storage : storages) { | ||
// We send the typeid of the serializer before loosing the type information (since storage.serialize | ||
// takes an ISerializer) | ||
storage.get().serialize(*this, typeid(S), entity.getIndex()); | ||
} | ||
return inner(); | ||
} | ||
|
||
/// | ||
/// @brief Load an object from the serializer. | ||
/// | ||
|
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 |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/// | ||
/// @file ComponentSerializers.hpp | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @brief | ||
/// @version 1.0.0 | ||
/// @date 2022-10-19 | ||
/// | ||
/// @copyright Copyright (c) ECSTASY 2022 - 2024 | ||
/// | ||
/// | ||
|
||
#ifndef ECSTASY_SERIALIZATION_IS_SERIALIZABLE_HPP_ | ||
#define ECSTASY_SERIALIZATION_IS_SERIALIZABLE_HPP_ | ||
|
||
#include <type_traits> | ||
|
||
namespace ecstasy::serialization | ||
{ | ||
/// | ||
/// @brief Check if a component is serializable with the given serializer. | ||
/// | ||
/// @tparam S Serializer type. | ||
/// @tparam C Component type. | ||
/// @tparam typename Placeholder for SFINAE. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2024-06-11) | ||
/// | ||
template <typename S, typename C, typename = void> | ||
struct is_serializable : std::false_type {}; | ||
|
||
/// @copydoc is_serializable | ||
template <typename S, typename C> | ||
struct is_serializable<S, C, std::void_t<decltype(std::declval<C &>() >> std::declval<S &>())>> : std::true_type {}; | ||
|
||
/// | ||
/// @brief Alias for @ref is_serializable::value. | ||
/// | ||
/// @tparam S Serializer type. | ||
/// @tparam C Component type. | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2024-06-11) | ||
/// | ||
template <typename S, typename C> | ||
bool constexpr is_serializable_v = is_serializable<S, C>::value; | ||
|
||
} // namespace ecstasy::serialization | ||
|
||
#endif /* !ECSTASY_SERIALIZATION_IS_SERIALIZABLE_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 |
---|---|---|
|
@@ -15,6 +15,7 @@ | |
#include <span> | ||
|
||
#include "ecstasy/config.hpp" | ||
#include "util/meta/Traits.hpp" | ||
|
||
#ifdef ECSTASY_LOCKABLE_STORAGES | ||
#include "ecstasy/thread/SharedRecursiveMutex.hpp" | ||
|
@@ -27,6 +28,11 @@ namespace util | |
|
||
namespace ecstasy | ||
{ | ||
|
||
namespace serialization | ||
{ | ||
class ISerializer; | ||
} | ||
class Entity; | ||
|
||
/// | ||
|
@@ -77,6 +83,23 @@ namespace ecstasy | |
/// @since 1.0.0 (2022-10-19) | ||
/// | ||
virtual bool contains(size_t index) const noexcept = 0; | ||
|
||
/// | ||
/// @brief Serialize an entity component. | ||
/// | ||
/// @note The type_info is used to counter the impossibility to use template virtual methods. | ||
/// | ||
/// @param[in] serializer Serializer object. | ||
/// @param[in] stype Type informations of the serializer. | ||
/// @param[in] entityId Entity index. | ||
/// | ||
/// @return serialization::ISerializer& Serializer object. | ||
/// | ||
/// @author Andréas Leroux ([email protected]) | ||
/// @since 1.0.0 (2024-06-11) | ||
/// | ||
virtual serialization::ISerializer &serialize( | ||
serialization::ISerializer &serializer, const std::type_info &stype, size_t entityId) const = 0; | ||
}; | ||
|
||
} // namespace ecstasy | ||
|
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