Skip to content

Commit bf593ce

Browse files
committed
Add TimeDurationOption.
1 parent f101a68 commit bf593ce

16 files changed

+1028
-415
lines changed

Common/Qt/ExpressionEvaluator.cpp renamed to Common/Cpp/ExpressionEvaluator.cpp

Lines changed: 372 additions & 299 deletions
Large diffs are not rendered by default.
Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
1-
/* Simple (and incomplete) Expression Evaluator
2-
*
3-
* From: https://github.com/PokemonAutomation/Arduino-Source
4-
*
5-
*/
6-
7-
#include <stdint.h>
8-
#include <string>
9-
10-
namespace PokemonAutomation{
11-
12-
uint32_t parse_ticks_ui32(const std::string& expression);
13-
14-
int32_t parse_ticks_i32(const std::string& expression);
15-
16-
17-
}
1+
/* Simple (and incomplete) Expression Evaluator
2+
*
3+
* From: https://github.com/PokemonAutomation/Arduino-Source
4+
*
5+
*/
6+
7+
#include <stdint.h>
8+
#include <string>
9+
#include <map>
10+
11+
namespace PokemonAutomation{
12+
13+
14+
15+
int64_t parse_expression(
16+
const std::map<std::string, int64_t>& variables,
17+
const std::string& expression
18+
);
19+
uint32_t parse_ticks_ui32(const std::string& expression);
20+
int32_t parse_ticks_i32(const std::string& expression);
21+
22+
23+
}
Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
/* Time Duration Option
2+
*
3+
* From: https://github.com/PokemonAutomation/Arduino-Source
4+
*
5+
*/
6+
7+
#include "Common/Cpp/PrettyPrint.h"
8+
#include "Common/Cpp/ExpressionEvaluator.h"
9+
#include "Common/Cpp/Json/JsonValue.h"
10+
#include "Common/Cpp/Containers/Pimpl.tpp"
11+
#include "Common/Cpp/Concurrency/SpinLock.h"
12+
#include "Common/Qt/Options/TimeDurationWidget.h"
13+
#include "TimeDurationOption.h"
14+
15+
//#include <iostream>
16+
//using std::cout;
17+
//using std::endl;
18+
19+
namespace PokemonAutomation{
20+
21+
22+
template <typename Type>
23+
struct TimeDurationCell<Type>::Data{
24+
const std::string m_units;
25+
const Type m_min_value;
26+
const Type m_max_value;
27+
const std::string m_default;
28+
29+
mutable SpinLock m_lock;
30+
std::string m_current;
31+
Type m_value;
32+
std::string m_error;
33+
34+
Data(
35+
std::string units,
36+
Type min_value, Type max_value,
37+
std::string default_value
38+
)
39+
: m_units(units)
40+
, m_min_value(min_value)
41+
, m_max_value(max_value)
42+
, m_default(std::move(default_value))
43+
, m_current(m_default)
44+
, m_value(0)
45+
{
46+
m_error = process(m_current, m_value);
47+
}
48+
49+
std::string process(const std::string& text, Type& value) const{
50+
if (text.empty()){
51+
return "Expression is empty.";
52+
}
53+
54+
static const std::map<std::string, int64_t> SYMBOLS{
55+
{"ms", std::chrono::duration_cast<Type>(std::chrono::milliseconds(1)).count()},
56+
{"s", std::chrono::duration_cast<Type>(std::chrono::seconds(1)).count()},
57+
{"min", std::chrono::duration_cast<Type>(std::chrono::minutes(1)).count()},
58+
{"h", std::chrono::duration_cast<Type>(std::chrono::hours(1)).count()},
59+
{"d", std::chrono::duration_cast<Type>(std::chrono::days(1)).count()},
60+
{"y", std::chrono::duration_cast<Type>(std::chrono::years(1)).count()},
61+
};
62+
63+
using Rep = typename Type::rep;
64+
Rep parsed;
65+
try{
66+
parsed = parse_expression(SYMBOLS, text);
67+
}catch (const ParseException& str){
68+
return str.message();
69+
}
70+
// std::cout << "value = " << parsed << " " << m_min_value << " " << m_max_value << std::endl;
71+
72+
if (Type(parsed) < m_min_value){
73+
return "Overflow: Number is too small.";
74+
}
75+
if (Type(parsed) > m_max_value){
76+
return "Overflow: Number is too large.";
77+
}
78+
value = (Type)parsed;
79+
return std::string();
80+
}
81+
};
82+
83+
84+
85+
86+
87+
template <typename Type>
88+
TimeDurationCell<Type>::~TimeDurationCell() = default;
89+
template <typename Type>
90+
TimeDurationCell<Type>::TimeDurationCell(
91+
std::string units,
92+
LockMode lock_while_running,
93+
Type min_value, Type max_value,
94+
std::string default_value
95+
)
96+
: ConfigOption(lock_while_running)
97+
, m_data(
98+
CONSTRUCT_TOKEN,
99+
std::move(units),
100+
min_value, max_value,
101+
std::move(default_value)
102+
)
103+
{}
104+
105+
template <typename Type>
106+
TimeDurationCell<Type>::TimeDurationCell(
107+
std::string units,
108+
LockMode lock_while_running,
109+
std::string default_value
110+
)
111+
: ConfigOption(lock_while_running)
112+
, m_data(
113+
CONSTRUCT_TOKEN,
114+
std::move(units),
115+
Type(0), std::chrono::milliseconds::max(),
116+
std::move(default_value)
117+
)
118+
{}
119+
template <typename Type>
120+
TimeDurationCell<Type>::TimeDurationCell(
121+
std::string units,
122+
LockMode lock_while_running,
123+
Type min_value,
124+
std::string default_value
125+
)
126+
: ConfigOption(lock_while_running)
127+
, m_data(
128+
CONSTRUCT_TOKEN,
129+
std::move(units),
130+
min_value, std::chrono::milliseconds::max(),
131+
std::move(default_value)
132+
)
133+
{}
134+
135+
136+
template <typename Type>
137+
const std::string& TimeDurationCell<Type>::units() const{
138+
return m_data->m_units;
139+
}
140+
template <typename Type>
141+
Type TimeDurationCell<Type>::min_value() const{
142+
return m_data->m_min_value;
143+
}
144+
template <typename Type>
145+
Type TimeDurationCell<Type>::max_value() const{
146+
return m_data->m_max_value;
147+
}
148+
template <typename Type>
149+
const std::string& TimeDurationCell<Type>::default_value() const{
150+
return m_data->m_default;
151+
}
152+
template <typename Type>
153+
std::string TimeDurationCell<Type>::current_text() const{
154+
const Data& data = *m_data;
155+
ReadSpinLock lg(data.m_lock);
156+
return data.m_current;
157+
}
158+
template <typename Type>
159+
TimeDurationCell<Type>::operator Type() const{
160+
const Data& data = *m_data;
161+
ReadSpinLock lg(data.m_lock);
162+
return data.m_value;
163+
}
164+
template <typename Type>
165+
Type TimeDurationCell<Type>::get() const{
166+
const Data& data = *m_data;
167+
ReadSpinLock lg(data.m_lock);
168+
return data.m_value;
169+
}
170+
template <typename Type>
171+
std::string TimeDurationCell<Type>::set(std::string text){
172+
Data& data = *m_data;
173+
Type value(0);
174+
std::string error;
175+
{
176+
WriteSpinLock lg(data.m_lock);
177+
if (data.m_current == text){
178+
return std::string();
179+
}
180+
error = data.process(text, value);
181+
data.m_current = std::move(text);
182+
data.m_value = value;
183+
data.m_error.clear();
184+
}
185+
report_value_changed(this);
186+
return error;
187+
}
188+
189+
template <typename Type>
190+
std::string TimeDurationCell<Type>::time_string() const{
191+
const Data& data = *m_data;
192+
ReadSpinLock lg(data.m_lock);
193+
if (!data.m_error.empty()){
194+
return "<font color=\"red\">" + data.m_error + "</font>";
195+
}
196+
return duration_to_string(std::chrono::duration_cast<Milliseconds>(data.m_value));
197+
}
198+
template <typename Type>
199+
std::string TimeDurationCell<Type>::time_string(const std::string& text) const{
200+
const Data& data = *m_data;
201+
Type value;
202+
std::string error = data.process(text, value);
203+
if (error.empty()){
204+
return duration_to_string(std::chrono::duration_cast<Milliseconds>(value));
205+
}else{
206+
return "<font color=\"red\">" + error + "</font>";
207+
}
208+
}
209+
210+
template <typename Type>
211+
void TimeDurationCell<Type>::load_json(const JsonValue& json){
212+
Data& data = *m_data;
213+
const std::string* str = json.to_string();
214+
if (str == nullptr){
215+
return;
216+
}
217+
{
218+
WriteSpinLock lg(data.m_lock);
219+
data.m_current = *str;
220+
data.m_error = data.process(data.m_current, data.m_value);
221+
}
222+
report_value_changed(this);
223+
}
224+
template <typename Type>
225+
JsonValue TimeDurationCell<Type>::to_json() const{
226+
const Data& data = *m_data;
227+
ReadSpinLock lg(data.m_lock);
228+
return data.m_current;
229+
}
230+
231+
template <typename Type>
232+
std::string TimeDurationCell<Type>::check_validity() const{
233+
const Data& data = *m_data;
234+
ReadSpinLock lg(data.m_lock);
235+
return data.m_error;
236+
}
237+
template <typename Type>
238+
void TimeDurationCell<Type>::restore_defaults(){
239+
Data& data = *m_data;
240+
{
241+
WriteSpinLock lg(data.m_lock);
242+
data.m_current = data.m_default;
243+
data.m_error = data.process(data.m_current, data.m_value);
244+
}
245+
report_value_changed(this);
246+
}
247+
248+
249+
250+
251+
252+
253+
254+
255+
256+
template <typename Type>
257+
ConfigWidget* TimeDurationCell<Type>::make_QtWidget(QWidget& parent){
258+
return new TimeDurationCellWidget<Type>(parent, *this);
259+
}
260+
261+
template <typename Type>
262+
ConfigWidget* TimeDurationOption<Type>::make_QtWidget(QWidget& parent){
263+
return new TimeDurationOptionWidget<Type>(parent, *this);
264+
}
265+
266+
267+
268+
269+
270+
template class TimeDurationCell<std::chrono::milliseconds>;
271+
template class TimeDurationOption<std::chrono::milliseconds>;
272+
273+
274+
275+
276+
277+
278+
279+
}

0 commit comments

Comments
 (0)