1 /* gstreamermm - a C++ wrapper for gstreamer 2 * 3 * Copyright 2014 The gstreamermm Development Team 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free 17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 */ 19 20 #ifndef _GSTREAMERMM_ATOMICQUEUE_H 21 #define _GSTREAMERMM_ATOMICQUEUE_H 22 23 #include <glibmm/refptr.h> 24 #include <gstreamermm/handle_error.h> 25 #include <gst/gstatomicqueue.h> 26 27 namespace Gst 28 { 29 30 /** 31 * The Gst::AtomicQueue object implements a queue that can be used from multiple 32 * threads without performing any blocking operations. 33 */ 34 template <typename T> 35 class AtomicQueue 36 { 37 public: 38 #ifndef DOXYGEN_SHOULD_SKIP_THIS 39 typedef AtomicQueue CppObjectType; 40 typedef GstAtomicQueue BaseObjectType; 41 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 42 43 44 /** Increment the reference count for this object. 45 * You should never need to do this manually - use the object via a RefPtr instead. 46 */ reference()47 void reference() const 48 { 49 // See the comment at the top of this file, if you want to know why the cast works. 50 gst_atomic_queue_ref(reinterpret_cast<GstAtomicQueue*>(const_cast<AtomicQueue<T>*>(this))); 51 } 52 53 /** Decrement the reference count for this object. 54 * You should never need to do this manually - use the object via a RefPtr instead. 55 */ unreference()56 void unreference() const 57 { 58 // See the comment at the top of this file, if you want to know why the cast works. 59 gst_atomic_queue_unref(reinterpret_cast<GstAtomicQueue*>(const_cast<AtomicQueue<T>*>(this))); 60 } 61 62 ///Provides access to the underlying C instance. gobj()63 const GstAtomicQueue* gobj() const 64 { 65 // See the comment at the top of this file, if you want to know why the cast works. 66 return reinterpret_cast<const GstAtomicQueue*>(this); 67 } 68 69 ///Provides access to the underlying C instance. gobj()70 GstAtomicQueue* gobj() 71 { 72 // See the comment at the top of this file, if you want to know why the cast works. 73 return reinterpret_cast<GstAtomicQueue*>(this); 74 } 75 76 ///Provides access to the underlying C instance. The caller is responsible for unrefing it. Use when directly setting fields in structs. gobj_copy()77 GstAtomicQueue* gobj_copy() const 78 { 79 // See the comment at the top of this file, if you want to know why the cast works. 80 GstAtomicQueue *const gobject = reinterpret_cast<GstAtomicQueue*>(const_cast<AtomicQueue<T>*>(this)); 81 gst_atomic_queue_ref(gobject); 82 return gobject; 83 } 84 create(guint initial_size)85 static Glib::RefPtr<Gst::AtomicQueue<T> > create(guint initial_size) 86 { 87 // See the comment at the top of this file, if you want to know why the cast works. 88 return Glib::RefPtr<AtomicQueue<T> >(reinterpret_cast<AtomicQueue<T>*>(gst_atomic_queue_new(initial_size))); 89 } 90 91 protected: 92 // Do not derive this. Gst::AtomicQueue can neither be constructed nor deleted. 93 AtomicQueue(); 94 void operator delete(void*, std::size_t); 95 96 private: 97 // noncopyable 98 AtomicQueue(const AtomicQueue&); 99 AtomicQueue& operator=(const AtomicQueue&); 100 101 102 public: 103 104 /** Get the amount of items in the queue. 105 * @return The number of elements in the queue. 106 */ length()107 guint length() 108 { 109 return gst_atomic_queue_length(gobj()); 110 } 111 112 /** Get the amount of items in the queue. 113 * @return The number of elements in the queue. 114 */ length()115 guint length() const 116 { 117 return const_cast<AtomicQueue*>(this)->length(); 118 } 119 120 /** Append @a data to the tail of the queue. 121 * @param data The data. 122 */ push(const T & data)123 void push(const T& data) 124 { 125 T* tmp = new T(data); 126 gst_atomic_queue_push(gobj(), tmp); 127 } 128 129 /** Peek the head element of the queue without removing it from the queue. 130 * @return The head element of queue. 131 * 132 * @throws std::runtime_error if the queue is empty. 133 */ peek()134 T peek() 135 { 136 gpointer val = gst_atomic_queue_peek(gobj()); 137 if (val == nullptr) 138 gstreamermm_handle_error("Queue is empty"); 139 T v = *(T*)val; 140 return v; 141 } 142 143 /** Get the head element of the queue. 144 * @return The head element of queue. 145 * 146 * @throws std::runtime_error if the queue is empty. 147 */ pop()148 T pop() 149 { 150 gpointer val = gst_atomic_queue_pop(gobj()); 151 if (val == nullptr) 152 gstreamermm_handle_error("Queue is empty"); 153 T v = *(T*)val; 154 delete (T*)val; 155 return v; 156 } 157 158 }; 159 160 } // namespace Gst 161 162 163 namespace Glib 164 { 165 166 /** A Glib::wrap() method for this object. 167 * 168 * @param object The C instance. 169 * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref. 170 * @result A C++ instance that wraps this C instance. 171 * 172 * @relates Gst::AtomicQueue 173 */ 174 template <typename T> 175 Glib::RefPtr<Gst::AtomicQueue<T> > wrap(GstAtomicQueue* object, bool take_copy = false) 176 { 177 if(take_copy && object) 178 gst_atomic_queue_ref(object); 179 // See the comment at the top of this file, if you want to know why the cast works. 180 return Glib::RefPtr<Gst::AtomicQueue<T> >(reinterpret_cast<Gst::AtomicQueue<T>*>(object)); 181 } 182 183 } // namespace Glib 184 185 186 #endif /* _GSTREAMERMM_ATOMICQUEUE_H */ 187 188