ofxAutoSaveParam.h
#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