CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
Serialization.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
10#include "Forward.hpp"
11
14
21
24
25namespace CeresEngine {
26
29 None = 0,
30
39 Polymorphic = (1u << 0u),
40
49 Custom = (1u << 1u),
50 };
51
54
72
73 // ---------------------------------------------------------------------------------------------
74
78 None = 0,
79 };
80
83
93
94 // ---------------------------------------------------------------------------------------------
95
98 None = 0,
99 };
100
103
110
111 // ---------------------------------------------------------------------------------------------
112
116 None = 0,
117 };
118
121
135
136 // ---------------------------------------------------------------------------------------------
137
141 None = 0,
142 };
143
146
163
164 // ---------------------------------------------------------------------------------------------
165 // ---------------------------------------------------------------------------------------------
166
168
171
175 const SerializedPropertyMetadata& property, Box& value) const>;
176
181
186
193
197 private:
201
204
207
211
224
227
228 public:
231
234
235 public: // Constructors
240 template<typename T> void addConstructor(Constructor&& constructor) {
241 const TypeID typeID = getTypeID<T>();
242 CE_ASSERT(mConstructors.find(typeID) == mConstructors.end());
243 mConstructors[typeID] = std::move(constructor);
244 }
245
248
250 template<typename T> [[nodiscard]] Box construct(SerializationState& state) const { return construct(state, getType<T>()); }
251
252 public: // Property migrations
266
267 public:
273 template<typename T, typename CustomSerializer, typename CustomDeserializer>
277
285 template<typename T, typename CustomSerializer, typename CustomDeserializer>
288 getType<T>(), options,
289 [customSerializer = std::move(customSerializer)](Serializer& serializer, const Box& value) {
290 customSerializer(serializer, value.cref<T>());
291 },
292 [customDeserializer = std::move(customDeserializer)](Deserializer& deserializer, Box&& value) {
293 customDeserializer(deserializer, value.ref<T>());
294 return std::move(value);
295 });
296 }
297
307
317
325
331 [[nodiscard]] const CustomSerializer& getCustomSerializer(const Type& type) const;
332
339
340 public: // Serialization callbacks
342 void willSerialize(const Box& object) const;
343
345 void didSerialize(const Box& object) const;
346
349 void willSerializeProperty(const Box& object, const ClassProperty& property) const;
350
353 void didSerializeProperty(const Box& object, const ClassProperty& property) const;
354
355 public: // Deserialization callbacks
357 void willDeserialize(const Box& object) const;
358
360 void didDeserialize(const Box& object) const;
361
364 void willDeserializeProperty(const Box& object, const ClassProperty& property) const;
365
368 void didDeserializeProperty(const Box& object, const ClassProperty& property) const;
369
370 public:
374
375 private:
377 template<typename Func> using ForEachContextReturnType = std::invoke_result_t<Func, const SerializationContext&>;
378
390 template<typename Func> [[nodiscard]] ForEachContextReturnType<Func> forEachContext(Func&& func, const ForEachContextReturnType<Func>& defaultValue = {}) const;
391
398 template<typename K, typename V, typename Hash, typename KeyEqual, typename RawAllocator> [[nodiscard]] const V* recursiveLookup(HashMap<K, V, Hash, KeyEqual, RawAllocator> SerializationContext::*ptr, const K& key) const;
399 };
400
403 private:
405
406 public:
408
409 public:
411 [[nodiscard]] virtual bool isSerializerState() const noexcept { return false; };
412
414 [[nodiscard]] virtual bool isDeserializerState() const noexcept { return false; };
415
416 public: // State object stack
419 template<typename T, typename... Args> T& pushObjectValue(Args&&... args) {
420 const auto iterator = mObjects.emplace( //
421 std::piecewise_construct, //
422 std::forward_as_tuple(getType<T>().getDecayType()), //
423 std::forward_as_tuple(args...));
424 return iterator->second.template ref<T>();
425 }
426
429 template<typename T> T& pushObject(T& object) {
430 mObjects.emplace( //
431 std::piecewise_construct, //
432 std::forward_as_tuple(getType<T>().getDecayType()), //
433 std::forward_as_tuple(std::ref(object)));
434 return object;
435 }
436
439 template<typename T> T& getObject() {
440 if(T* const object = getObjectIf<T>()) {
441 return *object;
442 }
443
444 throw RuntimeError("Failed to get object with type. The object with the given type is not present on the map.");
445 }
446
448 template<typename T> const T& getObject() const { return const_cast<SerializationState*>(this)->getObject<T>(); }
449
452 template<typename T> T* getObjectIf() {
453 if(mObjects.count(getType<T>().getDecayType()) == 0) {
454 return nullptr;
455 }
456
457 auto found = mObjects.upper_bound(getType<T>().getDecayType());
458 if(found != mObjects.begin()) {
459 --found;
460 } else if(found == mObjects.end()) {
461 return nullptr;
462 }
463
464 return &(found->second.template ref<T>());
465 }
466
468 template<typename T> const T* getObjectIf() const { return const_cast<SerializationState*>(this)->getObjectIf<T>(); }
469
471 template<typename T> void popObject() {
472 auto found = mObjects.upper_bound(getType<T>().getDecayType());
473
474 if(found != mObjects.begin()) {
475 --found;
476 } else if(found == mObjects.end()) {
477 throw RuntimeError("Unable to pop object. The object type is not present on the object map.");
478 }
479
480 mObjects.erase(found);
481 }
482 };
483
496
498
499} // namespace CeresEngine
#define CE_EXCEPTION_DECL2(Name, Parent)
Definition Exception.hpp:100
#define CE_ASSERT(...)
Definition Macros.hpp:323
A value type that can hold any alongside it's type information.
Definition Box.hpp:40
Box cref() const &
Gets a reference to the meta value.
Box ref() const &
Gets a reference to the meta value.
Represents a reflected property from metadata defined by the class.
Definition Class.hpp:176
The deserializer class has basic support for reflection-based deserializers.
Definition Deserializer.hpp:73
Definition Optional.hpp:17
Definition Exception.hpp:115
A context that is shared between multiple serializer and deserializer instances.
Definition Serialization.hpp:196
void addPropertyMigration(const StringView propertyName, PropertyMigration &&migration)
Adds a new property migration for the given propertyName for type T.
Definition Serialization.hpp:261
void didDeserializeProperty(const Box &object, const ClassProperty &property) const
Fires the didDeserializeProperty callback for the given property of the object.
void didSerialize(const Box &object) const
Fires the didSerialize callback for the given object.
void willDeserialize(const Box &object) const
Fires the willDeserialize callback for the given object.
void willSerialize(const Box &object) const
Fires the willSerialize callback for the given object.
const CustomDeserializer & getCustomDeserializer(const Type &type) const
Gets a custom deserializer for the given type, if any exists.
std::invoke_result_t< Func, const SerializationContext & > ForEachContextReturnType
Determines the return type for the forEachContext call.
Definition Serialization.hpp:377
void addCustomSerialization(const CustomSerializationOptions &options, CustomSerializer &&customSerializer, CustomDeserializer &&customDeserializer)
Registers a new custom serializer for type T.
Definition Serialization.hpp:286
const V * recursiveLookup(HashMap< K, V, Hash, KeyEqual, RawAllocator > SerializationContext::*ptr, const K &key) const
Recursively lookups the given hash map in this context and all parents until the root.
void addCustomSerialization(const Type &type, CustomSerializer &&customSerializer, CustomDeserializer &&customDeserializer)
Registers a new custom serializer for type.
Definition Serialization.hpp:304
DeserializerPropertyMigrator PropertyMigration
Represents the signature of the function that performs migration of an abandoned serialized property.
Definition Serialization.hpp:209
void addConstructor(Constructor &&constructor)
Registers a new constructor for type T.
Definition Serialization.hpp:240
static const SerializationContext & getDefault()
Gets the default serialization context to be used in case the user doesn't provide one himself.
Box construct(SerializationState &state) const
Constructs a new instance of the given type T.
Definition Serialization.hpp:250
const CustomSerializationOptions & getCustomSerializationOptions(const Type &type) const
Gets a custom serializer/deserializer for the given type, if any exists.
void didDeserialize(const Box &object) const
Fires the didDeserialize callback for the given object.
void willDeserializeProperty(const Box &object, const ClassProperty &property) const
Fires the willDeserializeProperty callback for the given property of the object.
HashMap< TypeID, Constructor > mConstructors
A hash map that indexes constructors by type.
Definition Serialization.hpp:206
DeserializerConstructor Constructor
A type that represents the constructor function.
Definition Serialization.hpp:203
void addCustomSerialization(CustomSerializer &&customSerializer, CustomDeserializer &&customDeserializer)
Registers a new custom serializer for type T.
Definition Serialization.hpp:274
SerializationContext() noexcept=default
Creates a new root serialization context.
const SerializationContext * mParent
The parent context.
Definition Serialization.hpp:200
Box construct(SerializationState &state, const Type &type) const
Constructs a new instance of the given type.
void willSerializeProperty(const Box &object, const ClassProperty &property) const
Fires the willSerializeProperty callback for the given property of the object.
void addCustomSerialization(const Type &type, const CustomSerializationOptions &options, CustomSerializer &&customSerializer, CustomDeserializer &&customDeserializer)
Registers a new custom serializer for type.
HashMap< TypeID, CustomSerialization > mCustomSerialization
A map of registered custom serialization functions.
Definition Serialization.hpp:226
ForEachContextReturnType< Func > forEachContext(Func &&func, const ForEachContextReturnType< Func > &defaultValue={}) const
Executes the given function on each context until there are no more parent contexts or func returns a...
void didSerializeProperty(const Box &object, const ClassProperty &property) const
Fires the didSerializeProperty callback for the given property of the object.
HashMap< TypeID, HashMap< String, PropertyMigration > > mPropertyMigrations
Definition Serialization.hpp:210
const CustomSerializer & getCustomSerializer(const Type &type) const
Gets a custom serializer for the given type, if any exists.
Definition Serialization.hpp:497
A base class for serializer and deserializer states.
Definition Serialization.hpp:402
virtual ~SerializationState() noexcept=default
T * getObjectIf()
Gets an object from tge state.
Definition Serialization.hpp:452
virtual bool isSerializerState() const noexcept
Checks if the state represents a serializer state.
Definition Serialization.hpp:411
T & pushObjectValue(Args &&... args)
Pushes a new object value to the state.
Definition Serialization.hpp:419
T & getObject()
Gets an object from tge state.
Definition Serialization.hpp:439
T & pushObject(T &object)
Pushes a new object value to the state.
Definition Serialization.hpp:429
const T & getObject() const
Gets an object from tge state.
Definition Serialization.hpp:448
const T * getObjectIf() const
Gets an object from tge state.
Definition Serialization.hpp:468
virtual bool isDeserializerState() const noexcept
Checks if the state represents a deserializer state.
Definition Serialization.hpp:414
void popObject()
Pops an object value from the state.
Definition Serialization.hpp:471
MultiMap< Type, Box > mObjects
Definition Serialization.hpp:404
The serializer class has basic support for reflection-based serializers.
Definition Serializer.hpp:72
Represents a reflected C++ type. Can be used to get metadata from a C++ type.
Definition Type.hpp:32
Definition Application.hpp:19
SerializedMapMetadataFlag
A set of flags that determine how the map is serialized.
Definition Serialization.hpp:139
@ None
Specifies an empty flag set.
SerializedObjectMetadataFlag
A set of flags that determine how the object is serialized.
Definition Serialization.hpp:28
@ Polymorphic
If set, indicates that the type is polymorphic and the serializer implementation must include the typ...
@ Custom
If set, indicates that the type used a custom serializer/deserializer implementation.
UniqueFunction< Box(const SerializationContext &context, SerializationState &state, const Type &type) const > DeserializerConstructor
A type that represents the constructor function.
Definition Serialization.hpp:170
UniqueFunction< void(Serializer &, const Box &) const > CustomSerializer
A type alias to a function signature that implements a custom serializer.
Definition Serialization.hpp:180
std::unordered_map< Key, T, Hash, KeyEqual, ScopedAllocatorAdaptor< StdAllocator< Pair< const Key, T >, RawAllocator > > > HashMap
HashMap is an associative container that contains key-value pairs with unique keys.
Definition Map.hpp:33
struct CeresEngine::GLState state
SerializedArrayMetadataFlag
A set of flags that determine how the array is serialized.
Definition Serialization.hpp:114
@ None
Specifies an empty flag set.
std::uint16_t UInt16
Definition DataTypes.hpp:20
SerializedCustomObjectMetadataFlag
A set of flags that determine how the object is serialized.
Definition Serialization.hpp:97
auto parent(const Entity &parent)
Sets the entity parent.
Definition Helpers.hpp:52
SerializedPropertyMetadataFlag
A set of flags that determine how the property is serialized.
Definition Serialization.hpp:76
@ None
Specifies an empty flag set.
std::uint32_t UInt32
Definition DataTypes.hpp:23
UniqueFunction< Box(Deserializer &, Box &&) const > CustomDeserializer
A type alias to a function signature that implements a custom deserializer.
Definition Serialization.hpp:185
FunctionBase< true, false, fu2::capacity_default, true, false, Signatures... > UniqueFunction
An owning non copyable function wrapper for arbitrary callable types.
Definition Function.hpp:59
BasicString< char > String
Narrow string used for handling narrow encoded text in UTF-8.
Definition String.hpp:163
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
std::multimap< Key, T, Compare, ScopedAllocatorAdaptor< StdAllocator< Pair< const Key, T >, RawAllocator > > > MultiMap
Definition MultiMap.hpp:21
decltype(&*std::declval< I >() found)(const I &it, C &container)
Returns a pointer to the value if found, otherwise nullptr.
Definition Iterator.hpp:572
UniqueFunction< Box(const SerializationContext &context, SerializationState &state, Box &object, const SerializedPropertyMetadata &property, Box &value) const > DeserializerPropertyMigrator
Represents the signature of the function that performs migration of an abandoned serialized property.
Definition Serialization.hpp:175
Specifies a set of options that specify how a custom serializer should behave.
Definition Serialization.hpp:189
Holds data for custom serialization for a custom serializer/deserializer.
Definition Serialization.hpp:214
CustomDeserializer deserializer
A type alias to a function signature that implements a custom deserializer.
Definition Serialization.hpp:222
CustomSerializationOptions options
Specifies a set of options that specify how a custom serializer should behave.
Definition Serialization.hpp:216
CustomSerializer serializer
A type alias to a function signature that implements a custom serializer.
Definition Serialization.hpp:219
Scope object that pushes an object to the SerializationState.
Definition Serialization.hpp:485
SerializationStateObject(SerializationState &state, T &object)
Definition Serialization.hpp:491
~SerializationStateObject()
Pops the object from the state.
Definition Serialization.hpp:494
SerializationState & state
The serialization state the object was pushed to.
Definition Serialization.hpp:487
A structure that holds metadata for a serialized array.
Definition Serialization.hpp:123
SerializedArrayMetadataFlags flags
A set of flags that determine the serialization behavior of the object array.
Definition Serialization.hpp:126
TypeID elementType
The array element type.
Definition Serialization.hpp:129
UInt32 length
Specifies the number of elements in the array.
Definition Serialization.hpp:133
A struct that holds metadata for a serialized object.
Definition Serialization.hpp:105
SerializedCustomObjectMetadataFlags flags
A set of flags that determine the serialization behavior of the custom object.
Definition Serialization.hpp:108
A structure that holds metadata for a serialized map.
Definition Serialization.hpp:148
UInt32 length
Specifies the number of elements in the map.
Definition Serialization.hpp:161
SerializedMapMetadataFlags flags
A set of flags that determine the serialization behavior of the object map.
Definition Serialization.hpp:151
TypeID keyType
The map key type.
Definition Serialization.hpp:154
TypeID valueType
The map value type.
Definition Serialization.hpp:157
A struct that holds metadata for a serialized object.
Definition Serialization.hpp:56
SerializedObjectMetadataFlags flags
A set of flags that determine the serialization behavior of the object.
Definition Serialization.hpp:59
Type type
The object class definition.
Definition Serialization.hpp:62
Optional< SerializedObjectID > objectID
A unique object ID.
Definition Serialization.hpp:70
A structure that holds metadata for a serialized property.
Definition Serialization.hpp:85
StringView name
The class property.
Definition Serialization.hpp:91
SerializedPropertyMetadataFlags flags
A set of flags that determine the serialization behavior of the object property.
Definition Serialization.hpp:88