Daniel
Daniel

Reputation: 588

Serializing a class with boost that has embedded classes, but only the information in the wrapper is serialized

I am using Boost 1.47.0 to Serialize some classes for network transmission. I'm not very familiar with the library but I've been through the documentation quite a bit and now after 2 or 3 days of not getting this to work I need some help.

I have a class

class NetworkMessage
{
    public:
        NetworkMessage(){};
        void addPlayer(Player* player);
        std::string serializeToString();
        Player getPlayer();
        virtual ~NetworkMessage();
    protected:
    private:
        Player players;

        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            ar & players;
        }
};

At this point I've limited it to only sending one player's information in a message and that is working fine, but my player contains another class in it, which is the camera. All of my native c++ members on my player class serialize correctly. However when I deserialize it all the information for my players camera is lost. But the other information is kept and works. I've debugged my network transmissions and the message being received has all the serialized information in it.

I'm not sure if I've just misunderstood how the library works but a helping hand would be very useful, even just some advice to guide me in the right direction of what might be wrong.

Also just as a side note, I'm using the standard serialize method that boost provides.

class Player
{
    public:
        Player(){};
        Player(float _x, float _y, float _z, std::string _name);
        void setCamera(Camera camera);
        vec3 getLocation();
        std::string getName();
        Camera getCamera();
        virtual ~Player();
    protected:
    private:
        float x;
        float y;
        float z;
        std::string name;
        Camera playerCam;

    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & x;
        ar & y;
        ar & z;
        ar & name;
        ar & playerCam;
    }

};

EDIT: Added the camera class.

class Camera
{
    public:
        Camera(){};
        Camera(vec3 r, vec3 u, vec3 d);
        Camera& operator=(Camera rhs);
        void rotateCamera(int xDelta, int yDelta, int xMid, int yMid);
        void setKey(unsigned char key, bool state);
        void updateCamera();
        void print();
        void printVec(vec3 vectr);
        mat4 getViewMatrix();
        vec3 getEye();

    private:

        mat4 view;
        vec3 r;
        vec3 u;
        vec3 d;
        vec3 direction;
        bool keyStates[256];

        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            ar &r;
            ar &u;
            ar &d;
            ar &direction;
            ar &keyStates;
            ar &view;
        }
};

I'm also adding the code for serializing GLM's vectors and matrices.

namespace boost
{
    namespace serialization
    {
        template<class Archive>
        void serialize(Archive & ar, glm::detail::tmat4x4<float> transform, const unsigned int version)
        {
            ar & transform[0];
            ar & transform[1];
            ar & transform[2];
            ar & transform[3];
        }

        template<class Archive>
        void serialize(Archive & ar, glm::detail::tvec3<float> vec, const unsigned int version)
        {
            ar & vec.x;
            ar & vec.y;
            ar & vec.z;
        }

        template<class Archive>
        void serialize(Archive & ar, glm::detail::tvec4<float> vec, const unsigned int version)
        {
            ar & vec.x;
            ar & vec.y;
            ar & vec.z;
            ar & vec.w;
        }

        template<class Archive>
        void serialize(Archive & ar, glm::detail::tvec2<float> vec, const unsigned int version)
        {
            ar & vec.x;
            ar & vec.y;
        }
    }
}

Upvotes: 1

Views: 468

Answers (1)

Daniel
Daniel

Reputation: 588

Okay so I found the problem, and I'm kicking myself right now.

In my serialization for my glm related goodies I needed to pass them as a reference. Which I wasn't doing. so basically I had :

template<class Archive>
void serialize(Archive & ar, glm::detail::tvec3<glm::mediump_float> vec, const unsigned int version)
{
    ar & boost::serialization::make_nvp("x", vec.x);
    ar & boost::serialization::make_nvp("y", vec.y);
    ar & boost::serialization::make_nvp("z", vec.z);
}

but it should have been :

template<class Archive>
void serialize(Archive & ar, glm::detail::tvec3<glm::mediump_float>& vec, const unsigned int version)
{
    ar & boost::serialization::make_nvp("x", vec.x);
    ar & boost::serialization::make_nvp("y", vec.y);
    ar & boost::serialization::make_nvp("z", vec.z);
}

Thank you everyone that tried to help me :)

Upvotes: 3

Related Questions