port to platformio
This commit is contained in:
178
lib/Figments/Input.h
Normal file
178
lib/Figments/Input.h
Normal file
@@ -0,0 +1,178 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include "./Geometry.h"
|
||||
#include "./Figment.h"
|
||||
#include "./Ringbuf.h"
|
||||
#include <FastLED.h>
|
||||
|
||||
typedef Vector3d<int> MotionVec;
|
||||
|
||||
struct Variant {
|
||||
enum Type {
|
||||
Null,
|
||||
Integer,
|
||||
String,
|
||||
Color,
|
||||
};
|
||||
|
||||
Variant(int v)
|
||||
: type(Integer), m_value{.asInt=v} {}
|
||||
|
||||
Variant(const char* v)
|
||||
: type(String), m_value{.asString=v} {}
|
||||
|
||||
Variant(const CRGB &v)
|
||||
: type(Color), m_value{.asRGB={v.r, v.g, v.b}} {}
|
||||
|
||||
Variant()
|
||||
: type(Null) {}
|
||||
|
||||
Type type;
|
||||
|
||||
const char* asString() const;
|
||||
CRGB asRGB() const;
|
||||
int asInt() const;
|
||||
|
||||
private:
|
||||
union {
|
||||
int asInt;
|
||||
const char* asString;
|
||||
uint8_t asRGB[3];
|
||||
} m_value;
|
||||
};
|
||||
|
||||
struct InputEvent: public Variant {
|
||||
enum Intent {
|
||||
// An empty non-event
|
||||
None,
|
||||
|
||||
// An input from the user, for other tasks to translate into canonical
|
||||
// types. Makes for easy button re-mapping on the fly.
|
||||
UserInput,
|
||||
|
||||
//
|
||||
// The canonical types
|
||||
//
|
||||
// Hardware inputs
|
||||
ButtonPress,
|
||||
Acceleration,
|
||||
NetworkStatus,
|
||||
NetworkActivity,
|
||||
|
||||
// Power management
|
||||
PowerToggle,
|
||||
SetPower,
|
||||
SetBrightness,
|
||||
|
||||
// Animation sequencing
|
||||
PreviousPattern,
|
||||
NextPattern,
|
||||
SetPattern,
|
||||
PreviousScene,
|
||||
NextScene,
|
||||
SetScene,
|
||||
|
||||
// Timekeeping
|
||||
ScheduleChange,
|
||||
|
||||
// Task management
|
||||
StartThing,
|
||||
StopThing,
|
||||
|
||||
// Configuration
|
||||
SetDisplayOffset,
|
||||
SetDisplayLength,
|
||||
SetColor,
|
||||
SaveConfigurationRequest,
|
||||
|
||||
// Firmware events
|
||||
FirmwareUpdate,
|
||||
};
|
||||
|
||||
template<typename Value>
|
||||
InputEvent(Intent s, Value v)
|
||||
: Variant(v), intent(s) {}
|
||||
|
||||
InputEvent(Intent s)
|
||||
: Variant(), intent(s) {}
|
||||
|
||||
InputEvent()
|
||||
: Variant(), intent(None) {}
|
||||
|
||||
Intent intent;
|
||||
};
|
||||
|
||||
class InputSource: public Task {
|
||||
public:
|
||||
InputSource() : Task() {}
|
||||
InputSource(const char* name) : Task(name) {}
|
||||
InputSource(Task::State initialState) : Task(initialState) {}
|
||||
InputSource(const char* name, Task::State initialState) : Task(name, initialState) {}
|
||||
void loop() override;
|
||||
virtual InputEvent read() = 0;
|
||||
};
|
||||
|
||||
class InputFunc : public InputSource {
|
||||
public:
|
||||
InputFunc(std::function<InputEvent(void)> f) : InputSource(), m_func(f) {}
|
||||
InputFunc(std::function<InputEvent(void)> f, const char* name) : InputSource(name), m_func(f) {}
|
||||
InputFunc(std::function<InputEvent(void)> f, const char* name, Task::State initialState) : InputSource(name, initialState), m_func(f) {}
|
||||
|
||||
InputEvent read() override {
|
||||
return m_func();
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<InputEvent(void)> m_func;
|
||||
};
|
||||
|
||||
class BufferedInputSource: public InputSource {
|
||||
public:
|
||||
BufferedInputSource() : InputSource() {}
|
||||
BufferedInputSource(const char* name) : InputSource(name) {}
|
||||
InputEvent read() override;
|
||||
|
||||
protected:
|
||||
void setEvent(InputEvent &&evt);
|
||||
void setEvent(InputEvent::Intent intent, Variant &&v);
|
||||
|
||||
private:
|
||||
Ringbuf<InputEvent, 5> m_eventQueue;
|
||||
};
|
||||
|
||||
class InputMapper: public BufferedInputSource {
|
||||
public:
|
||||
InputMapper(std::function<InputEvent(const InputEvent)> f, const char* name) : BufferedInputSource(name), m_func(f) {}
|
||||
|
||||
void handleEvent(const InputEvent& evt) override {
|
||||
setEvent(m_func(evt));
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<InputEvent(const InputEvent)> m_func;
|
||||
};
|
||||
|
||||
class OnlineTaskMixin : public virtual Loopable {
|
||||
public:
|
||||
void handleEvent(const InputEvent &evt) override {
|
||||
if (evt.intent == InputEvent::NetworkStatus) {
|
||||
m_online = evt.asInt();
|
||||
}
|
||||
if (m_online) {
|
||||
handleEventOnline(evt);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void handleEventOnline(const InputEvent &evt) = 0;
|
||||
|
||||
void loop() override {
|
||||
if (m_online) {
|
||||
loopOnline();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void loopOnline() = 0;
|
||||
|
||||
private:
|
||||
bool m_online = false;
|
||||
};
|
||||
Reference in New Issue
Block a user