85 lines
1.8 KiB
C++
85 lines
1.8 KiB
C++
#include <psemek/async/event_loop.hpp>
|
|
|
|
#include <algorithm>
|
|
|
|
namespace psemek::async
|
|
{
|
|
|
|
auto event_loop::heap_compare()
|
|
{
|
|
return [](deferred_task const & t1, deferred_task const & t2){ return t1.time > t2.time; };
|
|
}
|
|
|
|
void event_loop::post(task t)
|
|
{
|
|
task_queue_.push_back(std::move(t));
|
|
}
|
|
|
|
void event_loop::post_at(clock::time_point time, task t)
|
|
{
|
|
if (time > clock::now())
|
|
{
|
|
deferred_task_heap_.push_back(deferred_task{time, std::move(t)});
|
|
std::push_heap(deferred_task_heap_.begin(), deferred_task_heap_.end(), heap_compare());
|
|
}
|
|
else
|
|
task_queue_.push_back(std::move(t));
|
|
}
|
|
|
|
void event_loop::stop()
|
|
{
|
|
task_queue_.clear();
|
|
deferred_task_heap_.clear();
|
|
}
|
|
|
|
void event_loop::wait()
|
|
{
|
|
while (!task_queue_.empty() || !deferred_task_heap_.empty())
|
|
{
|
|
flush_deferred();
|
|
if (task_queue_.empty())
|
|
{
|
|
std::this_thread::sleep_until(deferred_task_heap_.front().time);
|
|
}
|
|
else
|
|
{
|
|
auto t = std::move(task_queue_.front());
|
|
task_queue_.pop_front();
|
|
t();
|
|
}
|
|
}
|
|
}
|
|
|
|
void event_loop::wait_for(clock::duration period)
|
|
{
|
|
wait_until(clock::now() + period);
|
|
}
|
|
|
|
void event_loop::wait_until(clock::time_point time)
|
|
{
|
|
while ((!task_queue_.empty() || !deferred_task_heap_.empty()) && clock::now() < time)
|
|
{
|
|
flush_deferred();
|
|
auto t = std::move(task_queue_.front());
|
|
task_queue_.pop_front();
|
|
t();
|
|
}
|
|
}
|
|
|
|
std::size_t event_loop::task_count() const
|
|
{
|
|
return task_queue_.size() + deferred_task_heap_.size();
|
|
}
|
|
|
|
void event_loop::flush_deferred()
|
|
{
|
|
auto const now = clock::now();
|
|
while (!deferred_task_heap_.empty() && deferred_task_heap_.front().time <= now)
|
|
{
|
|
task_queue_.push_back(std::move(deferred_task_heap_.front().func));
|
|
std::pop_heap(deferred_task_heap_.begin(), deferred_task_heap_.end(), heap_compare());
|
|
deferred_task_heap_.pop_back();
|
|
}
|
|
}
|
|
|
|
}
|