Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/nall/config.hpp
2 views
1
#ifndef NALL_CONFIG_HPP
2
#define NALL_CONFIG_HPP
3
4
#include <nall/file.hpp>
5
#include <nall/string.hpp>
6
#include <nall/vector.hpp>
7
8
namespace nall {
9
namespace configuration_traits {
10
template<typename T> struct is_boolean { enum { value = false }; };
11
template<> struct is_boolean<bool> { enum { value = true }; };
12
13
template<typename T> struct is_signed { enum { value = false }; };
14
template<> struct is_signed<signed> { enum { value = true }; };
15
16
template<typename T> struct is_unsigned { enum { value = false }; };
17
template<> struct is_unsigned<unsigned> { enum { value = true }; };
18
19
template<typename T> struct is_double { enum { value = false }; };
20
template<> struct is_double<double> { enum { value = true }; };
21
22
template<typename T> struct is_string { enum { value = false }; };
23
template<> struct is_string<string> { enum { value = true }; };
24
}
25
26
class configuration {
27
public:
28
enum type_t { boolean_t, signed_t, unsigned_t, double_t, string_t, unknown_t };
29
struct item_t {
30
uintptr_t data;
31
string name;
32
string desc;
33
type_t type;
34
35
inline string get() const {
36
switch(type) {
37
case boolean_t: return { *(bool*)data };
38
case signed_t: return { *(signed*)data };
39
case unsigned_t: return { *(unsigned*)data };
40
case double_t: return { *(double*)data };
41
case string_t: return { "\"", *(string*)data, "\"" };
42
}
43
return "???";
44
}
45
46
inline void set(string s) {
47
switch(type) {
48
case boolean_t: *(bool*)data = (s == "true"); break;
49
case signed_t: *(signed*)data = integer(s); break;
50
case unsigned_t: *(unsigned*)data = decimal(s); break;
51
case double_t: *(double*)data = fp(s); break;
52
case string_t: s.trim("\""); *(string*)data = s; break;
53
}
54
}
55
};
56
vector<item_t> list;
57
58
template<typename T>
59
inline void append(T &data, const char *name, const char *desc = "") {
60
item_t item = { (uintptr_t)&data, name, desc };
61
if(configuration_traits::is_boolean<T>::value) item.type = boolean_t;
62
else if(configuration_traits::is_signed<T>::value) item.type = signed_t;
63
else if(configuration_traits::is_unsigned<T>::value) item.type = unsigned_t;
64
else if(configuration_traits::is_double<T>::value) item.type = double_t;
65
else if(configuration_traits::is_string<T>::value) item.type = string_t;
66
else item.type = unknown_t;
67
list.append(item);
68
}
69
70
//deprecated
71
template<typename T>
72
inline void attach(T &data, const char *name, const char *desc = "") {
73
append(data, name, desc);
74
}
75
76
inline virtual bool load(const string &filename) {
77
string data;
78
if(data.readfile(filename) == true) {
79
data.replace("\r", "");
80
lstring line;
81
line.split("\n", data);
82
83
for(unsigned i = 0; i < line.size(); i++) {
84
if(auto position = qstrpos(line[i], "#")) line[i][position()] = 0;
85
if(!qstrpos(line[i], " = ")) continue;
86
87
lstring part;
88
part.qsplit(" = ", line[i]);
89
part[0].trim();
90
part[1].trim();
91
92
for(unsigned n = 0; n < list.size(); n++) {
93
if(part[0] == list[n].name) {
94
list[n].set(part[1]);
95
break;
96
}
97
}
98
}
99
100
return true;
101
} else {
102
return false;
103
}
104
}
105
106
inline virtual bool save(const string &filename) const {
107
file fp;
108
if(fp.open(filename, file::mode::write)) {
109
for(unsigned i = 0; i < list.size(); i++) {
110
string output;
111
output.append(list[i].name, " = ", list[i].get());
112
if(list[i].desc != "") output.append(" # ", list[i].desc);
113
output.append("\r\n");
114
fp.print(output);
115
}
116
117
fp.close();
118
return true;
119
} else {
120
return false;
121
}
122
}
123
};
124
}
125
126
#endif
127
128