[serialization] Overriding serialization of class pointer types

Hi all, I'm currently working on a game engine, and hoping to use boost serialization for the world saving code. It's nearly perfect except for one snag - serializing pointers to sprite file classes. Ideally I'd like to simply serialize the name of the sprite file, and on deserialization find the file in the sprite cache 'gallery', but this requires using split serialization in all the classes that reference sprites. Is there a way to simply override the serialization of /pointers/ to classes? I've tried the following: typedef creaturesImage *p_img; namespace boost { namespace serialization { template <class Archive> inline void save(Archive &ar, const p_img &obj, const int version) { bool isNull = (obj == NULL); ar & isNull; if (!isNull) { std::string name = obj->serializedName(); ar & name; } } template <class Archive> inline void load(Archive &ar, p_img &obj, const int version) { bool isNull; ar & isNull; if (isNull) obj = NULL; else { std::string name; ar & name; obj = world.gallery.getImage(name); } } } } BOOST_SERIALIZATION_SPLIT_FREE(creaturesImage *); BOOST_CLASS_IMPLEMENTATION(creaturesImage *, boost::serialization::primitive_type); However, this seems to be ignored; the compiler errors complain of such things as /usr/include/boost/serialization/access.hpp:109: error: 'class creaturesImage' has no member named 'serialize' (full log at http://pastebin.com/747527) The code in question can be found at http://ccdevnet.org/viewcvs.cgi/trunk/?rev=941 (ser/ subdirectory and serialization.h particularly), or by subversion at svn://ccdevnet.org/openc2e/trunk (rev 941 contains the code cited here; build with make openc2e_s; dependency list at http://openc2e.ccdevnet.org/download). Thanks, Bryan Donlan

Rather than what you have below - just try BOOST_SERIALIZATION_SPLIT_FREE(creaturesImage); By default - pointers to primitive types aren't serializable. I'm not sure why you used the BOOST_CLASS_IMP.. below but it would seem to me in appropriate in your case. If you do this you will be able to do; const creaturesImage *pci; ... ar << pci; ... creaturesImage *new_pci; ar >> new_pci assert(*pci == *new_pci); In fact, given the size of your application, making a little program like the above to test your serialization code separately, is probably a good idea anyway. Good Luck Robert Ramey Bryan Donlan wrote:
Hi all,
BOOST_SERIALIZATION_SPLIT_FREE(creaturesImage *); BOOST_CLASS_IMPLEMENTATION(creaturesImage *, boost::serialization::primitive_type);

On 5/30/06, Robert Ramey
Rather than what you have below - just try
BOOST_SERIALIZATION_SPLIT_FREE(creaturesImage);
By default - pointers to primitive types aren't serializable. I'm not sure why you used the BOOST_CLASS_IMP.. below but it would seem to me in appropriate in your case. If you do this you will be able to do;
const creaturesImage *pci; ... ar << pci;
... creaturesImage *new_pci; ar >> new_pci
assert(*pci == *new_pci);
In fact, given the size of your application, making a little program like the above to test your serialization code separately, is probably a good idea anyway.
Good Luck
Robert Ramey
I should clarify a bit - creaturesImage /is/ a class. But I want to override the /pointer/ serialization, rather than the class serialization. As such, it doesn't matter if the representations of the pointers are unchanged between two runs of the program; rather, it matters that the class not be serialized by boost, as these classes are rather heavy in terms of memory-mappings and other external resources (hence using a global cache to share them).

I still don't understand why you want to do this - but no matter. If you don't want the standard pointer serialization - you could just not invoke ar << pci . Just do what ever you want to do instead. or make your own wrapper - see serialization wrappers that would be used like ar << my_wrapper(pci) when every you want your special code invoked. This wrapper could be used to apply your special behavior to any pointer type desired. Archives handle all pointers with the same code. Many you want to make your own archive class - via derivation from one of the existing ones - which handles you're special case of a particular type of pointer before it gets passed to the standard serialization code. Finally, if you want to make your own pointer serialization just derive from the desired archive class and implement your own code for template<class T> save(const * T){ .... } (assuming your compiler supports correct partial function template ordering) So you have lots of options. Robert Ramey Bryan Donlan wrote:
On 5/30/06, Robert Ramey
wrote: Rather than what you have below - just try
BOOST_SERIALIZATION_SPLIT_FREE(creaturesImage);
By default - pointers to primitive types aren't serializable. I'm not sure why you used the BOOST_CLASS_IMP.. below but it would seem to me in appropriate in your case. If you do this you will be able to do;
const creaturesImage *pci; ... ar << pci;
... creaturesImage *new_pci; ar >> new_pci
assert(*pci == *new_pci);
In fact, given the size of your application, making a little program like the above to test your serialization code separately, is probably a good idea anyway.
Good Luck
Robert Ramey
I should clarify a bit - creaturesImage /is/ a class. But I want to override the /pointer/ serialization, rather than the class serialization. As such, it doesn't matter if the representations of the pointers are unchanged between two runs of the program; rather, it matters that the class not be serialized by boost, as these classes are rather heavy in terms of memory-mappings and other external resources (hence using a global cache to share them).
participants (2)
-
Bryan Donlan
-
Robert Ramey