renderbug/lib/Figments/Figment.h

110 lines
2.5 KiB
C
Raw Normal View History

2019-05-10 05:17:29 +00:00
#pragma once
2021-03-29 08:10:55 +00:00
#include <Arduino.h>
2019-05-10 05:17:29 +00:00
#include <functional>
2021-03-29 08:10:55 +00:00
#include <ArduinoLog.h>
#include "./Command.h"
2019-05-10 05:17:29 +00:00
#define F_LIKELY(x) __builtin_expect(!!(x), true)
#define F_UNLIKELY(x) __builtin_expect(!!(x), false)
2019-05-10 05:17:29 +00:00
class Display;
class InputEvent;
class InputSource;
2023-03-03 18:43:51 +00:00
/**
* A generic interface for anything that can be executed and respond to events.
*/
2021-03-28 01:19:55 +00:00
struct Loopable {
2023-03-03 18:43:51 +00:00
/**
* Called by the MainLoop to process events
*/
2019-05-10 05:17:29 +00:00
virtual void handleEvent(const InputEvent& event) {}
2023-03-03 18:43:51 +00:00
/**
* Called on every MainLoop tick
*/
2019-05-10 05:17:29 +00:00
virtual void loop() = 0;
2021-03-28 01:19:55 +00:00
};
2023-03-03 18:43:51 +00:00
/**
* A Loopable that can be named and may be started or stopped in a MainLoop.
*/
2021-03-28 01:19:55 +00:00
struct Task : public virtual Loopable {
2023-03-03 18:43:51 +00:00
/**
* Implement in a subclass to run when the task is started
* The default implementation does nothing.
*/
2019-05-10 05:17:29 +00:00
virtual void onStart() {};
2023-03-03 18:43:51 +00:00
/**
* Implement in a subclass to run when the task is stopped.
* The default implementation does nothing.
*/
2019-05-10 05:17:29 +00:00
virtual void onStop() {};
enum State {
Running,
Stopped,
};
Task() {}
explicit Task(const char* name) : name(name) {}
2019-05-10 05:17:29 +00:00
2023-03-03 18:43:51 +00:00
/**
* Starts the task and makes it schedulable
*/
2021-03-29 08:10:55 +00:00
void start() { state = Running; onStart(); }
2023-03-03 18:43:51 +00:00
/**
* Stops the task and makes it unschedulable
*/
2021-03-29 08:10:55 +00:00
void stop() { onStop(); state = Stopped; }
2023-03-03 18:43:51 +00:00
/**
* A hacky way to determine if a task is a Figment subclass or not, without
* having to resort to RTTI
*/
2021-03-28 01:19:55 +00:00
virtual bool isFigment() const { return false; }
2019-05-10 05:17:29 +00:00
const char* name = "";
State state = Stopped;
virtual const std::vector<Command> &commands() const;
2019-05-10 05:17:29 +00:00
};
2023-03-03 18:43:51 +00:00
/**
* Functional lambda interface for creating Tasks
*/
2021-04-10 18:10:25 +00:00
struct TaskFunc: public Task {
TaskFunc(std::function<void()> func) : Task("lambda"), func(func) {}
void loop() override {func();}
std::function<void()> func;
};
2023-03-03 18:43:51 +00:00
/**
* A Task with a graphical output
*/
2019-05-10 05:17:29 +00:00
struct Figment: public Task {
Figment() : Task() {}
explicit Figment(const char* name) : Task(name) {}
2023-03-03 18:43:51 +00:00
/**
* Called when the Figment should render its output to a display
*/
2019-05-10 05:17:29 +00:00
virtual void render(Display* dpy) const = 0;
2021-03-28 01:19:55 +00:00
bool isFigment() const override { return true; }
2019-05-10 05:17:29 +00:00
};
2023-03-03 18:43:51 +00:00
/**
* Functional lambda interface for creating Figments
*/
2019-05-10 05:17:29 +00:00
struct FigmentFunc: public Figment {
FigmentFunc(std::function<void(Display*)> func) : Figment("lambda"), func(func) {}
void loop() override {}
void render(Display* dpy) const override {
func(dpy);
}
std::function<void(Display*)> func;
};