Skip to content

Commit

Permalink
Introduce new entity serialization methods
Browse files Browse the repository at this point in the history
Linked: #150
  • Loading branch information
AndreasLrx committed Oct 10, 2024
1 parent 7cd665e commit 90fe105
Show file tree
Hide file tree
Showing 8 changed files with 432 additions and 6 deletions.
14 changes: 11 additions & 3 deletions doc/Tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -654,14 +654,22 @@ Position &operator<<(RawSerializer &serializer)
}
```

#### Working with Entities (WIP)
If you need to (de)serialize the type from the save/update/loadEntity methods, you first need to register the type as serializable by the expected Serializer using the variadic macro @ref REGISTER_SERIALIZABLES

For example, if you want you type Position to be serializable by the RawSerializer and the (maybe to come) JsonSerializer:

```cpp
REGISTER_SERIALIZABLES(Position, RawSerializer, JsonSerializer)
```
#### Working with Entities
Since you can serialize any type, you can serialize entity components manually using the functions above.
If you define **ECSTASY_ENABLE_ENTITY_SERIALIZERS**, you can serialize an entire entity.
You can save entity components explicitly using the templated saveEntity method, or every registered components with the classic saveEntity method.
@warning
This is still work in progress and will certainly be refactored because the underlying code is shit.
To use the non templated `saveEntity` method, you need to register them using the @ref REGISTER_SERIALIZABLES macro (see below).
```cpp
RawSerializer serializer();
Expand Down
17 changes: 15 additions & 2 deletions src/ecstasy/registry/Registry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ namespace ecstasy
template <std::derived_from<ISystem> S>
S &getSystem()
{
return _storages.get<S>();
return _systems.get<S>();
}

///
Expand Down Expand Up @@ -1179,7 +1179,7 @@ namespace ecstasy
void runSystems(size_t group, size_t mask);

///
/// @brief Get a reference to the storages instances.
/// @brief Get a const reference to the storages instances.
///
/// @return constexpr const Instances<IStorage>& Const reference to the storages instance.
///
Expand All @@ -1191,6 +1191,19 @@ namespace ecstasy
return _storages;
}

///
/// @brief Get a reference to the storages instances.
///
/// @return constexpr Instances<IStorage>& Reference to the storages instance.
///
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2024-10-04)
///
constexpr Instances<IStorage> &getStorages()
{
return _storages;
}

private:
Instances<ResourceBase> _resources;
Instances<IStorage> _storages;
Expand Down
3 changes: 2 additions & 1 deletion src/ecstasy/serialization/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ add_subdirectory(traits)

set(SRC
${SRC}
${INCROOT}/ComponentSerializer.hpp
${INCROOT}/EntityComponentSerializer.hpp
${INCROOT}/IEntityComponentSerializer.hpp
${INCROOT}/include.hpp
${INCROOT}/ISerializer.hpp
${INCROOT}/RawSerializer.hpp
Expand Down
84 changes: 84 additions & 0 deletions src/ecstasy/serialization/EntityComponentSerializer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
///
/// @file EntityComponentSerializer.hpp
/// @author Andréas Leroux ([email protected])
/// @brief
/// @version 1.0.0
/// @date 2024-10-03
///
/// @copyright Copyright (c) ECSTASY 2024
///
///

#ifndef ECSTASY_COMPONENT_COMPONENT_SERIALIZER_HPP_
#define ECSTASY_COMPONENT_COMPONENT_SERIALIZER_HPP_

#include "ecstasy/serialization/IEntityComponentSerializer.hpp"

namespace ecstasy::serialization
{
///
/// @brief Entity component serializer class bound to a specific component and a serializer type.
///
/// The class instance doesn't contains any data except its vtable.
///
/// @tparam Component Type of the component to serialize.
/// @tparam Serializer Type of the serializer to use to serialize the component.
///
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2024-10-04)
///
template <typename Component, std::derived_from<ISerializer> Serializer>
class EntityComponentSerializer : public IEntityComponentSerializer {
public:
/// Type of the storage used to store the component.
using StorageType = getStorageType<Component>;

///
/// @brief Construct a new Component Rtti
///
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2024-10-04)
///
EntityComponentSerializer() : IEntityComponentSerializer()
{
}

///
/// @brief Destroy the Component Rtti
///
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2024-10-04)
///
~EntityComponentSerializer() override = default;

