-
Notifications
You must be signed in to change notification settings - Fork 1
How to Serialize
Prog'z edited this page May 27, 2021
·
5 revisions
- Reflect the class and add the Serialize() property to it.
- Reflect the field and add the Serialize() property to it.
Example :
// MyScript.hpp
// Put your includes here
#include "Engine/ECS/Component/BehaviourComponent.hpp"
// Generated
#include "Generated/MyScript.rfk.h"
namespace GPG RFKNamespace()
{
class RFKClass(Serialize()) MyScript : public GPE::BehaviourComponent
{
// Put your fields and methods here
RFKField(Serialize())
float mySerializedFloat;
RFKField(Serialize())
GPM::Vec3 mySerializedVector;
RFKField(Serialize())
GameObject* mySerializedPointer;
RFKField(Serialize())
GPE::Function* mySerializedFunctionPtr;
MyScript_GENERATED
};
}
// MyScript.cpp
// Put your includes here
#include "MyScript.hpp"
// Generated
#include "Generated/MyScript.rfk.h"
File_GENERATED
// Put your code here
It is very similar to serializing a script.
- Reflect your class or your struct, and its data.
- Add the Serialize() to what you want to serialize.
Example :
namespace GPG RFKNamespace()
{
struct RFKStruct(Serialize()) MyCustomStruct
{
MyCustomStruct() = default;
RFKField(Serialize())
int i;
MyCustomStruct_GENERATED
};
class RFKClass(Serialize()) MyCustomClass
{
MyCustomClass() = default;
RFKField(Serialize())
char c;
MyCustomClass_GENERATED
};
class RFKClass(Serialize()) MyScript : public GPE::BehaviourComponent
{
// Put your fields and methods here
RFKField(Serialize())
MyCustomStruct mySerializedCustomStruct;
RFKField(Serialize())
MyCustomClass mySerializedCustomClass;
MyScript_GENERATED
};
}
// MyScript.cpp
// Put your includes here
#include "MyScript.hpp"
// Generated
#include "Generated/MyScript.rfk.h"
File_GENERATED
// Put your code here
You have to inherit from rfk::Object. Be careful, you have to put Serialize(false) in the base class.
Example :
namespace GPG RFKNamespace()
{
class RFKClass(Serialize(false)) MyBaseClass : public rfk::Object
{
MyBaseClass() = default;
RFKField(Serialize())
int i;
MyBaseClass_GENERATED
};
class RFKClass(Serialize()) MyChildClass : public MyBaseClass
{
MyChildClass() = default;
RFKField(Serialize())
char c;
MyChildClass_GENERATED
};
class RFKClass(Serialize()) MyScript : public GPE::BehaviourComponent
{
// Put your fields and methods here
MyScript()
{
myPolymorphicPointer = new MyChildClass();
}
RFKField(Serialize())
MyBaseClass* myPolymorphicPointer = nullptr;
MyScript_GENERATED
};
}
// MyScript.cpp
// Put your includes here
#include "MyScript.hpp"
// Generated
#include "Generated/MyScript.rfk.h"
File_GENERATED
// Put your code here
In this example, when myPolymorphicPointer is loaded, a new MyChildClass will be instancied. Its serialized fields will be loaded too. If different serialized pointers point to the same instance, there will only be one instance loaded and all the pointers will then point to the new instance.
If you can't modify a class, then you can't reflect it with RFKClass and generate serialize functions automatically.
In that case, you have to make the serialize functions of the class yourself.
Example :
// .hpp
class MyThirdPartyClass
{
public:
int a;
char b;
float c;
};
template <>
void GPE::save(GPE::XmlSaver& context, const MyThirdPartyClass& data, const GPE::XmlSaver::SaveInfo& info);
template <>
void GPE::load(GPE::XmlLoader& context, MyThirdPartyClass& data, const GPE::XmlLoader::LoadInfo& info);// .cpp
template <>
void GPE::save(GPE::XmlSaver& context, const MyThirdPartyClass& data, const GPE::XmlSaver::SaveInfo& info)
{
context.push(info);
GPE::save(context, data.a, XmlSaver::SaveInfo{"a", "int", 0});
GPE::save(context, data.b, XmlSaver::SaveInfo{"b", "char", 0});
GPE::save(context, data.c, XmlSaver::SaveInfo{"c", "float", 0});
context.pop();
}
template <>
void load(GPE::XmlLoader& context, GPM::SplitTransform& data, const GPE::XmlLoader::LoadInfo& info)
{
if (context.goToSubChild(info))
{
GPE::load(context, data.a, XmlLoader::LoadInfo{"a", "int", 0});
GPE::load(context, data.b, XmlLoader::LoadInfo{"b", "char", 0});
GPE::load(context, data.c, XmlLoader::LoadInfo{"c", "float", 0});
context.pop();
}
}