[Serialization] Serialize base and derived classes.

Hi lists, I'm working with the Serialization library but I'm having some troubles with it. The tutorials in the website shown me much but still I need help. I'm using XML archives. I have this classes actually (these classes are all builders/prototypes, they serialize the datas and then they should make a new object with those datas): Serializer (an interface, every class which need serialization must be derived from this, however this is only a marker, it will be not serialized) RenderableSerializer : public Serializer - this isn't pure virtual however shouldn't be never serialized directly (since the object made by this class is a pure virtual one) - These will use the tag <renderable> SkyboxSerializer : public RenderableSerializer - these will use the tag <skybox> EntitySerializer : public Serializer - these will use the tag <entity> many other classes will be added in future and they'll all derive form RenderableSerializer. Now the problem is EntitySerializer have a pointer to a RenderableSerializer and when I serialize EntitySerializer the pointer to that class is considered to be a RenderableSerializer and not the derived class. I don't know at priori which class is the base class and this lead to problem. If I serialize a SkyboxSerializer I have the correct tag: a <skybox> which have inside a <renderable> and the datas are correct. If I try to serialize an Entity I had a lot of problem, mostly just make the library crash. As I've seen in the tutorial I should register all the derived classes before pass the pointer to the Archive. I did it registering the SkyboxSerializer classes but it lead to a wrong xml: a correct <entity> tag which have a correct <skybox> with all it's data but also a wrong <renderable> tag which have inside the same data of the tag <skybox> instead of the data of a RenderableSerializer class. Now the question is: is there a correct way to use the library this way? With a pointer to a base class of which the derived is not known? My code is too big and I made many attempt to use the library so I'm not posting it in this message. If you need it I will post it. Thank you for your replies.

Hi lists, I'm working with the Serialization library but I'm having some troubles with it. The tutorials in the website shown me much but still I need help.
I'm using XML archives. I have this classes actually (these classes are all builders/prototypes, they serialize the datas and then they should make a new object with those datas): Serializer (an interface, every class which need serialization must be derived from this, however this is only a marker, it will be not serialized) RenderableSerializer : public Serializer - this isn't pure virtual however shouldn't be never serialized directly (since the object made by this class is a pure virtual one) - These will use the tag <renderable> SkyboxSerializer : public RenderableSerializer - these will use the tag <skybox> EntitySerializer : public Serializer - these will use the tag <entity> many other classes will be added in future and they'll all derive form RenderableSerializer.
Now the problem is EntitySerializer have a pointer to a RenderableSerializer and when I serialize EntitySerializer the pointer to that class is considered to be a RenderableSerializer and not the derived class. I don't know at priori which class is the base class and this lead to problem. If I serialize a SkyboxSerializer I have the correct tag: a <skybox> which have inside a <renderable> and the datas are correct. If I try to serialize an Entity I had a lot of problem, mostly just make the library crash. As I've seen in the tutorial I should register all the derived classes before pass the pointer to the Archive. I did it registering the SkyboxSerializer classes but it lead to a wrong xml: a correct <entity> tag which have a correct <skybox> with all it's data but also a wrong <renderable> tag which have inside the same data of the tag <skybox> instead of the data of a RenderableSerializer class.
Now the question is: is there a correct way to use the library this way? With a pointer to a base class of which the derived is not known? My code is too big and I made many attempt to use the library so I'm not posting it in this message. If you need it I will post it. Thank you for your replies.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users It seems no one know the answer. I hope it's just I made a too vague request. Here's the partial code (load function are implemented the same way, simmetrically): EntitySerializer.hpp: void *save*(xml_oarchive& ar, const unsigned int version) const { ar << make_nvp("EntityName", _nome); // string ar.register_type(static_cast
(NULL)); // Note:
Il 26/07/2010 18:58, BlueAngel ha scritto:
this is just for debug, in the future I'll make a function in every
class derived from Serializer which register itself when needed.
ar << make_nvp(_renderable->getTagName().c_str(), _renderable);
}
SkyboxSerializer.hpp:
void *save*(xml_oarchive& ar, const unsigned int version) const
{
ar << make_nvp("renderable",
boost::serialization::base_object< RenderableSerializer >(*this));
//RenderableSerializer::save(ar, version); // If I use this line
instead of the previous it de/serializer correctly but I know this is a
dirty work-around and I want to avoid it.
ar << make_nvp("shader_file", _fx_file); // std::string
ar << make_nvp("mesh_file", _mesh_filename); // std::string
ar << make_nvp("cubemap_file", _tex_filename); // std::string
}
RenderableSerialier.hpp:
void *save*(xml_oarchive& ar, const unsigned int version) const
{
ar << make_nvp("scala", _scala); // struct vector
ar << make_nvp("rotazione", _rotazione); // struct vector
ar << make_nvp("posizione", _posizione); // struct vector
}
VectorSerializer.hpp:
struct vettore
{
float x, y, z;
};
namespace boost
{
namespace serialization
{
template<class Archive> void *serialize*(Archive& ar, vettore& vec,
const unsigned int version)
{
ar & make_nvp("x", vec.x);
ar & make_nvp("y", vec.y);
ar & make_nvp("z", vec.z);
}
}
}
Serializer.hpp:
virtual void *save*(xml_oarchive& ar, const unsigned int version) const = 0;
And this is the xml resultant:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>

