#include <psemek/async/event_loop.hpp>

namespace psemek::async
{

	void event_loop::post(task t)
	{
		queue_.push(std::move(t));
	}

	void event_loop::post_at(clock::time_point time, task t)
	{
		queue_.push_at(time, std::move(t));
	}

	void event_loop::stop()
	{
		queue_.clear();
	}

	void event_loop::clear()
	{
		queue_.clear();
	}

	void event_loop::wait()
	{
		while (!queue_.empty())
		{
			auto t = queue_.pop();
			t();
		}
	}

	void event_loop::wait_for(clock::duration period)
	{
		wait_until(clock::now() + period);
	}

	void event_loop::wait_until(clock::time_point time)
	{
		while (!queue_.empty() && clock::now() < time)
		{
			auto t = queue_.try_pop_until(time);
			if (!t) break;
			(*t)();
		}
	}

	std::size_t event_loop::task_count() const
	{
		return queue_.size();
	}

	std::size_t event_loop::pump(std::optional<std::size_t> max_events)
	{
		std::size_t events = 0;
		while (!max_events || events < *max_events)
		{
			auto t = queue_.try_pop();
			if (!t) break;
			(*t)();
			++events;
		}
		return events;
	}

}
