summaryrefslogtreecommitdiffstats
path: root/src/control/EventBus.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/control/EventBus.hpp')
-rw-r--r--src/control/EventBus.hpp58
1 files changed, 43 insertions, 15 deletions
diff --git a/src/control/EventBus.hpp b/src/control/EventBus.hpp
index ae4603f..7284883 100644
--- a/src/control/EventBus.hpp
+++ b/src/control/EventBus.hpp
@@ -27,12 +27,16 @@
#pragma once
-#include "Event.hpp"
+#include "TimeProvider.hpp"
+#include <chrono>
+#include <condition_variable>
+#include <cstdint>
#include <deque>
+#include <functional>
#include <limits>
-#include <memory>
#include <queue>
+#include <thread>
namespace RPGEdit {
@@ -40,35 +44,59 @@ namespace RPGEdit {
namespace Control {
class EventBus {
-private:
- typedef std::pair<uint64_t, std::shared_ptr<Event>> event_entry;
+public:
+ typedef std::function<void ()> Event;
+ typedef std::pair<uint64_t, Event> EventEntry;
- static bool compare_events(const event_entry &e1, const event_entry &e2) {
+private:
+ static bool compare_events(const EventEntry &e1, const EventEntry &e2) {
return e1.first > e2.first;
}
- std::priority_queue<event_entry, std::deque<event_entry>, bool (*)(const event_entry &, const event_entry &)> events;
+ std::priority_queue<EventEntry, std::deque<EventEntry>, bool (*)(const EventEntry &, const EventEntry &)> events;
+
+ std::mutex mutex;
+ std::condition_variable cond;
public:
EventBus() : events(compare_events) {
}
- void enqueue(const std::shared_ptr<Event> &event, uint64_t time) {
- events.push(std::pair<uint64_t, std::shared_ptr<Event>>(time, event));
+ void enqueue(const Event &event, uint64_t time) {
+ std::lock_guard<std::mutex> lock(mutex);
+ events.push(EventEntry(time, event));
+ cond.notify_one();
}
- std::pair<uint64_t, std::shared_ptr<Event>> get(uint64_t time) {
- if (events.empty())
- return std::make_pair<uint64_t, std::shared_ptr<Event>>(std::numeric_limits<uint64_t>::max(), nullptr);
+ EventEntry get(TimeProvider *timeProvider) {
+ std::unique_lock<std::mutex> lock(mutex);
+
+ while (true) {
+ if (events.empty()) {
+ cond.wait(lock);
+ continue;
+ }
- std::pair<uint64_t, std::shared_ptr<Event>> top = events.top();
+ EventEntry top = events.top();
+ uint64_t time = timeProvider->now();
+
+ if (top.first > time) {
+ cond.wait_for(lock, std::chrono::milliseconds(top.first - time));
+ continue;
+ }
- if (top.first <= time) {
events.pop();
return top;
}
- else
- return std::pair<uint64_t, std::shared_ptr<Event>>(top.first, std::shared_ptr<Event>());
+ }
+
+ uint64_t peek() {
+ std::lock_guard<std::mutex> lock(mutex);
+
+ if (events.empty())
+ return std::numeric_limits<uint64_t>::max();
+
+ return events.top().first;
}
};