diff options
Diffstat (limited to 'src/control/EventBus.hpp')
-rw-r--r-- | src/control/EventBus.hpp | 58 |
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; } }; |