xbot/thread.cpp

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;
}