Last active
April 18, 2017 23:02
-
-
Save heisters/4764fd11cab2eee2dc69 to your computer and use it in GitHub Desktop.
Cinder class for managing configuration with defaults, a UI, and persistence
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
#include "Config.h" | |
#include "cinder/app/App.h" | |
#include <boost/algorithm/string.hpp> | |
using namespace std; | |
using namespace ci; | |
Config::Config( const ci::fs::path &path ) : | |
mPath( path ), | |
mJson( app::loadAsset( path ) ) | |
{ | |
} | |
Config::~Config() | |
{ | |
} | |
struct to_json_visitor : boost::static_visitor<> { | |
to_json_visitor( JsonTree &json ) : json( json ) {} | |
JsonTree &json; | |
template< typename T > | |
void operator()( T* const ptr ) const | |
{ | |
json = JsonTree( json.getKey(), *ptr ); | |
} | |
}; | |
void Config::save() | |
{ | |
for ( const auto& setting : mSettingPointers ) { | |
const auto& k = setting.first; | |
JsonTree j = mJson.getChild( k ); | |
boost::apply_visitor( to_json_visitor( j ), setting.second ); | |
mJson.getChild( k ) = j; | |
} | |
mJson.write( app::getAssetPath( mPath ) ); | |
} | |
JsonTree* Config::ensurePath( const string &key ) | |
{ | |
deque< string > paths; | |
boost::split( paths, key, boost::is_any_of( "." ) ); | |
JsonTree *t = &mJson; | |
for ( const auto& p : paths ) { | |
t->hasChild( p ) ? t->getChild( p ) : t->addChild( JsonTree::makeObject( p ) ); | |
t = &t->getChild( p ); | |
} | |
return t; | |
} | |
JsonTree& Config::operator[]( const std::string &relativePath ) | |
{ | |
return mJson[ relativePath ]; | |
} | |
const JsonTree& Config::operator[]( const std::string &relativePath ) const | |
{ | |
return mJson[ relativePath ]; | |
} |
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 | |
#include "cinder/Json.h" | |
#include "cinder/Color.h" | |
#include "cinder/Vector.h" | |
#include <boost/variant.hpp> | |
class Config { | |
private: | |
typedef boost::variant< | |
int32_t*, | |
float*, | |
bool*, | |
std::string* | |
> | |
variant_t; | |
public: | |
Config( const ci::fs::path &path ); | |
~Config(); | |
void save(); | |
// Binds a config key to a variable pointer. | |
template< typename T > | |
Config& operator()( const std::string &key, T *setting ) | |
{ | |
mSettingPointers[ key ] = setting; | |
if ( mJson.hasChild( key ) ) { | |
auto lvalue = *setting; | |
*setting = mJson.getChild( key ).getValue< decltype( lvalue ) >(); | |
} | |
// create paths that don't exist, after the values are set | |
ensurePath( key ); | |
return *this; | |
} | |
ci::JsonTree& operator[]( const std::string &relativePath ); | |
const ci::JsonTree& operator[]( const std::string &relativePath ) const; | |
bool hasKey( const std::string &key ) const { return mJson.hasChild( key ); } | |
private: | |
ci::JsonTree* ensurePath( const std::string &key ); | |
std::map< std::string, variant_t > mSettingPointers; | |
ci::fs::path mPath; | |
ci::JsonTree mJson; | |
}; | |
inline ci::Colorf colorfFromJson( const ci::JsonTree& json ) | |
{ | |
return ci::Colorf( json.getValueAtIndex< float >( 0 ), json.getValueAtIndex< float >( 1 ), json.getValueAtIndex< float >( 2 ) ); | |
} | |
inline ci::vec3 vec3FromJson( const ci::JsonTree& json ) | |
{ | |
return ci::vec3( json.getValueAtIndex< float >( 0 ), json.getValueAtIndex< float >( 1 ), json.getValueAtIndex< float >( 2 ) ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment