openMSX
ImGuiPartInterface.hh
Go to the documentation of this file.
1#ifndef IMGUI_PARTINTERFACE_HH
2#define IMGUI_PARTINTERFACE_HH
3
4#include "ImGuiCpp.hh"
5
6#include "StringOp.hh"
7#include "stl.hh"
8#include "zstring_view.hh"
9
10#include <initializer_list>
11#include <string>
12#include <string_view>
13
14#include <imgui.h>
15
16namespace openmsx {
17
18class MSXMotherBoard;
19
21{
22public:
23 [[nodiscard]] virtual zstring_view iniName() const { return ""; }
24 virtual void save(ImGuiTextBuffer& /*buf*/) {}
25 virtual void loadStart() {}
26 virtual void loadLine(std::string_view /*name*/, zstring_view /*value*/) {}
27 virtual void loadEnd() {}
28
29 virtual void showMenu(MSXMotherBoard* /*motherBoard*/) {}
30 virtual void paint(MSXMotherBoard* /*motherBoard*/) {}
31};
32
34
35template<typename C, typename T> struct PersistentElementBase {
36 constexpr PersistentElementBase(zstring_view name_, T C::*p_)
37 : name(name_), p(p_) {}
38
40 T C::*p;
41
42 T& get(C& c) const { return c.*p; }
43};
44
45// 'PersistentElement' base-case, will be partially specialized for concrete 'T'.
46template<typename C, typename T>
48template<typename C, typename T>
50
51template<typename C>
53 using PersistentElementBase<C, int>::PersistentElementBase;
54 void save(ImGuiTextBuffer& buf, C& c) const {
55 buf.appendf("%s=%d\n", this->name.c_str(), this->get(c));
56 }
57 void load(C& c, zstring_view value) const {
58 if (auto r = StringOp::stringTo<int>(value)) {
59 this->get(c) = *r;
60 }
61 }
62};
63
64template<typename C>
66 int max;
67 constexpr PersistentElementMax(zstring_view name_, int C::*p_, int max_)
68 : PersistentElement<C, int>(name_, p_), max(max_) {}
69
70 void load(C& c, std::string_view value) const {
71 if (auto r = StringOp::stringTo<int>(value)) {
72 if (0 <= *r && *r < max) this->get(c) = *r;
73 }
74 }
75};
76
77template<typename C>
79 int min, max;
80 constexpr PersistentElementMinMax(zstring_view name_, int C::*p_, int min_, int max_)
81 : PersistentElement<C, int>(name_, p_), min(min_), max(max_) {}
82
83 void load(C& c, std::string_view value) const {
84 if (auto r = StringOp::stringTo<int>(value)) {
85 if (min <= *r && *r < max) this->get(c) = *r;
86 }
87 }
88};
89
90template<typename C>
92 std::initializer_list<int> valid;
93 constexpr PersistentElementEnum(zstring_view name_, int C::*p_, std::initializer_list<int> valid_)
94 : PersistentElement<C, int>(name_, p_), valid(valid_) {}
95
96 void load(C& c, std::string_view value) const {
97 if (auto r = StringOp::stringTo<int>(value)) {
98 if (contains(valid, *r)) this->get(c) = *r;
99 }
100 }
101};
102
103template<typename C>
104struct PersistentElement<C, unsigned> : PersistentElementBase<C, unsigned> {
105 using PersistentElementBase<C, unsigned>::PersistentElementBase;
106 void save(ImGuiTextBuffer& buf, C& c) const {
107 buf.appendf("%s=%u\n", this->name.c_str(), this->get(c));
108 }
109 void load(C& c, zstring_view value) const {
110 if (auto r = StringOp::stringTo<unsigned>(value)) {
111 this->get(c) = *r;
112 }
113 }
114};
115
116template<typename C>
117struct PersistentElement<C, bool> : PersistentElementBase<C, bool> {
118 using PersistentElementBase<C, bool>::PersistentElementBase;
119 void save(ImGuiTextBuffer& buf, C& c) const {
120 buf.appendf("%s=%d\n", this->name.c_str(), this->get(c));
121 }
122 void load(C& c, zstring_view value) const {
123 this->get(c) = StringOp::stringToBool(value);
124 }
125};
126
127template<typename C>
128struct PersistentElement<C, float> : PersistentElementBase<C, float> {
129 using PersistentElementBase<C, float>::PersistentElementBase;
130 void save(ImGuiTextBuffer& buf, C& c) const {
131 buf.appendf("%s=%f\n", this->name.c_str(), double(this->get(c))); // cast to silence warning
132 }
133 void load(C& c, zstring_view value) const {
134 this->get(c) = strtof(value.c_str(), nullptr); // TODO error handling
135 }
136};
137
138template<typename C>
139struct PersistentElement<C, std::string> : PersistentElementBase<C, std::string> {
140 using PersistentElementBase<C, std::string>::PersistentElementBase;
141 void save(ImGuiTextBuffer& buf, C& c) const {
142 buf.appendf("%s=%s\n", this->name.c_str(), this->get(c).c_str());
143 }
144 void load(C& c, zstring_view value) const {
145 this->get(c) = std::string(value);
146 }
147};
148
149template<typename C>
150struct PersistentElement<C, gl::ivec2> : PersistentElementBase<C, gl::ivec2> {
151 using PersistentElementBase<C, gl::ivec2>::PersistentElementBase;
152 void save(ImGuiTextBuffer& buf, C& c) const {
153 const auto& v = this->get(c);
154 buf.appendf("%s=[ %d %d ]\n", this->name.c_str(), v.x, v.y);
155 }
156 void load(C& c, zstring_view value) const {
157 gl::ivec2 t;
158 if (sscanf(value.c_str(), "[ %d %d ]", &t.x, &t.y) == 2) {
159 this->get(c) = t;
160 }
161 }
162};
163
164template<typename C>
165struct PersistentElement<C, gl::vec4> : PersistentElementBase<C, gl::vec4> {
166 using PersistentElementBase<C, gl::vec4>::PersistentElementBase;
167 void save(ImGuiTextBuffer& buf, C& c) const {
168 const auto& v = this->get(c);
169 buf.appendf("%s=[ %f %f %f %f ]\n", this->name.c_str(),
170 double(v.x), double(v.y), double(v.z), double(v.w)); // note: cast only needed to silence warnings
171 }
172 void load(C& c, zstring_view value) const {
173 gl::vec4 t;
174 if (sscanf(value.c_str(), "[ %f %f %f %f ]", &t.x, &t.y, &t.z, &t.w) == 4) {
175 this->get(c) = t;
176 }
177 }
178};
179
180template<typename C>
181struct PersistentElement<C, im::WindowStatus> : PersistentElementBase<C, im::WindowStatus> {
182 using PersistentElementBase<C, im::WindowStatus>::PersistentElementBase;
183 void save(ImGuiTextBuffer& buf, C& c) const {
184 buf.appendf("%s=%d\n", this->name.c_str(), this->get(c).open);
185 }
186 void load(C& c, zstring_view value) const {
187 this->get(c).open = StringOp::stringToBool(value);
188 }
189};
190
191
192template<typename C, typename... Elements>
193void savePersistent(ImGuiTextBuffer& buf, C& c, const std::tuple<Elements...>& tup)
194{
195 std::apply([&](auto& ...elem){(..., elem.save(buf, c));}, tup);
196}
197
198template<typename C, typename Elem>
199bool checkLoad(std::string_view name, zstring_view value,
200 C& c, Elem& elem)
201{
202 if (name != elem.name) return false;
203 elem.load(c, value);
204 return true;
205}
206template<typename C, typename... Elements>
207bool loadOnePersistent(std::string_view name, zstring_view value,
208 C& c, const std::tuple<Elements...>& tup)
209{
210 return std::apply([&](auto& ...elem){ return (... || checkLoad(name, value, c, elem));}, tup);
211}
212
213} // namespace openmsx
214
215#endif
TclObject t
virtual zstring_view iniName() const
virtual void showMenu(MSXMotherBoard *)
virtual void loadLine(std::string_view, zstring_view)
virtual void paint(MSXMotherBoard *)
virtual void save(ImGuiTextBuffer &)
Like std::string_view, but with the extra guarantee that it refers to a zero-terminated string.
constexpr const char * c_str() const
bool stringToBool(string_view str)
Definition StringOp.cc:16
Definition gl_mat.hh:23
Definition ImGuiCpp.hh:60
This file implemented 3 utility functions:
Definition Autofire.cc:9
bool loadOnePersistent(std::string_view name, zstring_view value, C &c, const std::tuple< Elements... > &tup)
void savePersistent(ImGuiTextBuffer &buf, C &c, const std::tuple< Elements... > &tup)
bool checkLoad(std::string_view name, zstring_view value, C &c, Elem &elem)
STL namespace.
constexpr bool contains(ITER first, ITER last, const VAL &val)
Check if a range contains a given value, using linear search.
Definition stl.hh:32
constexpr PersistentElementBase(zstring_view name_, T C::*p_)
void load(C &c, std::string_view value) const
constexpr PersistentElementEnum(zstring_view name_, int C::*p_, std::initializer_list< int > valid_)
std::initializer_list< int > valid
void load(C &c, std::string_view value) const
constexpr PersistentElementMax(zstring_view name_, int C::*p_, int max_)
void load(C &c, std::string_view value) const
constexpr PersistentElementMinMax(zstring_view name_, int C::*p_, int min_, int max_)
void save(ImGuiTextBuffer &buf, C &c) const
void load(C &c, zstring_view value) const
void load(C &c, zstring_view value) const
void save(ImGuiTextBuffer &buf, C &c) const
void load(C &c, zstring_view value) const
void save(ImGuiTextBuffer &buf, C &c) const
void save(ImGuiTextBuffer &buf, C &c) const
void load(C &c, zstring_view value) const
void save(ImGuiTextBuffer &buf, C &c) const
void save(ImGuiTextBuffer &buf, C &c) const
void load(C &c, zstring_view value) const
void load(C &c, zstring_view value) const
void save(ImGuiTextBuffer &buf, C &c) const
void load(C &c, zstring_view value) const
void save(ImGuiTextBuffer &buf, C &c) const