renderbug-cpp/firmware/Figments/MainLoop.h
2021-03-28 14:50:31 -07:00

70 lines
1.9 KiB
C++

#pragma once
#include <vector>
#include <algorithm>
#include "./Input.h"
#include "./Ringbuf.h"
class Task;
class InputSource;
struct Scheduler {
std::vector<Task*> tasks;
bool operator==(const Scheduler& other) const {
return tasks == other.tasks;
}
Scheduler(std::vector<Task*> &&tasks)
: tasks(std::move(tasks))
{}
struct iterator: public std::iterator<std::input_iterator_tag, Task*> {
Scheduler& queue;
int idx = 0;
explicit iterator(Scheduler& queue) : queue(queue), idx(nextEnabled(0)) {}
iterator(Scheduler& queue, int start) : queue(queue), idx(nextEnabled(start)) {}
iterator& operator++() {
while (idx < queue.tasks.size() && !queue.tasks[idx]->state == Task::Running) {
idx++;
}
idx = nextEnabled(idx+1);
return *this;
}
int nextEnabled(int start) const {
for(int pos = start; pos < queue.tasks.size();pos++) {
if (queue.tasks[pos]->state == Task::Running) {
return pos;
}
}
return queue.tasks.size();
}
iterator operator++(int) {iterator ret = *this; ++(*this); return ret;}
bool operator==(iterator other) const { return idx == other.idx && queue == other.queue; }
bool operator!=(iterator other) const { return !(*this == other); }
Task* operator*() const { return queue.tasks[idx]; }
};
iterator begin() { return iterator(*this); }
iterator end() { return iterator(*this, tasks.size()); }
};
struct MainLoop {
Scheduler scheduler;
MainLoop(std::vector<Task*> &&tasks)
: scheduler(std::move(tasks)) {s_instance = this;}
void start();
void loop();
void dispatch(const InputEvent& event);
static MainLoop* instance() { return s_instance; }
private:
Ringbuf<InputEvent, 10> m_eventBuf;
static MainLoop* s_instance;
};