#include "thread.hpp" auto Dispatcher::add_thread(std::shared_ptr thread) -> void { threads_.push_back(std::move(thread)); } auto Dispatcher::dispatch(std::shared_ptr event) -> void { if (dispatching_) { events_.push_back(std::move(event)); return; } dispatching_ = true; std::vector> events{std::move(event)}; while (not events.empty()) { for (auto && event : events) { std::vector> work; work.swap(threads_); std::sort(work.begin(), work.end(), [](auto const& a, auto const& b) { return a->priority() < b->priority(); }); std::size_t const n = work.size(); for (std::size_t i = 0; i < n; i++) { auto const [thread_outcome, msg_outcome] = work[i]->on_event(*event); if (thread_outcome == ThreadOutcome::Continue) { threads_.push_back(std::move(work[i])); } if (msg_outcome == EventOutcome::Consume) { std::move(work.begin() + i + 1, work.end(), std::back_inserter(threads_)); break; } } } events = std::move(events_); events_.clear(); } dispatching_ = false; }