Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
50 KB
Referenced Files
None
Subscribers
None
diff --git a/util/configuration.cpp b/util/configuration.cpp
index 0c0bec1c..1d3e93f0 100644
--- a/util/configuration.cpp
+++ b/util/configuration.cpp
@@ -1,984 +1,984 @@
#include "configuration.h"
#include "input/keyboard.h"
#include "exceptions/load_exception.h"
#include "tokenreader.h"
#include "token.h"
#include "file-system.h"
#include "input/input.h"
#include "debug.h"
#include <sstream>
#include <fstream>
#include <stdlib.h>
#include <string>
#include <map>
#ifdef USE_SDL
#if SDL_VERSION_ATLEAST(1, 3, 0)
static const std::string INPUT_TYPE = "SDL1.3";
#else
static const std::string INPUT_TYPE = "SDL";
#endif
#endif
#ifdef USE_ALLEGRO
static const std::string INPUT_TYPE = "Allegro";
#endif
#ifdef USE_ALLEGRO5
static const std::string INPUT_TYPE = "Allegro5";
#endif
bool Configuration::save = true;
Util::ReferenceCount<Token> Configuration::data;
/* text that appears in the config file */
#define define_config(n,str) static const char * config_##n = str
define_config(attack1, "attack1");
define_config(attack2, "attack2");
define_config(attack3, "attack3");
define_config(attack4, "attack4");
define_config(attack5, "attack5");
define_config(attack6, "attack6");
define_config(configuration, "configuration");
define_config(cooperative, "cooperative");
// define_config(current_game, "current-game");
define_config(down, "down");
define_config(free_for_all, "free-for-all");
define_config(fullscreen, "fullscreen");
define_config(game_speed, "game-speed");
define_config(invincible, "invincible");
define_config(jump, "jump");
define_config(quit, "quit");
define_config(keyboard_configuration, "keyboard-configuration");
define_config(input, "input");
define_config(joystick_configuration, "joystick-configuration");
define_config(left, "left");
define_config(lives, "lives");
define_config(menu_font, "menu-font");
define_config(menu_font_width, "menu-font-width");
define_config(menu_font_height, "menu-font-height");
define_config(npc_buddies, "npc-buddies");
define_config(number, "number");
define_config(play_mode, "play-mode");
define_config(right, "right");
define_config(screen_size, "screen-size");
define_config(sound, "sound");
define_config(music, "music");
define_config(up, "up");
define_config(quality_filter, "quality-filter");
define_config(fps, "frames-per-second");
define_config(language, "language");
define_config(mugen_motif, "mugen-motif");
/* version of the game: 3.3, 3.4, 4.24 */
define_config(version, "version");
#undef def_config
using namespace std;
static const int InvalidKey = 0;
static const Joystick::Key InvalidJoystick = Joystick::Invalid;
/* don't save the configuration while loading it */
class Disable{
public:
Disable(){
last = Configuration::getSave();
Configuration::disableSave();
}
~Disable(){
Configuration::setSave(last);
}
bool last;
};
/* FIXME: move this to some utils module */
static std::vector<std::string> split(std::string str, char splitter){
std::vector<std::string> strings;
size_t next = str.find(splitter);
while (next != std::string::npos){
strings.push_back(str.substr(0, next));
str = str.substr(next+1);
next = str.find(splitter);
}
if (str != ""){
strings.push_back(str);
}
return strings;
}
static std::string last(const vector<string> & what){
return what.at(what.size() - 1);
}
/* Create a token that contains the entire path.
* path = "foo/bar/baz"
* out = (foo (bar (baz)))
*/
static Token * createToken(const string & path){
vector<string> paths = split(path, '/');
Token * out = new Token();
Token * current = out;
for (vector<string>::iterator it = paths.begin(); it != paths.end(); it++){
current->addToken(new Token(*it, false));
if (paths.end() - it > 1){
Token * next = new Token();
current->addToken(next);
current = next;
}
}
return out;
}
/* Create a token with the given path and give it a value */
template <class Value>
static Token * createToken(const string & path, const Value & value){
Token * out = createToken(path);
*out << value;
return out;
}
template <class Value, class Value2>
static Token * createToken(const string & path, const Value & value, const Value2 & value2){
Token * out = createToken(path);
*out << value;
*out << value2;
return out;
}
/* remove a path if it exists */
static void removeToken(Token * data, const std::string & path){
Token * found = data->findToken(path);
/* See if the token already exists. If it does then remove it from its
* parent and add a new token to the parent with the updated value.
*/
if (found != NULL){
Token * parent = found->getParent();
parent->removeToken(found);
}
}
static void updateToken(Token * data, const std::string & path, Token * add){
if (data == NULL){
delete add;
}
Token * found = data->findToken(path);
/* See if the token already exists. If it does then remove it from its
* parent and add a new token to the parent with the updated value.
*/
if (found != NULL){
Token * parent = found->getParent();
parent->removeToken(found);
parent->addToken(add);
} else {
const vector<string> paths = split(path, '/');
Token * start = data;
for (int index = 1; index < paths.size() - 1; index++){
string where = paths[index];
Token * next = start->findToken(string("_/") + where);
if (next == NULL){
ostringstream out;
bool first = true;
for (int from = index; from < paths.size(); from++){
if (!first){
out << "/";
}
out << paths[from];
first = false;
}
/* If we run out of found paths then create a token with an empty
* value for the unfound paths we have so far and call updateToken
* again. This time the entire path will be there
* so the 'found = ...' logic will work.
*/
start->addToken(createToken(out.str(), string("")));
updateToken(data, path, add);
return;
} else {
start = next;
}
}
/* It probably shouldn't be possible to get here. If the entire
* path was there then the findToken() logic above should have worked.
*/
start->addToken(add);
}
}
template <class Value>
static void updateToken(Token * data, const string & path, const Value & value){
if (data == NULL){
return;
}
updateToken(data, path, createToken(last(split(path, '/')), value));
}
void Configuration::setProperty(const string & name, const string & value){
updateToken(getRawData(), string(config_configuration) + "/" + name, value);
saveConfiguration();
}
static Token * getPropertyX(Token * data, const std::string & path){
return data->findToken(string(config_configuration) + "/" + path);
}
template <class Out>
static Out getPropertyX(Token * data, const std::string & path, const Out & defaultValue){
if (data == NULL){
return defaultValue;
}
Out out;
if (data->match(string(config_configuration) + "/" + path, out)){
return out;
}
updateToken(data, string(config_configuration) + "/" + path, defaultValue);
return defaultValue;
}
void Configuration::setDefaultKeys(int config){
/* Set the keys token to an empty value */
ostringstream path;
path << config_input << "/" << config << "/keys";
setProperty(path.str(), createToken("keys"));
/* Call the get methods to reset the defaults */
int ignore;
ignore = getRight(config);
ignore = getLeft(config);
ignore = getUp(config);
ignore = getDown(config);
ignore = getAttack1(config);
ignore = getAttack2(config);
ignore = getAttack3(config);
ignore = getAttack4(config);
ignore = getAttack5(config);
ignore = getAttack6(config);
ignore = getJump(config);
}
/* hopefully this is only used right before setting all the values
* since the key mappings are bogus in here'
*/
Configuration::Configuration(){
}
Configuration::Configuration(const Configuration & config){
menuFont = config.menuFont;
}
Configuration & Configuration::operator=(const Configuration & config){
Disable disable;
setMenuFont(config.getMenuFont());
return *this;
}
Configuration::~Configuration(){
}
Util::ReferenceCount<Menu::FontInfo> Configuration::getMenuFont(){
return menuFont;
}
bool Configuration::hasMenuFont(){
return menuFont != NULL;
}
void Configuration::setMenuFont(const Util::ReferenceCount<Menu::FontInfo> & info){
menuFont = info;
saveConfiguration();
}
void Configuration::setMenuFontWidth(int x){
setProperty(config_menu_font_width, x);
saveConfiguration();
}
int Configuration::getMenuFontWidth(){
return getProperty(config_menu_font_width, 24);
}
void Configuration::setMenuFontHeight(int x){
setProperty(config_menu_font_height, x);
saveConfiguration();
}
int Configuration::getMenuFontHeight(){
return getProperty(config_menu_font_height, 24);
}
static string joystickKeyName(Joystick::Key key){
switch (key){
case Joystick::Up: return "up";
case Joystick::Down: return "down";
case Joystick::Left: return "left";
case Joystick::Right: return "right";
case Joystick::Button1: return "button1";
case Joystick::Button2: return "button2";
case Joystick::Button3: return "button3";
case Joystick::Button4: return "button4";
case Joystick::Button5: return "button5";
case Joystick::Button6: return "button6";
case Joystick::Start: return "start";
case Joystick::Quit: return "quit";
case Joystick::Invalid: return "invalid";
}
return "?";
}
void Configuration::setCustomButton(Joystick::Key key, int config, const std::string & name, int button){
if (key != Joystick::Invalid){
ostringstream base;
base << config_configuration << "/" << config_input << "/" << INPUT_TYPE << "/";
base << "joystick" << "/" << config << "/";
- base << '"' << name << '"' << "/" << joystickKeyName(key);
+ base << name << "/" << joystickKeyName(key);
removeToken(getRawData(), base.str());
updateToken(getRawData(), base.str() + "/button", button);
saveConfiguration();
}
}
void Configuration::setCustomAxis(Joystick::Key key, int config, const string & name, int stick, int axis, double low, double high){
if (key != Joystick::Invalid){
ostringstream base;
base << config_configuration << "/" << config_input << "/" << INPUT_TYPE << "/";
base << "joystick" << "/" << config << "/";
- base << '"' << name << '"' << "/" << joystickKeyName(key);
+ base << name << "/" << joystickKeyName(key);
removeToken(getRawData(), base.str());
updateToken(getRawData(), base.str() + "/stick", stick);
updateToken(getRawData(), base.str() + "/axis", axis);
updateToken(getRawData(), base.str() + "/low", low);
updateToken(getRawData(), base.str() + "/high", high);
saveConfiguration();
}
}
void Configuration::setKey(int config, const string & name, int value){
if (value != InvalidKey){
ostringstream path;
path << config_configuration << "/" << config_input << "/" << config << "/keys/" << name;
updateToken(getRawData(), path.str(), value);
saveConfiguration();
}
}
void Configuration::setRight(int config, int i){
setKey(config, "right", i);
}
void Configuration::setLeft(int config, int i){
setKey(config, "left", i);
}
void Configuration::setUp(int config, int i){
setKey(config, "up", i);
}
void Configuration::setDown(int config, int i){
setKey(config, "down", i);
}
void Configuration::setAttack1(int config, int i){
setKey(config, "attack1", i);
}
void Configuration::setAttack2(int config, int i){
setKey(config, "attack2", i);
}
void Configuration::setAttack3(int config, int i){
setKey(config, "attack3", i);
}
void Configuration::setAttack4(int config, int i){
setKey(config, "attack4", i);
}
void Configuration::setAttack5(int config, int i){
setKey(config, "attack5", i);
}
void Configuration::setAttack6(int config, int i){
setKey(config, "attack6", i);
}
void Configuration::setJump(int config, int i){
setKey(config, "jump", i);
}
int Configuration::getKey(int config, const string & name, int defaultValue){
ostringstream path;
path << config_input << "/" << INPUT_TYPE << "/" << config << "/keys/" << name;
return getProperty(path.str(), defaultValue);
}
/* this nonsense is just to convert a regular integer into an enum */
/*
static Configuration::JoystickInput intToJoystick(int a){
switch (a){
case Joystick::Up : return Joystick::Up;
case Joystick::Down : return Joystick::Down;
case Joystick::Left : return Joystick::Left;
case Joystick::Right : return Joystick::Right;
case Joystick::Button1 : return Joystick::Button1;
case Joystick::Button2 : return Joystick::Button2;
case Joystick::Button3 : return Joystick::Button3;
case Joystick::Button4 : return Joystick::Button4;
case Joystick::Button5 : return Joystick::Button5;
case Joystick::Button6 : return Joystick::Button6;
case Joystick::Start : return Joystick::Start;
case Joystick::Quit : return Joystick::Quit;
}
return Joystick::Invalid;
}
*/
/*
Configuration::JoystickInput Configuration::getJoystickKey(int config, const string & name, JoystickInput defaultValue){
ostringstream path;
path << config_input << "/" << config << "/joystick/" << name;
return intToJoystick(getProperty(path.str(), defaultValue));
}
*/
int Configuration::getRight(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_RIGHT; break;
case 1: normal = Keyboard::Key_L; break;
}
return getKey(config, "right", normal);
}
int Configuration::getLeft(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_LEFT; break;
case 1: normal = Keyboard::Key_J; break;
}
return getKey(config, "left", normal);
}
int Configuration::getUp(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_UP; break;
case 1: normal = Keyboard::Key_I; break;
}
return getKey(config, "up", normal);
}
int Configuration::getDown(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_DOWN; break;
case 1: normal = Keyboard::Key_COMMA; break;
}
return getKey(config, "down", normal);
}
int Configuration::getAttack1(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_A; break;
case 1: normal = Keyboard::Key_R; break;
}
return getKey(config, "attack1", normal);
}
int Configuration::getAttack2(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_S; break;
case 1: normal = Keyboard::Key_T; break;
}
return getKey(config, "attack2", normal);
}
int Configuration::getAttack3(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_D; break;
case 1: normal = Keyboard::Key_Y; break;
}
return getKey(config, "attack3", normal);
}
int Configuration::getAttack4(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_Z; break;
case 1: normal = Keyboard::Key_F; break;
}
return getKey(config, "attack4", normal);
}
int Configuration::getAttack5(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_X; break;
case 1: normal = Keyboard::Key_G; break;
}
return getKey(config, "attack5", normal);
}
int Configuration::getAttack6(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_C; break;
case 1: normal = Keyboard::Key_H; break;
}
return getKey(config, "attack6", normal);
}
int Configuration::getJump(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_SPACE; break;
case 1: normal = Keyboard::Key_B; break;
}
return getKey(config, "jump", normal);
}
/*
void Configuration::setJoystickKey(int config, const std::string & name, const Configuration::JoystickInput & what){
if (what != Joystick::Invalid){
ostringstream path;
path << config_configuration << "/" << config_input << "/" << config << "/joystick/" << name;
updateToken(data.raw(), path.str(), what);
saveConfiguration();
}
}
void Configuration::setJoystickRight(int config, Configuration::JoystickInput i){
setJoystickKey(config, "right", i);
}
void Configuration::setJoystickLeft(int config, Configuration::JoystickInput i){
setJoystickKey(config, "left", i);
}
void Configuration::setJoystickUp(int config, Configuration::JoystickInput i){
setJoystickKey(config, "up", i);
}
void Configuration::setJoystickDown(int config, Configuration::JoystickInput i){
setJoystickKey(config, "down", i);
}
void Configuration::setJoystickAttack1(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack1", i);
}
void Configuration::setJoystickAttack2(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack2", i);
}
void Configuration::setJoystickAttack3(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack3", i);
}
void Configuration::setJoystickAttack4(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack4", i);
}
void Configuration::setJoystickAttack5(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack5", i);
}
void Configuration::setJoystickAttack6(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack6", i);
}
void Configuration::setJoystickJump(int config, Configuration::JoystickInput i){
setJoystickKey(config, "jump", i);
}
void Configuration::setJoystickQuit(int config, Configuration::JoystickInput i){
setJoystickKey(config, "quit", i);
}
void Configuration::setJoystickStart(int config, Configuration::JoystickInput i){
setJoystickKey(config, "start", i);
}
Configuration::JoystickInput Configuration::getJoystickRight(int config){
return getJoystickKey(config, "right", Joystick::Right);
}
Configuration::JoystickInput Configuration::getJoystickLeft(int config){
return getJoystickKey(config, "left", Joystick::Left);
}
Configuration::JoystickInput Configuration::getJoystickUp(int config){
return getJoystickKey(config, "up", Joystick::Up);
}
Configuration::JoystickInput Configuration::getJoystickDown(int config){
return getJoystickKey(config, "down", Joystick::Down);
}
Configuration::JoystickInput Configuration::getJoystickAttack1(int config){
return getJoystickKey(config, "attack1", Joystick::Button1);
}
Configuration::JoystickInput Configuration::getJoystickAttack2(int config){
return getJoystickKey(config, "attack2", Joystick::Button2);
}
Configuration::JoystickInput Configuration::getJoystickAttack3(int config){
return getJoystickKey(config, "attack3", Joystick::Button3);
}
Configuration::JoystickInput Configuration::getJoystickAttack4(int config){
return getJoystickKey(config, "attack4", Joystick::Button4);
}
Configuration::JoystickInput Configuration::getJoystickAttack5(int config){
return getJoystickKey(config, "attack5", Joystick::Button5);
}
Configuration::JoystickInput Configuration::getJoystickAttack6(int config){
return getJoystickKey(config, "attack6", Joystick::Button6);
}
Configuration::JoystickInput Configuration::getJoystickJump(int config){
return getJoystickKey(config, "jump", Joystick::Button4);
}
Configuration::JoystickInput Configuration::getJoystickQuit(int config){
return getJoystickKey(config, "quit", Joystick::Quit);
}
Configuration::JoystickInput Configuration::getJoystickStart(int config){
return getJoystickKey(config, "start", Joystick::Start);
}
*/
/*
string Configuration::getCurrentGame(){
return getProperty(config_current_game, string(""));
}
/ * assumes the directory is readable and has a dir/dir.txt in it * /
void Configuration::setCurrentGame(const std::string & str){
setProperty(config_current_game, str);
saveConfiguration();
}
*/
void Configuration::disableSave(){
save = false;
}
void Configuration::setSave(bool what){
save = what;
}
bool Configuration::getSave(){
return save;
}
static Token * removeDuplicates(Token * token){
/* TODO */
return token;
}
Token * Configuration::getRawData(){
if (data == NULL){
data = new Token();
}
return data.raw();
}
void Configuration::loadConfigurations(){
data = new Token();
*data << config_configuration;
try{
Filesystem::AbsolutePath file = Storage::instance().configFile();
TokenReader tr;
Token * head = tr.readTokenFromFile(file.path());
if (*head != config_configuration){
throw LoadException(__FILE__, __LINE__, string("Config file ") + Storage::instance().configFile().path() + " does not use the configuration format" );
}
/* Store the entire configuration tree */
data = removeDuplicates(head->copy());
} catch ( const LoadException & le ){
Global::debug( 0 ) << "Notice: Could not load configuration file " << Storage::instance().configFile().path() << ": " << le.getTrace() << endl;
} catch ( const TokenException & t ){
Global::debug( 0 ) << "Notice: could not open configuration file '" << Storage::instance().configFile().path() << "': " << t.getTrace() << endl;
}
}
void Configuration::saveConfiguration(){
if (!save){
return;
}
if (data != NULL){
ofstream out(Storage::instance().configFile().path().c_str(), ios::trunc | ios::out);
if (! out.bad()){
data->toString(out, string(""));
out << endl;
out.close();
}
}
}
Util::ReferenceCount<Menu::FontInfo> Configuration::menuFont;
bool Configuration::joystickEnabled = true;
int Configuration::getProperty(const std::string & path, int defaultValue){
return getPropertyX(getRawData(), path, defaultValue);
}
void Configuration::setProperty(const std::string & path, int value){
updateToken(getRawData(), string(config_configuration) + "/" + path, value);
saveConfiguration();
}
void Configuration::setProperty(const std::string & path, Token * value){
updateToken(getRawData(), string(config_configuration) + "/" + path, value);
saveConfiguration();
}
Token * Configuration::getProperty(const std::string & path){
return getPropertyX(getRawData(),path);
}
double Configuration::getProperty(const std::string & path, double defaultValue){
return getPropertyX(getRawData(), path, defaultValue);
}
void Configuration::setProperty(const std::string & path, double value){
updateToken(getRawData(), string(config_configuration) + "/" + path, value);
saveConfiguration();
}
bool Configuration::getProperty(const std::string & path, bool defaultValue){
return getPropertyX(getRawData(), path, defaultValue);
}
void Configuration::setProperty(const std::string & path, bool value){
updateToken(getRawData(), string(config_configuration) + "/" + path, value);
saveConfiguration();
}
std::string Configuration::getProperty(const std::string & path, const std::string & defaultValue){
return getPropertyX(getRawData(), path, defaultValue);
}
double Configuration::getGameSpeed(){
return getProperty(config_game_speed, 1.0);
}
void Configuration::setGameSpeed(double s){
setProperty(config_game_speed, s);
saveConfiguration();
}
bool Configuration::getInvincible(){
return getProperty(config_invincible, false);
}
void Configuration::setInvincible(bool i){
setProperty(config_invincible, i);
saveConfiguration();
}
bool Configuration::getFullscreen(){
/* Defaults for all configuration options */
#if defined(PS3) || defined(ANDROID) || defined(IPHONE)
return getProperty(config_fullscreen, true);
#else
return getProperty(config_fullscreen, false);
#endif
}
void Configuration::setFullscreen(bool f){
setProperty(config_fullscreen, f);
saveConfiguration();
}
int Configuration::getLives(){
return getProperty(config_lives, 4);
}
void Configuration::setLives(int l){
setProperty(config_lives, l);
saveConfiguration();
}
int Configuration::getNpcBuddies(){
return getProperty(config_npc_buddies, 1);
}
void Configuration::setNpcBuddies(int i){
setProperty(config_npc_buddies,i);
saveConfiguration();
}
Configuration::PlayMode Configuration::getPlayMode(){
string mode = getProperty("play-mode", string(config_cooperative));
if (mode == config_cooperative){
return Cooperative;
}
if (mode == config_free_for_all){
return FreeForAll;
}
return Cooperative;
}
void Configuration::setPlayMode(Configuration::PlayMode mode){
if (mode == Configuration::Cooperative){
setProperty("play-mode", string(config_cooperative));
} else if (mode == Configuration::FreeForAll){
setProperty("play-mode", string(config_free_for_all));
}
}
std::string Configuration::getLanguage(){
return getProperty("language", string());
}
void Configuration::setLanguage(const std::string & str){
setProperty("language", str);
saveConfiguration();
}
/* In case this is ever useful again */
/*
#ifdef MINPSPW
// default resolution for the psp is 480x272
int Configuration::screen_width = 480;
int Configuration::screen_height = 272;
#else
int Configuration::screen_width = 640;
int Configuration::screen_height = 480;
#endif
*/
#ifdef GCW0
static int DefaultWidth = 320;
static int DefaultHeight = 240;
#else
static int DefaultWidth = 640;
static int DefaultHeight = 480;
#endif
/* TODO: All the screen width/height stuff shares a lot of code. Refactor */
void Configuration::setScreenWidth(int i){
int width = DefaultWidth;
int height = DefaultHeight;
Token * screen = getPropertyX(getRawData(), config_screen_size);
if (screen != NULL){
try{
screen->view() >> width >> height;
} catch (const TokenException & fail){
}
}
width = i;
setProperty(config_screen_size, createToken(config_screen_size, width, height));
saveConfiguration();
}
int Configuration::getScreenWidth(){
int width = DefaultWidth;
int height = DefaultHeight;
Token * screen = getPropertyX(getRawData(), config_screen_size);
if (screen != NULL){
try{
screen->view() >> width >> height;
} catch (const TokenException & fail){
}
} else {
setProperty(config_screen_size, createToken(config_screen_size, width, height));
}
return width;
}
void Configuration::setScreenHeight(int i){
int width = DefaultWidth;
int height = DefaultHeight;
Token * screen = getPropertyX(getRawData(), config_screen_size);
if (screen != NULL){
try{
screen->view() >> width >> height;
} catch (const TokenException & fail){
}
}
height = i;
setProperty(config_screen_size, createToken(config_screen_size, width, height));
saveConfiguration();
}
int Configuration::getScreenHeight(){
int width = DefaultWidth;
int height = DefaultHeight;
Token * screen = getPropertyX(getRawData(), config_screen_size);
if (screen != NULL){
try{
screen->view() >> width >> height;
} catch (const TokenException & fail){
}
} else {
setProperty(config_screen_size, createToken(config_screen_size, width, height));
}
return height;
}
int Configuration::getSoundVolume(){
return getProperty(config_sound, 70);
}
void Configuration::setSoundVolume(int volume){
setProperty(config_sound, volume);
saveConfiguration();
}
int Configuration::getMusicVolume(){
return getProperty(config_music, 70);
}
void Configuration::setMusicVolume(int volume){
setProperty(config_music, volume);
saveConfiguration();
}
bool Configuration::isJoystickEnabled(){
return joystickEnabled;
}
void Configuration::setJoystickEnabled(bool enabled){
joystickEnabled = enabled;
saveConfiguration();
}
std::string Configuration::getQualityFilter(){
return getProperty(config_quality_filter, string("none"));
}
void Configuration::setQualityFilter(const std::string & filter){
setProperty(config_quality_filter, filter);
saveConfiguration();
}
int Configuration::getFps(){
return getProperty(config_fps, 50);
}
void Configuration::setFps(int what){
setProperty(config_fps, what);
saveConfiguration();
}
diff --git a/util/token.cpp b/util/token.cpp
index 5becd69e..9feff754 100644
--- a/util/token.cpp
+++ b/util/token.cpp
@@ -1,761 +1,768 @@
#include "token.h"
#include "token_exception.h"
#include <string>
#include <vector>
#include <ostream>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <string.h>
#include "debug.h"
using namespace std;
static bool needQuotes(const std::string & what){
+
+ /* if it begins with a " and ends with " then it doesnt need more quotes */
+ if (what.size() > 0 && what[0] == '"' && what[what.size() - 1] == '"'){
+ return false;
+ }
+
/* ripped from tokenreader.cpp, maybe use a variable for nice sharing.. */
const char * alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./-_!:";
for (unsigned int position = 0; position < what.size(); position++){
if (strchr(alpha, what[position]) == NULL){
return true;
}
/*
if (what[position] == '"' ||
what[position] == ' ' ||
(unsigned char) what[position] > 127){
return true;
}
*/
}
return false;
}
/* put quotes around a string if there are spaces in it */
static string quoteify(const string & rhs){
if (needQuotes(rhs)){
return string("\"") + rhs + string("\"");
}
return rhs;
}
Token::Token():
num_token(1),
parent( NULL ),
own(true){
name = "HEAD";
}
Token::Token(string tok, bool parse):
num_token( 1 ),
parent( NULL ),
own(true){
/* legacy code, not used much */
if (!parse){
name = tok;
while (name.find(' ') == 0){
name.erase(0, 1);
}
/*
if (name.find(' ') != string::npos){
name = string("\"") + name + string("\"");
}
*/
}
}
Token::Token(Token const & copy):
num_token(1),
parent(copy.parent),
own(false){
this->tokens = copy.tokens;
this->name = copy.name;
this->filename = copy.filename;
}
/* Dump token to the screen */
void Token::print( const string space ) const {
Global::debug(0) <<space<<"Token: "<< getName() << endl;
for ( signed int i = 0; i < numTokens(); i++ ){
Token * x = getToken( i );
x->print( space + " |--" );
}
}
void Token::toStringCompact(ostream & stream) const {
if (numTokens() == -1){
- stream << getName();
+ stream << quoteify(getName());
} else {
- stream << "(" << getName();
+ stream << "(" << quoteify(getName());
for (signed int i = 0; i < numTokens(); i++){
Token * x = getToken(i);
stream << " ";
x->toStringCompact(stream);
}
stream << ")";
}
}
void Token::toString(ostream & stream, const string & space) const {
if (numTokens() == -1){
- stream << getName();
+ stream << quoteify(getName());
} else {
stream << endl;
- stream << space << "(" << getName();
+ stream << space << "(" << quoteify(getName());
for ( signed int i = 0; i < numTokens(); i++ ){
Token * x = getToken(i);
stream << " ";
x->toString( stream, space + " " );
}
stream << ")";
}
}
std::string Token::toString() const {
std::ostringstream out;
toString(out, "");
return out.str();
}
std::string Token::toStringCompact() const {
std::ostringstream out;
toStringCompact(out);
return out.str();
}
/* helper function */
string Token::lowerCase( const string & s ) const {
string ret = s;
for ( unsigned int q = 0; q < s.length(); q++ ){
if ( s[q] >= 'A' && s[q] <= 'Z' ){
ret[q] = s[q] - 'A' + 'a';
} else {
// ret[q] = s[q];
}
}
return ret;
}
/* Return next token and increment the internal position
* of the current token
*/
Token * Token::readToken(){
if ( num_token < tokens.size() ){
return tokens[ num_token++ ];
}
return NULL;
}
bool Token::hasTokens() const {
return num_token < tokens.size();
}
/*
vector<Token*> Token::findTokens(const string & path){
vector<Token*> whoba;
cout << "whoba has " << whoba.size() << endl;
whoba.push_back(this);
if (whoba[0] != this){
cout << "complete failure!!!" << endl;
}
int x = 2;
x = x + 12;
return whoba;
}
*/
vector<const Token *> Token::findTokens(const string & path) const {
vector<const Token *> found;
if (path == ""){
return found;
}
size_t find = path.find('/');
string self;
if (find == string::npos){
self = path;
} else {
self = path.substr(0, find);
}
/* a name of `_' means succeed with the current token no matter
* what its called.
* `*' means test all children. this is useful if you dont know where in the
* tree a given node lives.
* (... (... (... (foo ...))))
* *\foo would find the foo token (I used backslash because forward slash will
* kill the current c++ comment)
*/
if (self == "*"){
/* `*' and 'blah/stuff', test the current token for 'blah/stuff' */
string rest = path.substr(find+1);
vector<const Token*> more = findTokens(rest);
found.insert(found.end(), more.begin(), more.end());
/* then test all children for the original path */
for (int i = 0; i < numTokens(); i++){
Token * next = getToken(i);
if (next != NULL){
vector<const Token *> more = next->findTokens(path);
found.insert(found.end(), more.begin(), more.end());
}
}
} else if (self == "_" || *this == self){
if (find == string::npos){
found.push_back(this);
if (found[0] != this){
Global::debug(0) << "internal consistency error!!!!" << endl;
throw exception();
}
} else {
string rest = path.substr(find+1);
for (int i = 0; i < numTokens(); i++){
Token * next = getToken(i);
if (next != NULL){
vector<const Token *> more = next->findTokens(rest);
found.insert(found.end(), more.begin(), more.end());
}
}
}
}
return found;
}
TokenMatcher Token::getMatcher(const std::string & subject) const {
TokenMatcher matcher(findTokens(subject));
return matcher;
}
Token * Token::findToken(const string & path){
vector<const Token *> all = findTokens(path);
if (all.size() == 0){
return NULL;
}
return (Token*) all[0];
}
const Token * Token::findToken(const string & path) const {
vector<const Token *> all = findTokens(path);
if (all.size() == 0){
return NULL;
}
return all[0];
}
/*
Token * Token::findToken(const string & path){
if (path == ""){
return NULL;
}
size_t find = path.find('/');
string self;
if (find == string::npos){
self = path;
} else {
self = path.substr(0, find);
}
if (*this == self){
if (find == string::npos){
return this;
} else {
for (int i = 0; i < numTokens(); i++){
Token * next = getToken(i);
if (next != NULL){
Token * ok = next->findToken(path.substr(find+1));
if (ok != NULL){
return ok;
}
}
}
}
}
return NULL;
}
*/
Token * Token::getToken( unsigned int n ) const {
int q = numTokens();
if ( q == -1 ) return NULL;
if ( (signed int)n < q )
return tokens[n+1];
return NULL;
}
/* If the token has children then the name of this token
* is the name of the first child token.
* Otherwise, the name is this token's name
*/
const string & Token::getName() const {
if ( numTokens() != -1 ){
return tokens[0]->_getName();
}
// cout<<"No tokens!!"<<endl;
return name;
}
const Token * Token::getParent() const {
return this->parent;
}
Token * Token::getParent(){
return parent;
}
const Token * Token::getRootParent() const {
if (getParent() != NULL){
return getParent()->getRootParent();
}
return this;
}
const string Token::getLineage() const {
if (getParent() != NULL){
return getParent()->getLineage() + " -> " + getName();
}
return getName();
}
/* A token's identity is its name
*/
bool Token::operator== (const string & rhs) const {
return lowerCase(getName()) == lowerCase(rhs);
}
bool Token::operator!=(const string & rhs) const {
return !(*this == rhs);
}
void Token::setFile(const string & s){
filename = s;
}
void Token::removeToken(Token * token){
for (vector<Token*>::iterator it = tokens.begin(); it != tokens.end(); it++){
Token * what = *it;
if (token == what){
/* Found the token. If we own it then delete it, otherwise just
* remove it from the list and return.
*/
if (own){
delete what;
}
it = tokens.erase(it);
return;
}
}
}
const string Token::getFileName() const {
if (parent){
return parent->getFileName();
} else {
return filename;
}
}
/*
Token & Token::operator>>( Token * & rhs ) throw( TokenException ){
Token * x = readToken();
if ( x == NULL ){
throw TokenException(__FILE__, __LINE__, getFileName() + ": " + string("Tried to read a token from ") + this->getName() + string(" but there are no more elements") );
}
rhs = x;
return *this;
}
Token & Token::operator>>( string & rhs ) throw( TokenException ){
Token * token = readToken();
if (token == NULL){
throw TokenException(__FILE__, __LINE__, getFileName() + ":" + string("Tried to read a string from '") + this->getLineage() + string("' but there no more elements") );
}
if (!token->isData()){
ostringstream out;
out << getFileName() << ": Element is not a string '";
token->toString(out, "");
// throw TokenException(__FILE__, __LINE__, getFileName() + ":" + string(" Element is not a string: "));
throw TokenException(__FILE__, __LINE__, out.str());
}
rhs = token->getName();
// rhs = getName();
return *this;
}
Token & Token::operator>>( int & rhs ) throw( TokenException ){
Token * l = readToken();
if ( l == NULL ){
throw TokenException(__FILE__, __LINE__, getFileName() + ": " + string("Tried to read an int from ") + this->getLineage() + string(" but there are no more elements") );
}
if (!l->isData()){
throw TokenException(__FILE__, __LINE__, getFileName() + ":" + string(" Element is not a string"));
}
istringstream is ( l->getName() );
is >> rhs;
return *this;
}
Token & Token::operator>>( double & rhs ) throw( TokenException ){
Token * l = readToken();
if ( l == NULL ){
throw TokenException(__FILE__, __LINE__, getFileName() + ": " + string("Tried to read a double from ") + this->getLineage() + string(" but there no more elements") );
}
if (!l->isData()){
throw TokenException(__FILE__, __LINE__, getFileName() + ":" + string(" Element is not a string"));
}
istringstream is ( l->getName() );
is >> rhs;
return *this;
}
Token & Token::operator>>( bool & rhs ) throw( TokenException ){
Token * l = readToken();
if ( l == NULL ){
throw TokenException(__FILE__, __LINE__, getFileName() + ": " + string("Tried to read a bool from ") + this->getLineage() + string(" but there no more elements") );
}
if (!l->isData()){
throw TokenException(__FILE__, __LINE__, getFileName() + ":" + string(" Element is not a string"));
}
istringstream is ( l->getName() );
is >> rhs;
return *this;
}
*/
void Token::addToken(Token * t){
/*
if (!own){
throw TokenException(__FILE__, __LINE__, "This token does not own its own tokens, so you cannot add tokens to it");
}
*/
t->setParent(this);
tokens.push_back(t);
}
Token * Token::newToken(){
Token * token = new Token();
addToken(token);
return token;
}
TokenView Token::view() const {
vector<const Token*> out;
out.insert(out.end(), tokens.begin(), tokens.end());
return TokenView(out);
}
Token & Token::operator<<(Token * token){
if (!own){
throw TokenException(__FILE__, __LINE__, "Cannot add tokens to a token you don't own");
}
this->addToken(token);
return *this;
}
Token & Token::operator<<( const string rhs ){
if (!own){
throw TokenException(__FILE__, __LINE__, "Cannot add raw strings to a token you don't own");
}
- Token * n = new Token(quoteify(rhs), false);
+ // Token * n = new Token(quoteify(rhs), false);
+ Token * n = new Token(rhs, false);
this->addToken(n);
return *this;
}
Token & Token::operator<<( const int rhs ){
if (!own){
throw TokenException(__FILE__, __LINE__, "Cannot add raw integers to a token you don't own");
}
ostringstream o;
o << rhs;
return *this << o.str();
}
Token & Token::operator<<(const unsigned int rhs){
if (!own){
throw TokenException(__FILE__, __LINE__, "Cannot add raw integers to a token you don't own");
}
ostringstream o;
o << rhs;
return *this << o.str();
}
Token & Token::operator<<(const uint64_t rhs){
if (!own){
throw TokenException(__FILE__, __LINE__, "Cannot add raw integers to a token you don't own");
}
ostringstream o;
o << rhs;
return *this << o.str();
}
Token & Token::operator<<( const double rhs ){
if (!own){
throw TokenException(__FILE__, __LINE__, "Cannot add raw doubles to a token you don't own");
}
ostringstream o;
o << setprecision(6) << fixed << rhs;
return *this << o.str();
}
Token * Token::copy() const {
Token * token = new Token();
token->filename = this->filename;
token->name = this->name;
for (vector<Token *>::const_iterator it = this->tokens.begin(); it != this->tokens.end(); it++){
Token * him = (*it)->copy();
him->setParent(token);
token->addToken(him);
}
return token;
}
/* Delete tokens that are commented.
* A commented token has a '!' character as the first
* character in the name, e.g:
* (!a_token (child_token 2))
*/
/*
void Token::finalize(){
for ( vector< Token * >::iterator it = tokens.begin(); it != tokens.end(); ){
Token * t = *it;
if ( t->getName().find('!') == 0 ){
delete t;
it = tokens.erase( it );
} else {
t->finalize();
it++;
}
}
}
*/
Token::~Token(){
if (own){
for (vector<Token * >::iterator it = tokens.begin(); it != tokens.end(); it++){
delete *it;
}
}
}
TokenMatcher::TokenMatcher(){
throw TokenException(__FILE__, __LINE__, "Cannot instantiate a token matcher");
}
TokenMatcher & TokenMatcher::operator=(const TokenMatcher & matcher){
tokens = matcher.tokens;
current = tokens.begin();
return *this;
}
TokenMatcher::TokenMatcher(std::vector<const Token*> tokens):
tokens(tokens){
current = this->tokens.begin();
}
TokenView::TokenView(std::vector<const Token *> tokens):
tokens(tokens){
current = this->tokens.begin();
if (current != this->tokens.end()){
current++;
}
}
TokenView::TokenView(const TokenView & view):
tokens(view.tokens){
current = this->tokens.begin();
if (current != this->tokens.end()){
current++;
}
}
bool TokenView::hasMore() const {
return current != tokens.end();
}
TokenView & TokenView::operator=(const TokenView & view){
tokens = view.tokens;
current = tokens.begin();
if (current != tokens.end()){
current++;
}
return *this;
}
TokenView & TokenView::operator>>(string & item){
if (current == tokens.end()){
throw TokenException(__FILE__, __LINE__, "No more elements");
}
const Token * child = *current;
if (!child->isData()){
throw TokenException(__FILE__, __LINE__, "Token is not a datum");
}
item = child->getName();
current++;
return *this;
}
TokenView & TokenView::operator>>(int & item){
if (current == tokens.end()){
throw TokenException(__FILE__, __LINE__, "No more elements");
}
const Token * child = *current;
if (!child->isData()){
throw TokenException(__FILE__, __LINE__, "Token is not a datum");
}
istringstream out(child->getName());
out >> item;
current++;
return *this;
}
TokenView & TokenView::operator>>(unsigned char & item){
if (current == tokens.end()){
throw TokenException(__FILE__, __LINE__, "No more elements");
}
const Token * child = *current;
if (!child->isData()){
throw TokenException(__FILE__, __LINE__, "Token is not a datum");
}
istringstream out(child->getName());
out >> item;
current++;
return *this;
}
TokenView & TokenView::operator>>(uint64_t & item){
if (current == tokens.end()){
throw TokenException(__FILE__, __LINE__, "No more elements");
}
const Token * child = *current;
if (!child->isData()){
throw TokenException(__FILE__, __LINE__, "Token is not a datum");
}
istringstream out(child->getName());
out >> item;
current++;
return *this;
}
TokenView & TokenView::operator>>(unsigned int & item){
if (current == tokens.end()){
throw TokenException(__FILE__, __LINE__, "No more elements");
}
const Token * child = *current;
if (!child->isData()){
throw TokenException(__FILE__, __LINE__, "Token is not a datum");
}
istringstream out(child->getName());
out >> item;
current++;
return *this;
}
TokenView & TokenView::operator>>(double & item){
if (current == tokens.end()){
throw TokenException(__FILE__, __LINE__, "No more elements");
}
const Token * child = *current;
if (!child->isData()){
throw TokenException(__FILE__, __LINE__, "Token is not a datum");
}
istringstream out(child->getName());
out >> item;
current++;
return *this;
}
static bool isTrue(const string & name){
return name == "true" ||
name == "1" ||
name == "on" ||
name == "enable";
}
static bool isFalse(const string & name){
return name == "false" ||
name == "0" ||
name == "off" ||
name == "disable";
}
TokenView & TokenView::operator>>(bool & item){
if (current == tokens.end()){
throw TokenException(__FILE__, __LINE__, "No more elements");
}
const Token * child = *current;
if (!child->isData()){
throw TokenException(__FILE__, __LINE__, "Token is not a datum");
}
string what = child->getName();
if (isTrue(what)){
item = true;
} else if (isFalse(what)){
item = false;
} else {
ostringstream fail;
fail << "Not a true/false value: " << what << ". True values are 'true', '1', 'on', 'enable'. False values are 'false', 0', 'off', 'disable'";
throw TokenException(__FILE__, __LINE__, fail.str());
}
current++;
return *this;
}
TokenView & TokenView::operator>>(const Token* & item){
if (current == tokens.end()){
throw TokenException(__FILE__, __LINE__, "No more elements");
}
const Token * child = *current;
/*
if (!child->isData()){
throw TokenException(__FILE__, __LINE__, "Token is not a datum");
}
*/
item = child;
current++;
return *this;
}
const Token * TokenView::next(){
if (current == tokens.end()){
throw TokenException(__FILE__, __LINE__, "No more elements");
}
const Token * child = *current;
current++;
return child;
}
TokenException::TokenException(const std::string & file, int line, const std::string reason):
Exception::Base(file, line),
reason(reason){
}
TokenException::TokenException(const TokenException & copy):
Exception::Base(copy),
reason(copy.reason){
}
TokenException::TokenException(const Exception::Base & copy):
Exception::Base(copy),
reason("unknown"){
}
Exception::Base * TokenException::copy() const {
return new TokenException(*this);
}
TokenException::~TokenException() throw() {
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jun 16, 12:55 AM (2 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
71383
Default Alt Text
(50 KB)

Event Timeline