19 str.erase(0, str.find_first_not_of(
' '));
24 for (
char c: {
'\'',
'"'}) {
25 if (val[0] == c && val[val.size() - 1] == c) {
26 val.erase(val.begin());
34 for(
const auto& ite : internalValues){
35 cerr << ite.first <<
" -> " << ite.second << endl;
44 if(!file.is_open())
throw config_error(
"Error while opening config.yml. Check file location ?");
46 vector<string> keyParts;
53 auto match = line.find(
'#');
54 if (match != string::npos)line.erase(match);
55 if (line.find_first_not_of(
' ')==string::npos)
continue;
57 unsigned currentIndent = 0;
58 while (line[currentIndent] ==
' ')++currentIndent;
60 if(line[currentIndent]==
'-'){
61 string value = line.substr(currentIndent+1);
65 for (
unsigned i = 0; i < currentIndent; ++i) {
66 fullKey.append(keyParts[i]);
70 fullKey.append(to_string((listIndex)));
72 internalValues[fullKey] = value;
75 match = line.find(
':');
76 if (match == string::npos)
throw config_error(
"Line "+ to_string(lineno)+
" invalid : |"+line+
"|");
77 string key = line.substr(0, match);
78 string value = line.substr(match + 1);
82 keyParts.resize(currentIndent);
83 keyParts.push_back(key);
87 for (
unsigned i = 0; i < currentIndent; ++i) {
88 fullKey.append(keyParts[i]);
92 internalValues[fullKey] = value;
100void ConfigBuilder::readGrid(
const configKey& baseKey) {
102 getList(
"grid", tmp);
106 unsigned maxSize = 0;
107 for(
string& s : tmp){
108 if(s.size()>maxSize)maxSize = s.size();
112 for(
string& s : tmp){
114 for(;i<s.size();++i){
115 switch(toupper(s[i])){
133 throw config_error(
"Invalid invader ID in grid definition : "+ to_string(s[i]));
145 getColor(baseKey+
".color", pdef.
color);
146 pdef.
keys.
left = getChar(baseKey+
".keys.left");
147 pdef.
keys.
right = getChar(baseKey+
".keys.right");
148 pdef.
keys.
shoot = getChar(baseKey+
".keys.shoot");
152 invDef.
points = getInt(baseKey+
".points");
153 getColor(baseKey+
".color", invDef.
color);
210const string& ConfigBuilder::getString(
const configKey& key,
const string& def)
const {
212 return getString(key);
214 cerr << e.what() <<
" . Using default value" << endl;
219const string& ConfigBuilder::getString(
const configKey& key)
const {
221 if(internalValues.contains(key)){
223 DEBUG_MSG(
"Got config value " << internalValues.at(key))
224 return internalValues.at(key);
226 throw config_error(
"Non-existent key requested : "+key);
230int ConfigBuilder::getInt(
const configKey& key,
int def,
int min,
int max)
const {
232 int val = getInt(key);
233 if(val < min || val > max){
234 throw config_error(
"Value for key " + key +
" do not follow preconditions : " +
235 to_string(min) +
"<=" + to_string(val) +
"<=" + to_string(max));
239 cerr << e.what() <<
" . Using default value" << endl;
244int ConfigBuilder::getInt(
const configKey& key)
const {
246 return stoi(getString(key));
247 }
catch(invalid_argument& e){
248 throw config_error(
"Invalid int data for key "+key+
" : |"+getString(key)+
"|");
252char ConfigBuilder::getChar(
const configKey& key,
char def)
const {
256 cerr << e.what() <<
" . Using default value" << endl;
261char ConfigBuilder::getChar(
const configKey& key)
const {
262 string s = getString(key);
263 if(s.size()!=1)
throw config_error(
"Invalid char data for key "+key+
" : |"+s+
"|");
267void ConfigBuilder::getColor(
const configKey& key, nsGraphics::RGBAcolor& color,
const nsGraphics::RGBAcolor& def)
const {
269 getColor(key, color);
271 cerr << e.what() <<
" . Using default value" << endl;
276void ConfigBuilder::getColor(
const configKey& key, nsGraphics::RGBAcolor& color)
const {
278 string colorStr = getString(key);
279 if (colorStr ==
"black")color = nsGraphics::KBlack;
280 else if (colorStr ==
"white")color = nsGraphics::KWhite;
281 else if (colorStr ==
"red")color = nsGraphics::KRed;
282 else if (colorStr ==
"lime")color = nsGraphics::KLime;
283 else if (colorStr ==
"blue")color = nsGraphics::KBlue;
284 else if (colorStr ==
"yellow")color = nsGraphics::KYellow;
285 else if (colorStr ==
"cyan")color = nsGraphics::KCyan;
286 else if (colorStr ==
"magenta")color = nsGraphics::KMagenta;
287 else if (colorStr ==
"silver")color = nsGraphics::KSilver;
288 else if (colorStr ==
"gray")color = nsGraphics::KGray;
289 else if (colorStr ==
"maroon")color = nsGraphics::KMaroon;
290 else if (colorStr ==
"olive")color = nsGraphics::KOlive;
291 else if (colorStr ==
"green")color = nsGraphics::KGreen;
292 else if (colorStr ==
"purple")color = nsGraphics::KPurple;
293 else if (colorStr ==
"teal")color = nsGraphics::KTeal;
294 else if (colorStr ==
"navy")color = nsGraphics::KNavy;
295 else throw config_error(
"Invalid color string : "+colorStr);
298void ConfigBuilder::getList(
const configKey& baseKey, vector<string>& toPopulate)
const {
300 string fullKey = baseKey +
".0";
301 if(!internalValues.contains(fullKey))
throw config_error(
"Non-existent list baseKey requested : " + baseKey);
304 toPopulate.push_back(internalValues.at(fullKey));
306 fullKey = baseKey +
"." + to_string(i);
307 }
while(internalValues.contains(baseKey +
"." + to_string(i)));
312 map<string, string> strValues;
320 if(parsed)cerr <<
"An error occured while reading the configuration :" << endl;
321 else cerr <<
"An error occured while parsing the configuration :" << endl;
322 cerr << e.what() << endl;
324 cerr <<
"Parsed keys :" << endl;
327 cerr <<
"(The old configuration was kept in memory)" << endl;
temporary class used to populate a ConfigData object
void parseFile(const string &fname)
parse the file given, and put the keys/values in internalValues
ConfigData collectedData
Actual config data object.
void dumpInternalValues() const
print internalValues pairs in the console (in case in error reporting)
bool reloadConfig()
reload the configuration file (not dynamically used currently, but it was planned to be)
Simple clone of runtime_error to help us handle errors in config management.
void trimSpaces(string &str)
void sanitizeValue(string &val)
full game logic and display management
unsigned startXPosition
players horizontal start position
unsigned playersLives
player life points
unsigned invadersFireCooldown
wait time between two invader missile
unsigned playersSpeed
player movement speed
InvadersGrid grid
Invader type matrix.
string theme
theme to use. Valid values : good,bad
unsigned missilesWidth
invaders missiles width in pixel
unsigned torpedosLength
virtual value : players torpedos length in pixel - auto defined from width
unsigned playersFireCooldown
player shooting wait time
nsGraphics::RGBAcolor torpedosColor
players torpedos color
vector< PlayerDef > playerDefs
players configuration
unsigned torpedosSpeed
players topedos movement speed
unsigned invadersDistance
distance in pixel between two invader
nsGraphics::RGBAcolor missilesColor
invaders missiles color
unsigned invadersSpeed
invader movement speed
unsigned playersWidth
player horizontal size in pixel
unsigned invadersSize
invader radius size in pixel
unsigned maxFPS
maximum framerate at which the game will run
unsigned missilesSpeed
invaders missiles movement speed
unsigned missilesLength
virtual value : invaders missiles length in pixel - auto defined from width
unsigned torpedosWidth
players torpedos width in pixel
map< InvaderType, InvaderTypeDef > invadersDef
link between an invader type, and its data
unsigned points
points given to the player by defeating this invader type
nsGraphics::RGBAcolor color
color of the invader type
player data, contains colors and key configuration
PlayerKeys keys
player key configuration
nsGraphics::RGBAcolor color
player color
char left
key to move left
char right
key to move right
#define PROJ_LENGTH_FACTOR