ofSerializable

Java has the Serializable class http://java.sun.com/developer/technicalArticles/Programming/serialization/ It lets you say:

  
  
class MyClass implements Serializable...  
  

Which lets you do stuff like this:

  
  
MyClass x, y;  
ObjectOutputStream oos = new ObjectOutputStream(file);  
oos.writeObject(x);  
ObjectInputStream ois = new ObjectInputStream(file);  
y = (MyClass) ois.readObject();  
  

Java handles saving all the member data to a file, and loading it back into your object.

ofxXmlSettings has something in this direction… but I propose:

1 ofxXmlSettings becomes part of the core as “ofXml” (and incorporates code from elsewhere on the forum for using xml attributes).

2 We add a small class, ofSerializable:

  
  
class ofSerializable {  
  virtual TiXmlDocument saveXml() = 0;  
  virtual ofSerializable loadXml(TiXmlDocument& tree) = 0;  
}  
  

3 We add to ofXml:

  
  
class ofXml {  
...  
  void addValue(ofSerializable& object, string tagName);  
  ofSerializable getValue(stringTagName);  
}  
  

So that objects like ofRect, ofPoint and ofColor can be loaded and saved from xml files more directly simply by implementing saveXml() and loadXml(), so we don’t keep writing stuff like:

  
  
ofRectangle rect;  
xml.setValue("rect:x", rect.x);  
xml.setValue("rect:y", rect.y);  
xml.setValue("rect:w", rect.w);  
xml.setValue("rect:h", rect.h);  
...  
ofRectangle rect;  
xml.getValue("rect:x", rect.x);  
xml.getValue("rect:y", rect.y);  
xml.getValue("rect:w", rect.w);  
xml.getValue("rect:h", rect.h);  
  

And instead can write:

  
  
ofRectangle rect;  
xml.setValue("rect", rect);  
...  
ofRectangle rect;  
xml.getValue("rect", rect);  
  

This also provides a good framework for other classes that want to abstract away functionality for loading and saving their data.

1 Like

hi, currently iam happy with one of these two:

http://code.google.com/p/yaml-cpp/wiki/-…-eADocument
http://jsoncpp.sourceforge.net/

YAML and JSON are awesome, but they are basically different ways of representing XML. Also, the issue isn’t so much the type of storage that happens (whether XML, YAML, or JSON) but implementing the methods for things like ofPoint, ofRectangle, ofColor, etc. that let you actually import/export from these formats. If we had YAML and JSON wrappers that inherited the same add/get sort of class that ofxXmlSettings has right now, we could even allow for serialization into any of these formats. For JSON and YAML, that also means easier data exchange over http.

1 Like

i think it will be better to have something like ofSerializer with:

setValue(string,ofPoint)=0;
setValue(string,ofColor)=0;

that way we don’t need xml in the core and is much more flexible as you don’t bind to any technology.

1 Like

thats what i had in mind :slight_smile: jsoncpp has a enjoyable api already, we should just extend/combine it.

json and yaml have the advantage of easy ‘data-types’ exchange as part of their lightweight RFC, where XML only has structured string-items which can have string-attributes. this results in xsl(t)-styled parsing hell - if you need to export/import more complex data-structures. http://www.jenitennison.com/datatypes/D-…-sInXML.pdf there are types, coz xml can do just about everything as part of beeing the common buisness-data-exchange format… they are pain to use.

ofSerializable sounds interesting!

[quote author=“arturo”]i think it will be better to have something like ofSerializer with:

setValue(string,ofPoint)=0;
setValue(string,ofColor)=0;

that way we don’t need xml in the core and is much more flexible as you don’t bind to any technology.[/quote]

This would be a good way to get around adding things to the core (and it’s kind of how I’m doing it right now), but I don’t think it’s a very good model. If done this way, ofSerializer is responsible for serializing new data types whenever someone invents them. On the other hand, if we just have ofSerializable, then it’s the responsibility of the object creator to write the serialization code. So when someone creates myWeirdDataType, they’re not stuck with the fact that ofSerializer doesn’t support it. Instead, they just need to implement the read and write methods.

Also, lian – I’ll read more about what you linked to. I’m only familiar with JSON from writing javascript and making web requests, so I basically treat it like XML. But I can see why you’re saying it has some advantages (e.g., dictionary vs list already worked out). YAML is pretty new to me, but looks good too.

Here’s how I’m doing it for a project right now:

