renderbug/lib/Figments/Figment.h

110 lines
2.5 KiB
C++

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