46 lines
1.3 KiB
C++
46 lines
1.3 KiB
C++
|
#include "thread.hpp"
|
||
|
|
||
|
auto Dispatcher::add_thread(std::shared_ptr<Thread> thread) -> void
|
||
|
{
|
||
|
threads_.push_back(std::move(thread));
|
||
|
}
|
||
|
|
||
|
auto Dispatcher::dispatch(std::shared_ptr<Event> event) -> void
|
||
|
{
|
||
|
if (dispatching_)
|
||
|
{
|
||
|
events_.push_back(std::move(event));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
dispatching_ = true;
|
||
|
std::vector<std::shared_ptr<Event>> events{std::move(event)};
|
||
|
while (not events.empty())
|
||
|
{
|
||
|
for (auto && event : events)
|
||
|
{
|
||
|
std::vector<std::shared_ptr<Thread>> 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;
|
||
|
}
|