1

I'm working on a video game written in C++, and we want to let the player save the game. We have found that the best solution in our case is to save the state of one of the objects (called game, which contains map, players, etc) in a file.

Problem: I can't use boost. So what is the best and easiest solution to do that ?

Thanks

EDIT : I can use other libs as google protocol buffers. In game there are complex objects :

Camera              _camera; 
std::list<AObject*> _objects;
int                 size_map;
PJ Bergeron
  • 2,788
  • 4
  • 25
  • 42
  • 3
    Curious, why can't you use boost? – Matt Phillips Jun 03 '13 at 00:27
  • 1
    possible duplicate of [Serialization without Boost.Serialization](http://stackoverflow.com/questions/11975606/serialization-without-boost-serialization) – jogojapan Jun 03 '13 at 06:01
  • There are also many other questions about serialization that do not exclude boost specifically, but have answers that mention alternatives: 1) http://stackoverflow.com/questions/523872/how-do-you-serialize-an-object-in-c, 2) http://stackoverflow.com/questions/12765949/preferred-way-to-serialize-an-object-with-c, http://stackoverflow.com/questions/12499146/serializing-c-objects – jogojapan Jun 03 '13 at 06:02
  • 2
    it seems most of the time somebody says they can't use boost in a question, they are questioned "why not؟". once you have read ten such explanations, you'll notice patterns. this question doesn't need to be asked so often; nor should people fill their question with noise to defend such decisions and constraints. Berpj didn't mention this restriction to be questioned or to moan, but to present the problem so it could be answered accurately. – justin Jun 03 '13 at 06:33

2 Answers2

4

Can you use google protocol buffers? It's another serialization library. If not there are a few ways to roll your own. You also need to think about if you want to do a binary format or one that is human readable. For binary you could do something simple in your class such as a serialize and deserialize method to an input or output stream.

struct MyStruct {  
    int data;  
    int more_data;  
    double even_more_data;  
    void serialize(std::ostream output) {  
        output.write((char *)&data, sizeof(data));  
        output.write((char *)&more_data, sizeof(more_data));  
        output.write((char *)&even_more_data, sizeof(even_more_data));  
    }  
    void deserialize(std::istream input) {  
        input.read((char *)&data, sizeof(data));  
        input.read((char *)&more_data, sizeof(more_data));  
        input.read((char *)&even_more_data, sizeof(even_more_data));  
    }  
}

If you need to contain a string you'd need to write out the size and then the string so when you read it back in you know how many characters to read. Some other things you can do are XML, JSON, CSV, or a line by line thing that's kind of like:
Name = Bob
Level = 99
HP = 201
MP = 109
...

You might also want to create an interface for serializable objects:

class ISerializable {  
     virtual void serialize(std::ostream output) = 0;  
     virtual void deserialize(std::istream output) = 0;  
 }
scaryrawr
  • 777
  • 4
  • 12
2

I'm always baffled on constraints like that. Boost is there, it works, it would take just a few hours to add to the project and then solve the problems in no time -- but instead weeks are spent on reimplementing a jagged wheel.

If you don't use boost you can still study it. The code itself will likely be ridden with macros as usual but the interface can provide insight.

MFC can be studied for both design and implementation if you have MSVC, whatever old version. The one is pretty straightforward and you can use the ideas to create your own variant. Guess you can find more existing frameworks.

The basic idea is simple, you have a CArchive-like class that manages the serialization, owning a data stream, and providing I/O for the primitive types. Normally using an overload set of a common function plus a few special variants.

Then you make all your classes implement their own load and save by calling that function for each data member. It can be intrusive or use overloaded free function or specializing a template or some combination of those. Also somewhere add support to serialize collections -- not really hard as it's just iteration and calling serialize on items. And for smart pointers.

The hard part is to deal with pointers, especially shared ones -- with some luck you can sidestep it.

The store format is arbitrary and you can even change it just in the archive manager without anyone noticing. Except is you want XML-like store that uses tags beside the content, you must plan for that in the interface.

For polymorphic pointers you will need some more support, some factory facility and identifiers.

Then drop in schema handling as in few weeks your classes will change and people will still want to load yesterday's file.

Are you sure you want to avoid using boost or another stock solution?

Balog Pal
  • 16,195
  • 2
  • 23
  • 37