#pragma once #include "threaded_container.hpp" #include "../std/queue.hpp" template class ThreadedPriorityQueue : public ThreadedContainer { private: priority_queue m_queue; public: template void ProcessQueue(Fn const & fn) { threads::ConditionGuard g(m_Cond); bool hadElements = !m_queue.empty(); fn(m_queue); bool hasElements = !m_queue.empty(); if (!hadElements && hasElements) m_Cond.Signal(); } void Push(T const & t) { threads::ConditionGuard g(m_Cond); bool doSignal = m_queue.empty(); m_queue.push(t); if (doSignal) m_Cond.Signal(); } bool WaitNonEmpty() { double StartWaitTime = m_Timer.ElapsedSeconds(); while (m_queue.empty()) { if (IsCancelled()) break; m_Cond.Wait(); } m_WaitTime += m_Timer.ElapsedSeconds() - StartWaitTime; if (IsCancelled()) return true; return false; } T Top(bool doPop) { threads::ConditionGuard g(m_Cond); if (WaitNonEmpty()) return T(); T res = m_queue.top(); if (doPop) m_queue.pop(); return res; } bool Empty() const { threads::ConditionGuard g(m_Cond); return m_queue.empty(); } void Clear() { threads::ConditionGuard g(m_Cond); while (!m_queue.empty()) m_queue.pop(); } };