Skip to content

Commit 8e3de3d

Browse files
committed
Merge pull request #41 from Databean/softConfig
Soft config
2 parents 4194963 + 80001db commit 8e3de3d

File tree

9 files changed

+354
-42
lines changed

9 files changed

+354
-42
lines changed

include/Config.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#ifndef CONFIG_H
2+
#define CONFIG_H
3+
4+
#include <map>
5+
#include <string>
6+
#include <utility>
7+
#include <fstream>
8+
9+
#include "Util.h"
10+
11+
/**
12+
* A configuration value stored in a configuration file.
13+
* These can auto-convert to several common types that are used.
14+
*/
15+
class ConfigValue {
16+
private:
17+
std::string value;
18+
public:
19+
ConfigValue(const std::string& val);
20+
ConfigValue(const ConfigValue&) = default;
21+
ConfigValue(ConfigValue&&) = default;
22+
~ConfigValue() = default;
23+
ConfigValue& operator=(const ConfigValue&) = default;
24+
ConfigValue& operator=(ConfigValue&&) = default;
25+
26+
operator float() const;
27+
operator std::string() const;
28+
operator Coordinate() const;
29+
operator ScreenCoordinate() const;
30+
};
31+
32+
/**
33+
* Configuration storage. Reads in configuration files in the format:
34+
*
35+
* #Comment
36+
* name=value
37+
*
38+
* Particular configuration values can be accessed by name and automatically to convert to common types.
39+
*/
40+
class Config {
41+
private:
42+
std::map<std::string, ConfigValue> values;
43+
44+
void init(std::istream& in);
45+
public:
46+
Config(std::istream& source);
47+
Config(std::fstream&& source);
48+
Config(const std::string& filename);
49+
Config(const Config&) = default;
50+
Config(Config&&) = default;
51+
~Config() = default;
52+
Config& operator=(const Config&) = default;
53+
Config& operator=(Config&&) = default;
54+
55+
const ConfigValue& operator[](const std::string& name) const;
56+
};
57+
58+
const Config& getConfigFile(const std::string& filename);
59+
const Config& getGraphicsConfig();
60+
61+
#endif

resources/graphics.conf

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Font settings
2+
font.path=resources/ComicNeue-Bold.ttf
3+
font.size=50
4+
5+
# General window settings
6+
screen.width=900
7+
screen.height=800
8+
9+
# Trading view screen coordinates
10+
screen.tradingView.bottomLeft=(0.1,0.1)
11+
screen.tradingView.topRight=(0.9,0.9)
12+
13+
screen.tradingView.tradeButton.bottomLeft=(0.7,0.1)
14+
screen.tradingView.tradeButton.topRight=(0.9,0.2)
15+
16+
screen.tradingView.cancelButton.bottomLeft=(0.1,0.1)
17+
screen.tradingView.cancelButton.topRight=(0.3,0.2)
18+
19+
screen.tradingView.resources.height=0.13
20+
screen.tradingView.resources.leftX=0.3
21+
screen.tradingView.resources.rightX=0.6
22+
screen.tradingView.resources.bottomY=0.2
23+
24+
screen.tradingView.players.bottomLeft=(0.1,0.8)
25+
screen.tradingView.players.topRight=(0.9,0.9)

