はじめに
oFにおけるsave/load機能を実装したい場合、ofxGuiとofxXmlSettingsでの実装が散見されるが、imguiでこれをやりたい。
cerealでもいいけど、ofParameterGroupに対応させるのめんどくさい。どうにか楽に実装できないか調べてみた。
結論
ofSerializeとofDeserializeを使う。
とりあえず一番これが低カロリーで実装できた。ofParameterGroupにも対応。
何より、コアの機能で実現できたのでメンテナンスのコストもない。(わーい)
保存
ofJson json;
ofSerialize(json, parameter_group_);
ofSaveJson("settings.json", json);
呼び出し
ofJson json = ofLoadJson("settings.json");
ofDeserialize(json, parameter_group_);
How to Use
ofxImGuiと組み合わせて使うとこんな感じと思う。
class BaseLayer
{
public:
BaseLayer(const std::string& unique_name)
: name_(unique_name)
{
parameter_group_.setName(name_);
}
void drawGui() {
auto Settings = ofxImGui::Settings();
ofxImGui::AddGroup(this->parameter_group_, Settings);
ImGui::Begin("Util");
if (ImGui::Button("Save")) {
ofJson json;
ofSerialize(json, parameter_group_);
ofSaveJson(name_ + "_settings.json", json);
}
if (ImGui::Button("Load")) {
ofJson json = ofLoadJson(name_ + "_settings.json");
ofDeserialize(json, parameter_group_);
}
ImGui::End();
}
std::string name_;
ofParameterGroup parameter_group_;
};
みたいに親クラスで実装して子クラスのコンストラクタで....
class MyGenLayer : public BaseLayer
{
MyGenLayer(const std::string& unique_name)
: BaseLayer(unique_name)
{
vec2_param.set("Emit Position", glm::vec2(5.0f, 5.0f), glm::vec2(0.0f, 0.0f), glm::vec2(12.0f, 12.0f));
vec3_param.set("Rotation", glm::vec3(5.0f, 5.0f, 5.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(12.0f, 12.0f, 12.0f));
parameter_group_.add(vec2_param);
parameter_group_.add(vec3_param);
ofJson json = ofLoadJson(name_ + "_settings.json");
ofDeserialize(json, parameter_group_);
}
void update() {}
void draw() {}
private:
//user define
ofParameter<glm::vec2> vec2_param;
ofParameter<glm::vec3> vec3_param;
};