#pragma once #include #include #include #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 &commands() const; }; /** * Functional lambda interface for creating Tasks */ struct TaskFunc: public Task { TaskFunc(std::function func) : Task("lambda"), func(func) {} void loop() override {func();} std::function 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 func) : Figment("lambda"), func(func) {} void loop() override {} void render(Display* dpy) const override { func(dpy); } std::function func; };