Last active
April 3, 2016 14:59
-
-
Save satoruhiga/22b38349ba14e65c550b to your computer and use it in GitHub Desktop.
ofxAutoSaveParam.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
/* | |
USAGE: | |
ofxAutoSaveParam param; | |
class ofApp { | |
public: | |
float my_float; | |
ofVec3f my_vec; | |
void setup() | |
{ | |
// param.setup("custom_filename.xml"); // option. default = params.xml | |
// attach to vars | |
param.attach("my_float", my_float); | |
param.attach("my_vec", my_vec); | |
// key access | |
param.setString("test", "my string"); | |
cout << param.getString("test", "defalut value") << endl; // returns "my string" | |
} | |
}; | |
*/ | |
#include "ofMain.h" | |
#include "Poco/Util/XMLConfiguration.h" | |
class ofxAutoSaveParam | |
{ | |
public: | |
ofxAutoSaveParam() | |
: config(new Poco::Util::XMLConfiguration) | |
{ | |
setup("params.xml"); | |
} | |
~ofxAutoSaveParam() | |
{ | |
save(); | |
} | |
void setup(const string& path) | |
{ | |
this->path = path; | |
load(); | |
} | |
bool load() | |
{ | |
config->loadEmpty("root"); | |
if (ofFile::doesFileExist(path)) | |
{ | |
config->load(ofToDataPath(path)); | |
return true; | |
} | |
return false; | |
} | |
void save() | |
{ | |
for (int i = 0; i < params.size(); i++) | |
params[i]->save(config); | |
config->save(ofToDataPath(path)); | |
} | |
float getNumber(const string& key, float default_value = 0) const | |
{ | |
if (config->has(key) == false) | |
return default_value; | |
return config->getDouble(key); | |
} | |
void setNumber(const string& key, float value) | |
{ | |
config->setDouble(key, value); | |
} | |
string getString(const string& key, string default_value = "") const | |
{ | |
if (config->has(key) == false) | |
return default_value; | |
return config->getString(key); | |
} | |
void setString(const string& key, const string& value) | |
{ | |
config->setString(key, value); | |
} | |
template <typename T> | |
T get(const string& key, T default_value = T()); | |
template <typename T> | |
void set(const string& key, const T& value); | |
template <typename T> | |
void attach(const string& key, T& value) | |
{ | |
ofPtr<Parameter> param = ofPtr<Parameter>(new Parameter_<T>(key, value)); | |
params.push_back(param); | |
try | |
{ | |
param->load(config); | |
} | |
catch (Poco::NotFoundException& e) | |
{ | |
value = T(); | |
} | |
} | |
public: | |
struct Parameter | |
{ | |
string key; | |
Parameter(const string& key) | |
: key(key) | |
{} | |
virtual ~Parameter() {} | |
virtual void load(Poco::AutoPtr<Poco::Util::XMLConfiguration>& config) {} | |
virtual void save(Poco::AutoPtr<Poco::Util::XMLConfiguration>& config) {} | |
}; | |
template <typename T> | |
struct Parameter_ : public Parameter | |
{}; | |
protected: | |
string path; | |
Poco::AutoPtr<Poco::Util::XMLConfiguration> config; | |
vector<ofPtr<Parameter> > params; | |
}; | |
#define DEFINE_BASIC_PARAM_TYPE(TYPE, XML_TYPE) \ | |
template <> \ | |
struct ofxAutoSaveParam::Parameter_<TYPE> : public ofxAutoSaveParam::Parameter { \ | |
TYPE* value; \ | |
Parameter_(const string& key, TYPE& v) \ | |
: Parameter(key) \ | |
, value(&v) \ | |
{} \ | |
\ | |
void load(Poco::AutoPtr<Poco::Util::XMLConfiguration>& config) { \ | |
if (config->has(key) == false) return; \ | |
*value = config->get ## XML_TYPE(key); \ | |
} \ | |
\ | |
void save(Poco::AutoPtr<Poco::Util::XMLConfiguration>& config) { \ | |
config->set ## XML_TYPE(key, *value); \ | |
} \ | |
}; | |
DEFINE_BASIC_PARAM_TYPE(float, Double); | |
DEFINE_BASIC_PARAM_TYPE(double, Double); | |
DEFINE_BASIC_PARAM_TYPE(int, Int); | |
DEFINE_BASIC_PARAM_TYPE(unsigned int, Int); | |
DEFINE_BASIC_PARAM_TYPE(string, String); | |
DEFINE_BASIC_PARAM_TYPE(bool, Bool); | |
#undef DEFINE_PARAM_TYPE | |
#define DEFINE_LOAD_PARAM_ELEMENT(VAL, XML_TYPE) if (config->has(key)) { value->VAL = config->get ## XML_TYPE(key + "[@" #VAL "]"); } | |
#define DEFINE_SAVE_PARAM_ELEMENT(VAL, XML_TYPE) config->set ## XML_TYPE(key + "[@" #VAL "]" , value->VAL); | |
#define DEFINE_LOAD_PARAM_ELEMENT2(VAL, XML_NAME, XML_TYPE) if (config->has(key)) { value->VAL = config->get ## XML_TYPE(key + "[@" #XML_NAME "]"); } | |
#define DEFINE_SAVE_PARAM_ELEMENT2(VAL, XML_NAME, XML_TYPE) config->set ## XML_TYPE(key + "[@" #XML_NAME "]" , value->VAL); | |
template <> | |
struct ofxAutoSaveParam::Parameter_<ofVec3f> : public ofxAutoSaveParam::Parameter{ | |
ofVec3f* value; | |
Parameter_(const string& key, ofVec3f& v) | |
: Parameter(key) | |
, value(&v) | |
{} | |
void load(Poco::AutoPtr<Poco::Util::XMLConfiguration>& config) { | |
if (config->has(key) == false) return; | |
DEFINE_LOAD_PARAM_ELEMENT(x, Double); | |
DEFINE_LOAD_PARAM_ELEMENT(y, Double); | |
DEFINE_LOAD_PARAM_ELEMENT(z, Double); | |
} | |
void save(Poco::AutoPtr<Poco::Util::XMLConfiguration>& config) { | |
DEFINE_SAVE_PARAM_ELEMENT(x, Double); | |
DEFINE_SAVE_PARAM_ELEMENT(y, Double); | |
DEFINE_SAVE_PARAM_ELEMENT(z, Double); | |
} | |
}; | |
template <> | |
struct ofxAutoSaveParam::Parameter_<ofRectangle> : public ofxAutoSaveParam::Parameter{ | |
ofRectangle* value; | |
Parameter_(const string& key, ofRectangle& v) | |
: Parameter(key) | |
, value(&v) | |
{} | |
void load(Poco::AutoPtr<Poco::Util::XMLConfiguration>& config) { | |
if (config->has(key) == false) return; | |
DEFINE_LOAD_PARAM_ELEMENT(x, Double); | |
DEFINE_LOAD_PARAM_ELEMENT(y, Double); | |
DEFINE_LOAD_PARAM_ELEMENT(width, Double); | |
DEFINE_LOAD_PARAM_ELEMENT(height, Double); | |
} | |
void save(Poco::AutoPtr<Poco::Util::XMLConfiguration>& config) { | |
DEFINE_SAVE_PARAM_ELEMENT(x, Double); | |
DEFINE_SAVE_PARAM_ELEMENT(y, Double); | |
DEFINE_SAVE_PARAM_ELEMENT(width, Double); | |
DEFINE_SAVE_PARAM_ELEMENT(height, Double); | |
} | |
}; | |
template <> | |
struct ofxAutoSaveParam::Parameter_<ofMatrix4x4> : public ofxAutoSaveParam::Parameter { | |
ofMatrix4x4* value; | |
Parameter_(const string& key, ofMatrix4x4& v) | |
: Parameter(key) | |
, value(&v) | |
{} | |
void load(Poco::AutoPtr<Poco::Util::XMLConfiguration>& config) { | |
if (config->has(key) == false) return; | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[0][0], m00, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[0][1], m01, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[0][2], m02, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[0][3], m03, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[1][0], m10, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[1][1], m11, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[1][2], m12, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[1][3], m13, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[2][0], m20, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[2][1], m21, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[2][2], m22, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[2][3], m23, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[3][0], m30, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[3][1], m31, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[3][2], m32, Double); | |
DEFINE_LOAD_PARAM_ELEMENT2(_mat[3][3], m33, Double); | |
} | |
void save(Poco::AutoPtr<Poco::Util::XMLConfiguration>& config) { | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[0][0], m00, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[0][1], m01, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[0][2], m02, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[0][3], m03, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[1][0], m10, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[1][1], m11, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[1][2], m12, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[1][3], m13, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[2][0], m20, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[2][1], m21, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[2][2], m22, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[2][3], m23, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[3][0], m30, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[3][1], m31, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[3][2], m32, Double); | |
DEFINE_SAVE_PARAM_ELEMENT2(_mat[3][3], m33, Double); | |
} | |
}; | |
template <typename T> | |
inline T ofxAutoSaveParam::get(const string& key, T default_value) | |
{ | |
T value; | |
Parameter_<T> param(key, value); | |
param.load(config); | |
return value; | |
} | |
template <typename T> | |
inline void ofxAutoSaveParam::set(const string& key, const T& value_) | |
{ | |
T value = value_; | |
Parameter_<T> param(key, value); | |
param.save(config); | |
} | |
#undef DEFINE_SAVE_PARAM_ELEMENT | |
#undef DEFINE_LOAD_PARAM_ELEMENT |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment