Reputation: 2307
So i'm legit confused. It won't compile for an external serialization function. It gives the error
cereal could not find any output serialization functions for the provided type and archive combination.
So the code below doesn't compile
#include <fstream>
#include <glm/glm.hpp>
#include "SceneObject.h"
#include <cereal/cereal.hpp>
#include <cereal/archives/json.hpp>
template<typename Archive> void serialize(Archive& archive, glm::vec3& v3)
{
archive(cereal::make_nvp("x", v3.x), cereal::make_nvp("y", v3.y), cereal::make_nvp("z", v3.z));
}
struct something
{
public:
float x, y, z;
};
template<typename Archive> void serialize(Archive& archive, something& v3)
{
archive(cereal::make_nvp("x", v3.x), cereal::make_nvp("y", v3.y), cereal::make_nvp("z", v3.z));
}
int main(int argc, char** argv)
{
SceneObject test;
test.transform().setPosition(1.0f,2.0f,3.0f);
{
std::ofstream file("TestPath.json");
cereal::JSONOutputArchive output(file);
glm::vec3 p = test.transform().getPosition();
output(p);
}
return 0;
}
but this DOES compile
#include <fstream>
#include <glm/glm.hpp>
#include "SceneObject.h"
#include <cereal/cereal.hpp>
#include <cereal/archives/json.hpp>
template<typename Archive> void serialize(Archive& archive, glm::vec3& v3)
{
archive(cereal::make_nvp("x", v3.x), cereal::make_nvp("y", v3.y), cereal::make_nvp("z", v3.z));
}
struct something
{
public:
float x, y, z;
};
template<typename Archive> void serialize(Archive& archive, something& v3)
{
archive(cereal::make_nvp("x", v3.x), cereal::make_nvp("y", v3.y), cereal::make_nvp("z", v3.z));
}
int main(int argc, char** argv)
{
SceneObject test;
test.transform().setPosition(1.0f,2.0f,3.0f);
{
std::ofstream file("TestPath.json");
cereal::JSONOutputArchive output(file);
glm::vec3 p = test.transform().getPosition();
something s;
s.x = p.x;
s.y = p.y;
s.z = p.z;
output(s);
}
return 0;
}
I literally copy and pasted the save code from glm::vec3 to something and just changed glm::vec3 to 'something'. It makes NO sense to me why it would work for one and not the other. I think it might be a namespace thing, but I have no clue how to fix that.
Upvotes: 6
Views: 2679
Reputation: 81
I can confirm your conclusion. in case of externally defined serialize-functions you would place them in the same namespace to enable cereal to see/use them.
a complete/templated set of serialization-functions for all flavors of vec2-4, mat2-4 and quat types can be achieved like this (requires glm-version >=0.9.6, https://www.g-truc.net/post-0693.html):
#include <glm/glm.hpp>
#include <cereal/cereal.hpp>
namespace glm
{
template<class Archive, class T>
void serialize(Archive &archive, glm::vec<2, T, glm::defaultp> &v)
{
archive(cereal::make_nvp("x", v.x),
cereal::make_nvp("y", v.y));
}
template<class Archive, class T>
void serialize(Archive &archive, glm::vec<3, T, glm::defaultp> &v)
{
archive(cereal::make_nvp("x", v.x),
cereal::make_nvp("y", v.y),
cereal::make_nvp("z", v.z));
}
template<class Archive, class T>
void serialize(Archive &archive, glm::vec<4, T, glm::defaultp> &v)
{
archive(cereal::make_nvp("x", v.x),
cereal::make_nvp("y", v.y),
cereal::make_nvp("z", v.z),
cereal::make_nvp("w", v.w));
}
// glm matrices serialization
template<class Archive, class T>
void serialize(Archive &archive, glm::mat<2, 2, T, glm::defaultp> &m){ archive(m[0], m[1]); }
template<class Archive, class T>
void serialize(Archive &archive, glm::mat<3, 3, T, glm::defaultp> &m){ archive(m[0], m[1], m[2]); }
template<class Archive, class T>
void serialize(Archive &archive, glm::mat<4, 4, T, glm::defaultp> &m){ archive(m[0], m[1], m[2], m[3]); }
template<class Archive, class T>
void serialize(Archive &archive, glm::qua<T, glm::defaultp> &q)
{
archive(cereal::make_nvp("x", q.x),
cereal::make_nvp("y", q.y),
cereal::make_nvp("z", q.z),
cereal::make_nvp("w", q.w));
}
}// namespace glm
Upvotes: 0
Reputation: 2307
Well apparently posting made me find the solution.
You need to make sure the serialize functions share the same namespace so if I wrap them like
namespace glm
{
template<typename Archive> void serialize(Archive& archive, glm::vec3& v3)
{
archive(cereal::make_nvp("x", v3.x), cereal::make_nvp("y", v3.y), cereal::make_nvp("z", v3.z));
}
}
It works. Kinda odd, but it is what it is.
Upvotes: 12