/// @copydoc IEntityComponentSerializer::save
ISerializer &save(
ISerializer &serializer, const IStorage &storage, const RegistryEntity &entity) const override final
{
return dynamic_cast<Serializer &>(serializer)
.template saveEntityComponent<Component>(
dynamic_cast<const StorageType &>(storage).at(entity.getIndex()));
}

/// @copydoc IEntityComponentSerializer::load
ISerializer &load(ISerializer &serializer, IStorage &storage, RegistryEntity &entity) const override final
{
if (!storage.contains(entity.getIndex())) {
dynamic_cast<StorageType &>(storage).insert(
entity.getIndex(), dynamic_cast<Serializer &>(serializer).template load<Component>());
return serializer;
} else
return dynamic_cast<Serializer &>(serializer)
.template update<Component>(dynamic_cast<StorageType &>(storage).at(entity.getIndex()));
}

/// @copydoc IEntityComponentSerializer::getStorageTypeIndex
std::type_index getStorageTypeIndex() const override final
{
return std::type_index(typeid(StorageType));
}
};

} // namespace ecstasy::serialization

#endif /* !ECSTASY_COMPONENT_COMPONENT_SERIALIZER_HPP_ */
90 changes: 90 additions & 0 deletions src/ecstasy/serialization/IEntityComponentSerializer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
///
/// @file IEntityComponentSerializer.hpp
/// @author Andréas Leroux ([email protected])
/// @brief File containing the IEntityComponentSerializer class, used to serialize entity components from an IStorage
/// instance.
/// @version 1.0.0
/// @date 2024-10-03
///
/// @copyright Copyright (c) ECSTASY 2024
///
///

#ifndef ECSTASY_COMPONENT_ICOMPONESERIALIZERTTI_HPP_
#define ECSTASY_COMPONENT_ICOMPONESERIALIZERTTI_HPP_

#include <functional>
#include <typeindex>

namespace ecstasy
{
class IStorage;
class RegistryEntity;

namespace serialization
{
class ISerializer;

///
/// @brief Type erased interface for serializing entity components.
///
/// This interface is used to serialize entity components from IStorage/ISerializer instances when we don't know
/// the type of the component/serializer.
///
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2024-10-04)
///
class IEntityComponentSerializer {
public:
///
/// @brief Destroy the IEntityComponentSerializer
///
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2024-10-04)
///
virtual ~IEntityComponentSerializer() = default;

///
/// @brief Save the component to the serializer.
///
/// @param[in] serializer Reference to the serializer to save the component to.
/// @param[in] storage Const reference to the storage containing the component.
/// @param[in] entity Const reference to the entity associated with the component.
///
/// @return ISerializer& Reference to the serializer for chaining.
///
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2024-10-04)
///
virtual ISerializer &save(
ISerializer &serializer, const IStorage &storage, const RegistryEntity &entity) const = 0;

///
/// @brief Load an entity component from the serializer.
///
/// @param[in] serializer Reference to the serializer to load the component from.
/// @param[in] storage Reference to the storage to load the component to.
/// @param[in] entity Reference to the entity to load/update the component to.
///
/// @return ISerializer& Reference to the serializer for chaining.
///
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2024-10-04)
///
virtual ISerializer &load(ISerializer &serializer, IStorage &storage, RegistryEntity &entity) const = 0;

///
/// @brief Get the Storage Type Index of the component.
///
/// @return std::type_index Type index of the storage.
///
/// @author Andréas Leroux ([email protected])
/// @since 1.0.0 (2024-10-04)
///
virtual std::type_index getStorageTypeIndex() const = 0;
};

} // namespace serialization
} // namespace ecstasy

#endif /* !ECSTASY_COMPONENT_ICOMPONENT_SERIALIZER_HPP_ */
6 changes: 6 additions & 0 deletions src/ecstasy/serialization/RawSerializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,12 @@ namespace ecstasy::serialization
return *result;
}

/// @copydoc loadComponentHash
std::size_t loadComponentHash() override final
{
return loadRaw<std::size_t>();
}

///
/// @brief Get the string stream of the serializer.
///
Expand Down
Loading

0 comments on commit 90fe105

Please sign in to comment.