c++cereal

Serialize/ Deserialize ID instead of object in cereal


I want to serialize structs using cereal. One of them looks like this:

struct Material {
  std::shared_ptr<Texture> texture1;
  std::shared_ptr<Texture> texture2;
};

In my program, Textures are managed by a TextureManager:

class Texture {
  std::string id_; // Guaranteed to be unique
};

class TextureManager {
public:
  std::shared_ptr<Texture> get_texture_by_id(std::string_view id);

private:
  std::unordered_map<std::string, std::shared_ptr<Texture>> textures_;
};

I would like cereal to serialize these textures as their IDs, and have it use the TextureManager to load them.

{
  "texture1": "/assets/dog.bmp",
  "texture2": "/assets/foo.jpg"
}

Is this possible? If yes: How?


Solution

  • I solved this by specializing save and load for std::shared_ptr, as suggested by @Botje:

    namespace cereal {
    
    template <class Archive>
    void save(Archive& archive, const std::shared_ptr<Texture>& ptr)
    {
        archive(make_nvp("id", std::string(ptr->get_id()))); // Store just the ID
    }
    
    template <class Archive>
    void load(Archive& archive, std::shared_ptr<Texture>& ptr)
    {
        std::string id;
        archive(make_nvp("id", id));
    
        ptr = TextureManager::get().get_texture_by_id(id);
    }
    
    }