2019-05-10 05:17:29 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
#include <algorithm>
|
|
|
|
#include "./Input.h"
|
2021-03-28 21:50:31 +00:00
|
|
|
#include "./Ringbuf.h"
|
2019-05-10 05:17:29 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
};
|