ofxXmlSerializable.h:

  
  
#pragma once  
  
#include "ofxXmlSettings.h"  
  
class ofxXmlSerializable {  
public:  
	void xmlSave(string filename);  
	void xmlWrite(ofxXmlSettings& xml);  
	virtual void _xmlWrite(ofxXmlSettings& xml) = 0;  
  
	void xmlLoad(string filename);  
	void xmlRead(ofxXmlSettings& xml);  
	virtual void _xmlRead(ofxXmlSettings& xml) = 0;  
protected:  
	string name;  
	void setup(string name);  
};  
  

ofxXmlSerializable.cpp:

  
  
#include "ofxXmlSerializable.h"  
  
void ofxXmlSerializable::setup(string name) {  
	this->name = name;  
}  
  
void ofxXmlSerializable::xmlWrite(ofxXmlSettings& xml) {  
	int nextWhich = xml.getNumTags(name);  
	xml.addTag(name);  
	xml.pushTag(name, nextWhich);  
	_xmlWrite(xml);  
	xml.popTag();  
}  
  
void ofxXmlSerializable::xmlSave(string filename) {  
	ofxXmlSettings file;  
	xmlWrite(file);  
	file.saveFile(ofToDataPath(filename));  
}  
  
void ofxXmlSerializable::xmlRead(ofxXmlSettings& xml) {  
	xml.pushTag(name);  
	_xmlRead(xml);  
	xml.popTag();  
	xml.removeTag(name);  
}  
  
void ofxXmlSerializable::xmlLoad(string filename) {  
	ofxXmlSettings file;  
	file.loadFile(ofToDataPath(filename));  
	xmlRead(file);  
}  
  

And as an example of a serialized ofxPoint2f, ofxPoint2fs.h:

  
  
#pragma once  
  
#include "ofxPoint2f.h"  
  
class ofxPoint2fs : public ofxPoint2f, public ofxXmlSerializable {  
public:  
	ofxPoint2fs() {  
		ofxXmlSerializable::setup("ofxPoint2fs");  
	}  
	void _xmlWrite(ofxXmlSettings& xml) {  
		xml.addValue("x", x);  
		xml.addValue("y", y);  
	}  
	void _xmlRead(ofxXmlSettings& xml) {  
		x = xml.getValue("x", x);  
		y = xml.getValue("y", y);  
	}  
};  
  

Slightly different style than I initially proposed, you can either say something like:

  
  
ofxPoint2fs point;  
point.xmlLoad("savedPoint.xml");  
  

Or more like:

  
  
ofxPoint2fs point;  
ofxXmlSettings file;  
... // navigate to the right context manually, with push + pop  
point.xmlRead(file);  
  

The thing that’s nice is that you only need to implement _xmlRead and _xmlWrite, and you’re set. The contextualization is handled by the ofxXmlSerializable class.

What about using boost::serialization? If I’m correct you don’t need the whole package, just the serialization and an archiver. I did not try it, but the serialization they use is kind of standard.

1 Like

Thanks – that looks good, I haven’t seen it before.

The main advantage I see is that they don’t require you to extend or modify classes, and that STL is already implemented.

But I’m going to keep using my solution for now because I understand it better :slight_smile:

hi, any chance anyone could post a simple openframeworks examples using JSON?
ive downloaded and compiled the jsoncpp source and added to a openframeworks project but having trouble getting started.
hoping that once i can load a json feed and parse the data, it will be enough of a foot hold to get me started.

thx,
L.

If you’re looking for a great and mostly transparent way of serializing data, check out the Serialization support in the Boost library. I implemented it without much trouble (I’m no C++ king) and it’s saving and loading vectors of custom classes that contain vectors of ofxVec3f objects - a fairly complex structure (1000s of nested arrays), and fast!

You have the option of saving to plain text or binary (though floats and doubles will only work in binary format)

I used this tutorial:
http://www.boost.org/doc/libs/1-42-0/li-…-orial.html

If you’re on OS X, you can get Boost from MacPorts.

Let me know if you need a hand getting it going… a little cumbersome to compile the Boost library and then set up XCode to use it, but well worth it…

cheers!
James

[quote author=“kylemcdonald”]Here’s how I’m doing it for a project right now:

[snip]

The thing that’s nice is that you only need to implement _xmlRead and _xmlWrite, and you’re set. The contextualization is handled by the ofxXmlSerializable class.[/quote]

Very useful info, made my serialization code much cleaner.