Skip to main content
Disambiguating reflection tag as discussed here https://gamedev.meta.stackexchange.com/q/2552/39518
Link
DMGregory
  • 140.8k
  • 23
  • 257
  • 401
Post Closed as "off topic" by Tetrad
Tweeted twitter.com/#!/StackGameDev/status/312694710051409922
Source Link
Grieverheart
  • 1.2k
  • 3
  • 15
  • 26

C++ formatted serialization

I've decided it's time to implement serialization in my simple engine but this has caused me many headaches for the past couple of days/weeks. My engine uses an entity/component based approach similar to what is described in the T=Machine blog.

To keep it simple, my first goal was to implement serialization of entities. Since I'm going to use Lua for scripting, I thought it would be nice to serialize entities into Lua tables. Unfortunately, I find the information that is available on serialization in C++ is rather scarce. After many days of thinking I found one approach which is working for my implementation and is described here.

In essence, I have an EntityManager class from which I request new entities. This class holds entity as well as pointers of type BaseComponent from which all components derive. Because I store components as base pointers, I couldn't use a friend class for serialization, but had to make the BaseComponent inherit from a Serializable class, which has pure virtual serialization methods.

So, this is not that bad, I just have to inherit from the Serializable class and implement the serialization method. To support deserialization though, I have to do a few tricks according to the last link. That is, I have to include a static object inside each component whose sole purpose is to populate a map from component names to constructors. Here is a generic example (and please ignore any possible errors),


/* Base.h */
struct Base: public Serializeable{
    static std::map<std::string, std::function<Base*(void)> > deriveds;
    virtual ~Base(void){}
};

/* Derived.h */
template<class T>
struct add_map_entry{
    explicit add_map_entry(std::string name){
        Base::deriveds[name] = [](void) -> Base* {
            return new T;
        };
    }
}
    
class Derived: public Base{
public:
    int x;
    int y;
    Derived(void){
        std::cout << "Derived created" << std::endl;
    }
    void serialize(std::ostream&);
    static add_map_entry<Derived> adder_;
};

Then in the implementation file I also have to initialize the static map of the base class as well as the static object of each derived class.

I find this quite a mess and although it could probably be improved with the use of macros, I can't help to wonder if there are better ways. How do you handle this kind of formatted serialization?

PS: Please don't recommend changing to a more flexible programming language :) !