Il 28/07/2010 12:38, BlueAngel ha scritto:
Hi lists, I'm working with the Serialization library but I'm having some troubles with it. The tutorials in the website shown me much but still I need help.
I'm using XML archives. I have this classes actually (these classes are all builders/prototypes, they serialize the datas and then they should make a new object with those datas): Serializer (an interface, every class which need serialization must be derived from this, however this is only a marker, it will be not serialized) RenderableSerializer : public Serializer - this isn't pure virtual however shouldn't be never serialized directly (since the object made by this class is a pure virtual one) - These will use the tag <renderable> SkyboxSerializer : public RenderableSerializer - these will use the tag <skybox> EntitySerializer : public Serializer - these will use the tag <entity> many other classes will be added in future and they'll all derive form RenderableSerializer.
Now the problem is EntitySerializer have a pointer to a RenderableSerializer and when I serialize EntitySerializer the pointer to that class is considered to be a RenderableSerializer and not the derived class. I don't know at priori which class is the base class and this lead to problem. If I serialize a SkyboxSerializer I have the correct tag: a <skybox> which have inside a <renderable> and the datas are correct. If I try to serialize an Entity I had a lot of problem, mostly just make the library crash. As I've seen in the tutorial I should register all the derived classes before pass the pointer to the Archive. I did it registering the SkyboxSerializer classes but it lead to a wrong xml: a correct <entity> tag which have a correct <skybox> with all it's data but also a wrong <renderable> tag which have inside the same data of the tag <skybox> instead of the data of a RenderableSerializer class.
Now the question is: is there a correct way to use the library this way? With a pointer to a base class of which the derived is not known? My code is too big and I made many attempt to use the library so I'm not posting it in this message. If you need it I will post it. Thank you for your replies.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users It seems no one know the answer. I hope it's just I made a too vague request. Here's the partial code (load function are implemented the same way, simmetrically): EntitySerializer.hpp: void *save*(xml_oarchive& ar, const unsigned int version) const { ar << make_nvp("EntityName", _nome); // string ar.register_type(static_cast
(NULL)); // Note: Il 26/07/2010 18:58, BlueAngel ha scritto: this is just for debug, in the future I'll make a function in every class derived from Serializer which register itself when needed. ar << make_nvp(_renderable->getTagName().c_str(), _renderable); }
SkyboxSerializer.hpp: void *save*(xml_oarchive& ar, const unsigned int version) const { ar << make_nvp("renderable", boost::serialization::base_object< RenderableSerializer >(*this)); //RenderableSerializer::save(ar, version); // If I use this line instead of the previous it de/serializer correctly but I know this is a dirty work-around and I want to avoid it. ar << make_nvp("shader_file", _fx_file); // std::string ar << make_nvp("mesh_file", _mesh_filename); // std::string ar << make_nvp("cubemap_file", _tex_filename); // std::string } RenderableSerialier.hpp: void *save*(xml_oarchive& ar, const unsigned int version) const { ar << make_nvp("scala", _scala); // struct vector ar << make_nvp("rotazione", _rotazione); // struct vector ar << make_nvp("posizione", _posizione); // struct vector } VectorSerializer.hpp: struct vettore { float x, y, z; };
namespace boost { namespace serialization { template<class Archive> void *serialize*(Archive& ar, vettore& vec, const unsigned int version) { ar & make_nvp("x", vec.x); ar & make_nvp("y", vec.y); ar & make_nvp("z", vec.z); } } }
Serializer.hpp: virtual void *save*(xml_oarchive& ar, const unsigned int version) const = 0;
And this is the xml resultant: <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <!DOCTYPE boost_serialization>
<entity class_id="0" tracking_level="0" version="0"> <EntityName>skybohx</EntityName> <skybox class_id="1" tracking_level="1" version="0" object_id="_0"> <renderable class_id="2" tracking_level="1" version="0" object_id="_1"> <renderable object_id_reference="_1"></renderable> skybox.fx asd.x CubeMap.dds </renderable>skybox.fx asd.x CubeMap.dds </skybox> </entity>As you can see the renderable tag inside the skybox tag is wrong. The <renderable> should have: <scala> <x>3</x> <y>3</y> <z>3</z> </scala> <rotazione> <x>2</x> <y>2</y> <z>2</z> </rotazione> <posizione> <x>1</x> <y>1</y> <z>1</z> </posizione>
Why that tag serialize the derived class instead of itself? Thank you again for your answers.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users Hi, I don't want to insist but... I don't understand: The: ar << make_nvp("renderable", boost::serialization::base_object< RenderableSerializer >(*this)); of the *save* function of SkyboxSerializer seems to call itself again instead of the save function of the RenderableSerializer. How can this happen?

Il 29/07/2010 00:14, BlueAngel ha scritto:
Il 28/07/2010 12:38, BlueAngel ha scritto:
Hi lists, I'm working with the Serialization library but I'm having some troubles with it. The tutorials in the website shown me much but still I need help.
I'm using XML archives. I have this classes actually (these classes are all builders/prototypes, they serialize the datas and then they should make a new object with those datas): Serializer (an interface, every class which need serialization must be derived from this, however this is only a marker, it will be not serialized) RenderableSerializer : public Serializer - this isn't pure virtual however shouldn't be never serialized directly (since the object made by this class is a pure virtual one) - These will use the tag <renderable> SkyboxSerializer : public RenderableSerializer - these will use the tag <skybox> EntitySerializer : public Serializer - these will use the tag <entity> many other classes will be added in future and they'll all derive form RenderableSerializer.
Now the problem is EntitySerializer have a pointer to a RenderableSerializer and when I serialize EntitySerializer the pointer to that class is considered to be a RenderableSerializer and not the derived class. I don't know at priori which class is the base class and this lead to problem. If I serialize a SkyboxSerializer I have the correct tag: a <skybox> which have inside a <renderable> and the datas are correct. If I try to serialize an Entity I had a lot of problem, mostly just make the library crash. As I've seen in the tutorial I should register all the derived classes before pass the pointer to the Archive. I did it registering the SkyboxSerializer classes but it lead to a wrong xml: a correct <entity> tag which have a correct <skybox> with all it's data but also a wrong <renderable> tag which have inside the same data of the tag <skybox> instead of the data of a RenderableSerializer class.
Now the question is: is there a correct way to use the library this way? With a pointer to a base class of which the derived is not known? My code is too big and I made many attempt to use the library so I'm not posting it in this message. If you need it I will post it. Thank you for your replies.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users It seems no one know the answer. I hope it's just I made a too vague request. Here's the partial code (load function are implemented the same way, simmetrically): EntitySerializer.hpp: void *save*(xml_oarchive& ar, const unsigned int version) const { ar << make_nvp("EntityName", _nome); // string ar.register_type(static_cast
(NULL)); // Note: Il 26/07/2010 18:58, BlueAngel ha scritto: this is just for debug, in the future I'll make a function in every class derived from Serializer which register itself when needed. ar << make_nvp(_renderable->getTagName().c_str(), _renderable); }
SkyboxSerializer.hpp: void *save*(xml_oarchive& ar, const unsigned int version) const { ar << make_nvp("renderable", boost::serialization::base_object< RenderableSerializer
(*this)); //RenderableSerializer::save(ar, version); // If I use this line instead of the previous it de/serializer correctly but I know this is a dirty work-around and I want to avoid it. ar << make_nvp("shader_file", _fx_file); // std::string ar << make_nvp("mesh_file", _mesh_filename); // std::string ar << make_nvp("cubemap_file", _tex_filename); // std::string } RenderableSerialier.hpp: void *save*(xml_oarchive& ar, const unsigned int version) const { ar << make_nvp("scala", _scala); // struct vector ar << make_nvp("rotazione", _rotazione); // struct vector ar << make_nvp("posizione", _posizione); // struct vector } VectorSerializer.hpp: struct vettore { float x, y, z; };
namespace boost { namespace serialization { template<class Archive> void *serialize*(Archive& ar, vettore& vec, const unsigned int version) { ar & make_nvp("x", vec.x); ar & make_nvp("y", vec.y); ar & make_nvp("z", vec.z); } } }
Serializer.hpp: virtual void *save*(xml_oarchive& ar, const unsigned int version) const = 0;
And this is the xml resultant: <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <!DOCTYPE boost_serialization>
<entity class_id="0" tracking_level="0" version="0"> <EntityName>skybohx</EntityName> <skybox class_id="1" tracking_level="1" version="0" object_id="_0"> <renderable class_id="2" tracking_level="1" version="0" object_id="_1"> <renderable object_id_reference="_1"></renderable> skybox.fx asd.x CubeMap.dds </renderable>skybox.fx asd.x CubeMap.dds </skybox> </entity>As you can see the renderable tag inside the skybox tag is wrong. The <renderable> should have: <scala> <x>3</x> <y>3</y> <z>3</z> </scala> <rotazione> <x>2</x> <y>2</y> <z>2</z> </rotazione> <posizione> <x>1</x> <y>1</y> <z>1</z> </posizione>
Why that tag serialize the derived class instead of itself? Thank you again for your answers.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users Hi, I don't want to insist but... I don't understand: The: ar << make_nvp("renderable", boost::serialization::base_object< RenderableSerializer >(*this)); of the *save* function of SkyboxSerializer seems to call itself again instead of the save function of the RenderableSerializer. How can this happen?
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users I still hope someone can answer me. I finally made everything work but with an issue: I had to remove the *save/load* functions and use just the *serialize* function. At the beginning I reverted all the functions above as template (like instead of void *save*(xml_oarchive& ar, const unsigned int version) const I reverted as: template<class Archive> void *save*(Archive& ar, const unsigned int version) and the same for the *load* function). The result was that the library call only the *save/load* in Serializer.hpp, there were no way to make it call the derived functions. I tried to brutally cast the pointer to the base object (like: ar & make_nvp(_tagName.c_str(), static_cast
(*this)); but I wont work, still the library call the functions in Serialier.hpp.
Now I reverted the functions to *serialize* instead of *save/load* and now everything works fine, the derived function are called before the base ones and Why not with *save/load*?

BlueAngel wrote: ... Your whole explanation is impossible for me to follow. But it seems you might be missing the section in the documentation: Reference/Serializable Concept/Class Types/Splitting into save/load whereBOOST_SERIALIZATION_SPLIT_MEMBER() is described. Robert Ramey

Il 29/07/2010 18:25, Robert Ramey ha scritto:
BlueAngel wrote: ... Your whole explanation is impossible for me to follow.
But it seems you might be missing the section in the documentation:
Reference/Serializable Concept/Class Types/Splitting into save/load
whereBOOST_SERIALIZATION_SPLIT_MEMBER() is described.
Robert Ramey
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
My apologize, you are right, I made a mess. I'll cleanup everything and make some specific questions.
participants (2)
-
BlueAngel
-
Robert Ramey