Boost logo

Boost Users :

Subject: [Boost-users] Serialization of polymorphic types defined by plugins loaded at runtime
From: Sam Spilsbury (smspillaz_at_[hidden])
Date: 2010-06-08 22:03:10


Hi Everyone,

I'm working on a project called "compiz" which is a plugin-based
compositing window manager for X11 written in C++[1]. Recently, I've
been adding serialization through the use of a wrapper class such that
plugin class inherits this wrapper class, which automatically loads
serialized data when instantiated and saves it when destroyed (by
using a function that is called at the beginning of the plugin class
destructor.

My main problem at the moment is that I have a boost::ptr_vector of a
class called "Element", which is a base for which other plugins derive
and add their own "move" "start" "stop" functions as well as any
additional properties they wish to attach to the "Element".

So for example, this is where the ptr_vector is kept:

class PrivateElementAnimation
{
    public:

        PrivateElementAnimation (CompString type,
                                  int nElement,
                                  int size,
                                  int speed,
                                  int iter,
                                  bool rotate);
        
        PrivateElementAnimation () {};
        
        template <class Archive>
        void serialize (Archive &ar, const unsigned int version)
        {
            ar & mElements; // Exception unregistered_type is raised here
        }

        boost::ptr_vector<Element> mElements;
};

This is the definition of the class "Element"

class Element
{
    public:

        Element ();

        ElementAnimation *anim;

        float x, y, z;
        float dx, dy, dz;
        float rSpeed;
        int rDirection;
        int rAngle;

        float opacity;
        
        template <class Archive>
        void serialize (Archive &ar, const unsigned int version)
        {
            fprintf (stderr, "saving an element\n");
            ar & x;
            ar & y;
            ar & z;
            ar & dx;
            ar & dy;
            ar & dz;
            ar & rSpeed;
            ar & rDirection;
            ar & rAngle;
            ar & opacity;
        }

        virtual bool init ();
        virtual void move ();
        virtual void fini ();
    private:

        void defaultInit ();
        void regenerateOffscreen ();

    friend class ElementAnimation;
    friend class PrivateElementScreen;
};

And this is the definition of a derived class, FireflyElement, which
is stored in a separate library loaded at runtime. (E.g,
boost::serialization doesn't know this type exists at compile time of
Element and PrivateElementAnimation.

class FireflyElement :
    public Element
{
    public:

        float lifespan;
        float age;
        float lifecycle;
        float dx[4], dy[4], dz[4];

        bool init ();
        void move ();
        void fini ();

        template <class Archive>
        void serialize (Archive &ar, const unsigned int version)
        {
            boost::serialization::base_object <Element> (*this);
            ar & lifespan;
            ar & age;
            ar & lifecycle;
            ar & dx;
            ar & dy;
            ar & dz;
        }

        static Element *
        create ();

        ~FireflyElement ();
        FireflyElement ();
        friend class boost::serialization::access;
    private:
};

BOOST_CLASS_EXPORT_GUID (FireflyElement, "FireflyElement");
// this class has a default constructor
BOOST_SERIALIZATION_FACTORY_0 (FireflyElement);

Of course, at this point, when I try to run the program, boost raises
an exception unregistered_type, which as far as I know means that it
doesn't know about the type relationship between FireflyElement and
Element when trying to serialize Element *. I had a look at the
documentation, and it appears that this is the way to register such
type relationships (by using EXPORT_GUID, SERIALIZATION_FACTORY_0 and
boost::serialization::base_object <Element> (*this); in the serialize
function.

I also had a look at the documentation for "plugins" and "dll's"[2]
and couldn't find anything of use there.

Does anybody know how to resolve this?

Kind Regards,

Sam

[1] http://www.compiz.org
[2] http://www.boost.org/doc/libs/1_38_0/libs/serialization/doc/special.html#derivedpointers

-- 
Sam Spilsbury

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net