1 #include "hardwareMappingEffects.h"
2 #include "logging.h"
3 #include "tween.h"
4 #include "hardwareController.h"
5 
6 #define REQ_SETTING(key, variable, effect_name) \
7     if (settings.find(key) == settings.end()) { LOG(ERROR) << "[" << key << "] not set for " << effect_name << " effect"; return false; } \
8     variable = convertOutput(settings[key]);
9 #define OPT_SETTING(key, variable, effect_name, default) \
10     if (settings.find(key) == settings.end()) { variable = default; } else { variable = convertOutput(settings[key]); }
11 
convertOutput(string number)12 float HardwareMappingEffect::convertOutput(string number)
13 {
14     if (number.startswith("$"))
15         return float(number.substr(1).toInt(16)) / 255;
16     if (number.startswith("[") && number.endswith("]"))
17         return float(number.substr(1, -1).toInt()) / 255;
18     return number.toFloat();
19 }
20 
configure(std::unordered_map<string,string> settings)21 bool HardwareMappingEffectStatic::configure(std::unordered_map<string, string> settings)
22 {
23     REQ_SETTING("value", value, "static");
24     return true;
25 }
26 
onActive()27 float HardwareMappingEffectStatic::onActive()
28 {
29     return value;
30 }
31 
configure(std::unordered_map<string,string> settings)32 bool HardwareMappingEffectGlow::configure(std::unordered_map<string, string> settings)
33 {
34     OPT_SETTING("min_value", min_value, "glow", 0.0);
35     OPT_SETTING("max_value", max_value, "glow", 1.0);
36     REQ_SETTING("time", time, "glow");
37     clock.restart();
38     return true;
39 }
40 
onActive()41 float HardwareMappingEffectGlow::onActive()
42 {
43     if (clock.getElapsedTime().asSeconds() > time * 2.0)
44         clock.restart();
45     float f = clock.getElapsedTime().asSeconds() / time;
46     if (f > 1.0)
47         return min_value * (f - 1.0) + max_value * (2.0 - f);
48     else
49         return min_value * (1.0 - f) + max_value * (f);
50 }
51 
onInactive()52 void HardwareMappingEffectGlow::onInactive()
53 {
54     clock.restart();
55 }
56 
configure(std::unordered_map<string,string> settings)57 bool HardwareMappingEffectBlink::configure(std::unordered_map<string, string> settings)
58 {
59     OPT_SETTING("on_value", on_value, "blink", 1.0);
60     OPT_SETTING("off_value", off_value, "blink", 0.0);
61     REQ_SETTING("on_time", on_time, "blink");
62     REQ_SETTING("off_time", off_time, "blink");
63     clock.restart();
64     return true;
65 }
66 
onActive()67 float HardwareMappingEffectBlink::onActive()
68 {
69     if (clock.getElapsedTime().asSeconds() > on_time + off_time)
70         clock.restart();
71     if (clock.getElapsedTime().asSeconds() > on_time)
72         return off_value;
73     else
74         return on_value;
75 }
76 
onInactive()77 void HardwareMappingEffectBlink::onInactive()
78 {
79     clock.restart();
80 }
81 
HardwareMappingEffectVariable(HardwareController * controller)82 HardwareMappingEffectVariable::HardwareMappingEffectVariable(HardwareController* controller)
83 : controller(controller)
84 {
85 }
86 
configure(std::unordered_map<string,string> settings)87 bool HardwareMappingEffectVariable::configure(std::unordered_map<string, string> settings)
88 {
89     if (settings.find("condition") != settings.end())
90     {
91         variable_name = settings["condition"];
92         if (variable_name.find("<") >= 0) variable_name = variable_name.substr(0, variable_name.find("<")).strip();
93         if (variable_name.find(">") >= 0) variable_name = variable_name.substr(0, variable_name.find(">")).strip();
94         if (variable_name.find("==") >= 0) variable_name = variable_name.substr(0, variable_name.find("==")).strip();
95         if (variable_name.find("!=") >= 0) variable_name = variable_name.substr(0, variable_name.find("!=")).strip();
96     }
97     if (settings.find("trigger") != settings.end())
98     {
99         variable_name = settings["trigger"];
100         if (variable_name.startswith("<"))
101         {
102             variable_name = variable_name.substr(1).strip();
103         }
104         if (variable_name.startswith(">"))
105         {
106             variable_name = variable_name.substr(1).strip();
107         }
108     }
109     if (settings.find("input") != settings.end())
110     {
111         variable_name = settings["input"];
112     }
113     OPT_SETTING("min_input", min_input, "value", 0.0);
114     OPT_SETTING("max_input", max_input, "value", 1.0);
115     OPT_SETTING("min_output", min_output, "value", 0.0);
116     OPT_SETTING("max_output", max_output, "value", 1.0);
117     return variable_name != "";
118 }
119 
onActive()120 float HardwareMappingEffectVariable::onActive()
121 {
122     float input = 0.0;
123     controller->getVariableValue(variable_name, input);
124     input = std::min(max_input, std::max(min_input, input));
125     return Tween<float>::linear(input, min_input, max_input, min_output, max_output);
126 }
127 
configure(std::unordered_map<string,string> settings)128 bool HardwareMappingEffectNoise::configure(std::unordered_map<string, string> settings)
129 {
130     OPT_SETTING("min_value", min_value, "noise", 0.0);
131     OPT_SETTING("max_value", max_value, "noise", 1.0);
132     OPT_SETTING("smoothness", smoothness, "noise", 0.0);
133     start_value = random(0.0, 1.0);
134     target_value = random(0.0, 1.0);
135     return true;
136 }
137 
onActive()138 float HardwareMappingEffectNoise::onActive()
139 {
140     float f = clock.getElapsedTime().asSeconds();
141     if (f > smoothness)
142     {
143         clock.restart();
144         start_value = target_value;
145         target_value = random(0, 1);
146         f = 0;
147     }
148     if (smoothness > 0)
149         f = Tween<float>::linear(f, 0, smoothness, start_value, target_value);
150     else
151         f = start_value;
152     return Tween<float>::linear(f, 0, 1, min_value, max_value);
153 }
154 
onInactive()155 void HardwareMappingEffectNoise::onInactive()
156 {
157     clock.restart();
158 }
159