#ifndef D93EB1DD_2BCB_47B7_9361_91841576013D #define D93EB1DD_2BCB_47B7_9361_91841576013D /* ******************************************************************************* * INCLUDE ******************************************************************************* */ #include "MediaType.h" #include #include #include #include #include namespace Video { namespace Core { /* ******************************************************************************* * CLASS DECLARE ******************************************************************************* */ template class Notification: public Poco::Notification { public: Notification(typename T::Ptr pObject): _pObject(pObject) { } public: typename T::Ptr get() { return _pObject; } private: typename T::Ptr _pObject; }; enum class QueueStatus { UNKNOWN = -1, NORMAL, OVERHALF, FULL, }; template class NotificationQueue { public: using Ptr = Poco::SharedPtr>; public: NotificationQueue(const std::string& name, MediaType type, int limit = 300); public: MediaType type() const; void enqueue(typename T::Ptr pObject, bool force = true); typename T::Ptr dequeue(long timeout); void clear(); QueueStatus status(); int size(); private: Poco::NotificationQueue _queue; std::string _name; MediaType _type; int _limit; }; template inline NotificationQueue::NotificationQueue(const std::string& name, MediaType type, int limit) : _name(name), _type(type), _limit(limit) { } template inline MediaType NotificationQueue::type() const { return _type; } template inline void NotificationQueue::enqueue(typename T::Ptr pObject, bool force) { if (_queue.size() >= _limit) { if (!force) throw std::overflow_error("Queue overflow!"); std::cout << "NotificationQueue(" + _name + "[" << (type() == MediaType::VIDEO ? "Video" : "Audio") << "]): OVERFLOW!" << std::endl; _queue.dequeueNotification()->release(); } _queue.enqueueNotification(new Notification(pObject)); } template inline typename T::Ptr NotificationQueue::dequeue(long timeout) { Poco::Notification::Ptr p = _queue.waitDequeueNotification(timeout); if (!p) throw Poco::TimeoutException("Dequeue timeout: " + std::string(type() == MediaType::VIDEO ? "Video" : "Audio")); return p.cast>()->get(); } template inline void NotificationQueue::clear() { _queue.clear(); } template inline QueueStatus NotificationQueue::status() { QueueStatus s = QueueStatus::NORMAL; const auto size = _queue.size(); if (size >= _limit) s = QueueStatus::FULL; else if (size >= (_limit >> 1)) s = QueueStatus::OVERHALF; return s; } template inline int NotificationQueue::size() { return _queue.size(); } } } #endif