src/Config.cpp

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#include "Config.h"
2+
3+
#include <sstream>
4+
#include <stdexcept>
5+
6+
#include "Util.h"
7+
8+
using std::string;
9+
using std::stringstream;
10+
using std::runtime_error;
11+
using std::istream;
12+
using std::fstream;
13+
14+
/**
15+
* Initialize a ConfigValue with the raw string it represents.
16+
* @param value The raw value.
17+
*/
18+
ConfigValue::ConfigValue(const string& value) : value(value) {
19+
20+
}
21+
22+
/**
23+
* Convert the ConfigValue into a float.
24+
* @return The text of the ConfigValue, interpreted as a float.
25+
*/
26+
ConfigValue::operator float() const {
27+
return fromString<float>(value);
28+
}
29+
30+
/**
31+
* Convert the ConfigValue into a string.
32+
* @return The text of the ConfigValue.
33+
*/
34+
ConfigValue::operator string() const {
35+
return value;
36+
}
37+
38+
/**
39+
* Convert the ConfigValue into a game Coordinate.
40+
* @throws runtime_error If the value cannot be converted.
41+
* @return The text of the ConfigValue, interpreted as a game Coordinate.
42+
*/
43+
ConfigValue::operator Coordinate() const {
44+
stringstream stream(value);
45+
Coordinate ret;
46+
char c = stream.get();
47+
if(c != '(') {
48+
throw runtime_error("Attempt to read a coordinate out of a non-coordinate value");
49+
}
50+
stream >> ret.first;
51+
c = stream.get();
52+
if(c != ',') {
53+
throw runtime_error("Attempt to read a coordinate out of a non-coordinate value");
54+
}
55+
stream >> ret.second;
56+
return ret;
57+
}
58+
59+
/**
60+
* Convert the ConfigValue into a ScreenCoordinate.
61+
* @throws runtime_error If the value cannot be converted.
62+
* @return The text of the ConfigValue, interpreted as a ScreenCoordinate.
63+
*/
64+
ConfigValue::operator ScreenCoordinate() const {
65+
stringstream stream(value);
66+
ScreenCoordinate ret;
67+
char c = stream.get();
68+
if(c != '(') {
69+
throw runtime_error("Attempt to read a coordinate out of a non-coordinate value");
70+
}
71+
stream >> ret.first;
72+
c = stream.get();
73+
if(c != ',') {
74+
throw runtime_error("Attempt to read a coordinate out of a non-coordinate value");
75+
}
76+
stream >> ret.second;
77+
return ret;
78+
}
79+
80+
/**
81+
* Initialize a Config file, reading from an input stream.
82+
* @param source The stream to read config values from.
83+
*/
84+
Config::Config(istream& source) {
85+
init(source);
86+
}
87+
88+
/**
89+
* Initialize a Config file, reading from a file stream.
90+
* @param source The file stream to read config values from.
91+
*/
92+
Config::Config(fstream&& source) {
93+
init(source);
94+
}
95+
96+
/**
97+
* Initialize a Config file, reading from a given file.
98+
* @param filename The path to the file to read.
99+
*/
100+
Config::Config(const string& filename) {
101+
fstream source(filename, fstream::in);
102+
init(source);
103+
}
104+
105+
/**
106+
* Read in configuration values from a stream.
107+
* @param source The place to read configuration values from.
108+
*/
109+
void Config::init(istream& source) {
110+
string line;
111+
while(source) {
112+
std::getline(source, line);
113+
if(line[0] == '#' || line.find('=') == string::npos) {
114+
continue;
115+
}
116+
string name = line.substr(0, line.find('='));
117+
string value = line.substr(line.find('=') + 1);
118+
values.insert(std::make_pair(name, ConfigValue(value)));
119+
}
120+
}
121+
122+
/**
123+
* Retrieve a configuration value.
124+
* @throws runtime_error If no configuration value with that name exists.
125+
* @param name The name to retrieve from the configuration file.
126+
* @return The configuration value stored at the given name.
127+
*/
128+
const ConfigValue& Config::operator[](const string& name) const {
129+
auto it = values.find(name);
130+
if(it == values.end()) {
131+
throw runtime_error("No such key in the config");
132+
} else {
133+
return it->second;
134+
}
135+
}
136+
137+
/**
138+
* Load a configuration file at a given path.
139+
* These configuration files are cached, and only will be loaded once.
140+
* @throws runtime_error If the file cannot be loaded.
141+
* @param filename The path to the file to read in.
142+
* @return The configuration stored at the file.
143+
*/
144+
const Config& getConfigFile(const std::string& filename) {
145+
static std::map<std::string, Config> configs;
146+
147+
auto it = configs.find(filename);
148+
if(it == configs.end()) {
149+
fstream file(filename);
150+
if(!file) {
151+
throw runtime_error("Cannot open file " + filename);
152+
}
153+
return configs.insert(std::make_pair(filename, Config(file))).first->second;
154+
} else {
155+
return it->second;
156+
}
157+
}
158+
159+
/**
160+
* Load the graphics configuration file.
161+
* @throws runtime_error If the graphics configuration file is missing.
162+
* @return The graphics configuration.
163+
*/
164+
const Config& getGraphicsConfig() {
165+
return getConfigFile("resources/graphics.conf");
166+
}

src/GameController.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <functional>
55
#include <memory>
66

7+
#include "Config.h"
78
#include "GameBoard.h"
89
#include "GameView.h"
910
#include "Renderer.h"
@@ -22,11 +23,10 @@ GameController::GameController(GameBoard& model, GameView& view) : model(model),
2223
view.addElement(makeViewButtonColor(std::bind(&GameController::nextTurn, this, _1), {{0, 0.2}, {0.1, 0.3}}, std::make_tuple(0.f, 0.f, 1.f)));
2324
view.addElement(makeViewButtonColor(std::bind(&GameController::handleRoadButtonEvent, this, _1), {{0, 0}, {0.1, 0.1}}, std::make_tuple(1.f, 0.f, 0.f)));
2425
view.addElement(makeViewButtonColor(std::bind(&GameController::handleSettlementButtonEvent, this, _1), {{0, 0.1}, {0.1, 0.2}}, std::make_tuple(0.f, 1.0f, 0.f)));
25-
26-
auto font = "resources/ComicNeue-Bold.ttf";
27-
auto fontSize = 50;
2826

29-
27+
auto font = getGraphicsConfig()["font.path"];
28+
auto fontSize = getGraphicsConfig()["font.size"];
29+
3030
auto playerTopY = 0.9;
3131
for(auto i = 0; i < model.getNoOfPlayers(); i++) {
3232
auto width = 0.15;
@@ -35,11 +35,8 @@ GameController::GameController(GameBoard& model, GameView& view) : model(model),
3535
playerTopY -= 0.05;
3636
}
3737

38-
39-
40-
4138
view.addElement(makeViewButtonColor(std::bind(&GameController::handleCancelButtonEvent, this, _1), {{.95, .95}, {1.0, 1.0}}, std::make_tuple(1.f, 0.0f, 0.f)));
42-
39+
4340
view.addElement(makeViewButtonText(std::bind(&GameController::handleRoadCardButtonEvent, this, _1), {{0.85, 0.0}, {0.97, 0.05}}, font, fontSize, "Road Building "));
4441
view.addElement(makeViewButtonText(std::bind(&GameController::handleKnightCardButtonEvent, this, _1), {{0.85, 0.05}, {0.97, 0.10}}, font, fontSize, "Knight "));
4542
view.addElement(makeViewButtonText(std::bind(&GameController::handleYearOfPlentyCardButtonEvent, this, _1), {{0.85, 0.10}, {0.97, 0.15}}, font, fontSize, "Year of Plenty "));

0 commit comments

Comments
 (0)