[gstreamermm] Gst::AtomicQueue: wrapped GstAtomicQueue module.



commit 8da29bd740fdd02e163d84535a15d76f6b373839
Author: Marcin Kolny <marcin kolny gmail com>
Date:   Fri Aug 8 10:41:37 2014 +0200

    Gst::AtomicQueue: wrapped GstAtomicQueue module.
    
    Gst::AtomicQueue is template class. It helps with control queue types.
    For exactly the same behavior as GstAtomicQueue, gpointer as template
    type might be used.
    
        * .gitignore: added atomicqueue test executable file to
        ignore list
        * gstreamer/gstreamermm.h: atomicqueue header to a core includes
        * gstreamer/gstreamermm/atomicqueue.h: atomicqueue wrapper. This
        file isn't autogenerated, because Gst::AtomicQueue is template
        class.
        * gstreamer/gstreamermm/filelist.am: atomicqueue header as an
        extra header.
        * tests/Makefile.am:
        * tests/test-automaticqueue.cc: added a few tests for
        Gst::AtomicQueue class.

 .gitignore                          |    1 +
 gstreamer/gstreamermm.h             |    1 +
 gstreamer/gstreamermm/atomicqueue.h |  187 +++++++++++++++++++++++++++++++++++
 gstreamer/gstreamermm/filelist.am   |    1 +
 tests/Makefile.am                   |    3 +-
 tests/test-atomicqueue.cc           |   61 +++++++++++
 6 files changed, 253 insertions(+), 1 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index f8b65eb..fba784a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -477,6 +477,7 @@ gstreamer/src/xvimagesink.hg
 
 #tests/
 tests/test-allocator
+tests/test-atomicqueue
 tests/test-buffer
 tests/test-bus
 tests/test-caps
diff --git a/gstreamer/gstreamermm.h b/gstreamer/gstreamermm.h
index 96d3cf9..009894c 100644
--- a/gstreamer/gstreamermm.h
+++ b/gstreamer/gstreamermm.h
@@ -65,6 +65,7 @@
 
 // Core includes
 #include <gstreamermm/allocator.h>
+#include <gstreamermm/atomicqueue.h>
 #include <gstreamermm/bin.h>
 #include <gstreamermm/buffer.h>
 #include <gstreamermm/bufferlist.h>
diff --git a/gstreamer/gstreamermm/atomicqueue.h b/gstreamer/gstreamermm/atomicqueue.h
new file mode 100644
index 0000000..e9b168b
--- /dev/null
+++ b/gstreamer/gstreamermm/atomicqueue.h
@@ -0,0 +1,187 @@
+/* gstreamermm - a C++ wrapper for gstreamer
+ *
+ * Copyright 2014 The gstreamermm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _GSTREAMERMM_ATOMICQUEUE_H
+#define _GSTREAMERMM_ATOMICQUEUE_H
+
+#include <glibmm/refptr.h>
+#include <gstreamermm/handle_error.h>
+#include <gst/gstatomicqueue.h>
+
+namespace Gst
+{
+
+/**
+ * The Gst::AtomicQueue object implements a queue that can be used from multiple
+ * threads without performing any blocking operations.
+ */
+template <typename T>
+class AtomicQueue
+{
+  public:
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  typedef AtomicQueue CppObjectType;
+  typedef GstAtomicQueue BaseObjectType;
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+
+  /** Increment the reference count for this object.
+   * You should never need to do this manually - use the object via a RefPtr instead.
+   */
+  void reference()   const
+  {
+    // See the comment at the top of this file, if you want to know why the cast works.
+    gst_atomic_queue_ref(reinterpret_cast<GstAtomicQueue*>(const_cast<AtomicQueue<T>*>(this)));
+  }
+
+  /** Decrement the reference count for this object.
+   * You should never need to do this manually - use the object via a RefPtr instead.
+   */
+  void unreference() const
+  {
+    // See the comment at the top of this file, if you want to know why the cast works.
+    gst_atomic_queue_unref(reinterpret_cast<GstAtomicQueue*>(const_cast<AtomicQueue<T>*>(this)));
+  }
+
+  ///Provides access to the underlying C instance.
+  const GstAtomicQueue* gobj() const
+  {
+    // See the comment at the top of this file, if you want to know why the cast works.
+    return reinterpret_cast<const GstAtomicQueue*>(this);
+  }
+
+  ///Provides access to the underlying C instance.
+  GstAtomicQueue*       gobj()
+  {
+    // See the comment at the top of this file, if you want to know why the cast works.
+    return reinterpret_cast<GstAtomicQueue*>(this);
+  }
+
+  ///Provides access to the underlying C instance. The caller is responsible for unrefing it. Use when 
directly setting fields in structs.
+  GstAtomicQueue* gobj_copy() const
+  {
+    // See the comment at the top of this file, if you want to know why the cast works.
+    GstAtomicQueue *const gobject = reinterpret_cast<GstAtomicQueue*>(const_cast<AtomicQueue<T>*>(this));
+    gst_atomic_queue_ref(gobject);
+    return gobject;
+  }
+
+  static Glib::RefPtr<Gst::AtomicQueue<T> > create(guint initial_size)
+  {
+    // See the comment at the top of this file, if you want to know why the cast works.
+    return Glib::RefPtr<AtomicQueue<T> 
(reinterpret_cast<AtomicQueue<T>*>(gst_atomic_queue_new(initial_size)));
+  }
+
+protected:
+  // Do not derive this.  Gst::AtomicQueue can neither be constructed nor deleted.
+  AtomicQueue();
+  void operator delete(void*, std::size_t);
+
+private:
+  // noncopyable
+  AtomicQueue(const AtomicQueue&);
+  AtomicQueue& operator=(const AtomicQueue&);
+
+
+public:
+  
+  /** Get the amount of items in the queue.
+   * @return The number of elements in the queue.
+   */
+  guint length()
+  {
+    return gst_atomic_queue_length(gobj());
+  }
+
+  /** Get the amount of items in the queue.
+   * @return The number of elements in the queue.
+   */
+  guint length() const
+  {
+         return const_cast<AtomicQueue*>(this)->length();
+  }
+
+  /** Append @a data to the tail of the queue.
+   * @param data The data.
+   */
+  void push(const T& data)
+  {
+    T* tmp = new T(data);
+    gst_atomic_queue_push(gobj(), tmp);
+  }
+  
+  /** Peek the head element of the queue without removing it from the queue.
+   * @return The head element of queue.
+   *
+   * @throws std::runtime_error if the queue is empty.
+   */
+  T peek()
+  {
+    gpointer val = gst_atomic_queue_peek(gobj());
+    if (val == 0)
+      gstreamermm_handle_error("Queue is empty");
+    T v = *(T*)val;
+    return v;
+  }
+  
+  /** Get the head element of the queue.
+   * @return The head element of queue.
+   *
+   * @throws std::runtime_error if the queue is empty.
+   */
+  T pop()
+  {
+    gpointer val = gst_atomic_queue_pop(gobj());
+    if (val == 0)
+      gstreamermm_handle_error("Queue is empty");
+    T v = *(T*)val;
+    delete (T*)val;
+    return v;
+  }
+
+};
+
+} // namespace Gst
+
+
+namespace Glib
+{
+
+  /** A Glib::wrap() method for this object.
+   * 
+   * @param object The C instance.
+   * @param take_copy False if the result should take ownership of the C instance. True if it should take a 
new copy or ref.
+   * @result A C++ instance that wraps this C instance.
+   *
+   * @relates Gst::AtomicQueue
+   */
+  template <typename T>
+  Glib::RefPtr<Gst::AtomicQueue<T> > wrap(GstAtomicQueue* object, bool take_copy = false)
+  {
+    if(take_copy && object)
+      gst_atomic_queue_ref(object);
+    // See the comment at the top of this file, if you want to know why the cast works.
+    return Glib::RefPtr<Gst::AtomicQueue<T> >(reinterpret_cast<Gst::AtomicQueue<T>*>(object));
+  }
+
+} // namespace Glib
+
+
+#endif /* _GSTREAMERMM_ATOMICQUEUE_H */
+
diff --git a/gstreamer/gstreamermm/filelist.am b/gstreamer/gstreamermm/filelist.am
index ca9635a..16b6773 100644
--- a/gstreamer/gstreamermm/filelist.am
+++ b/gstreamer/gstreamermm/filelist.am
@@ -9,6 +9,7 @@ files_extra_cc =                \
         handle_error.cc         \
         version.cc
 files_extra_h  =                \
+        atomicqueue.h           \
         check.h                 \
         init.h                  \
         handle_error.h          \
diff --git a/tests/Makefile.am b/tests/Makefile.am
index de76e0f..62b7d05 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -21,7 +21,7 @@ AM_CXXFLAGS = $(GSTREAMERMM_WXXFLAGS) -g
 LDADD = $(GSTREAMERMM_LIBS) $(local_libgstreamermm) -lgtest -lpthread
 
 check_PROGRAMS = test-caps test-buffer test-bus test-caps test-pad \
-                 test-allocator \
+                 test-allocator test-atomicqueue \
                  test-urihandler test-ghostpad test-init \
                  test-query test-structure test-taglist test-plugin-appsink \
                  test-plugin-appsrc test-plugin-register test-plugin-pushsrc \
@@ -35,6 +35,7 @@ TEST_MAIN_SOURCE = main.cc
 TEST_REGRESSION_UTILS = regression/utils.cc
 
 test_allocator_SOURCES         = test-allocator.cc $(TEST_MAIN_SOURCE)
+test_atomicqueue_SOURCES       = test-atomicqueue.cc $(TEST_MAIN_SOURCE)
 test_caps_SOURCES                      = test-caps.cc $(TEST_MAIN_SOURCE)
 test_buffer_SOURCES                    = test-buffer.cc $(TEST_MAIN_SOURCE)
 test_bus_SOURCES                       = test-bus.cc $(TEST_MAIN_SOURCE)
diff --git a/tests/test-atomicqueue.cc b/tests/test-atomicqueue.cc
new file mode 100644
index 0000000..789cfa0
--- /dev/null
+++ b/tests/test-atomicqueue.cc
@@ -0,0 +1,61 @@
+/*
+ * test-atomicqueue.cc
+ *
+ *  Created on: Aug 7, 2014
+ *      Author: loganek
+ */
+
+#include <gtest/gtest.h>
+#include <gstreamermm.h>
+#include <string>
+
+using namespace Gst;
+using Glib::RefPtr;
+
+TEST(AtomicQueueTest, ShouldReturnFirstElementInQueueAndNotRemoveIt)
+{
+       RefPtr<AtomicQueue<int> > queue = AtomicQueue<int>::create(2);
+       queue->push(12);
+       queue->push(5);
+       queue->push(9);
+
+       ASSERT_EQ(12, queue->peek());
+       ASSERT_EQ(3, queue->length());
+}
+
+TEST(AtomicQueueTest, ShouldThrowExceptionOnPeekIfQueueIsEmpty)
+{
+       RefPtr<AtomicQueue<int> > queue = AtomicQueue<int>::create(2);
+
+       EXPECT_THROW(queue->peek(), std::runtime_error);
+}
+
+TEST(AtomicQueueTest, ShouldReturnFirstElementAndRemoveIt)
+{
+       RefPtr<AtomicQueue<int> > queue = AtomicQueue<int>::create(2);
+       queue->push(7);
+       queue->push(14);
+       queue->push(10);
+
+       ASSERT_EQ(7, queue->pop());
+       ASSERT_EQ(2, queue->length());
+}
+
+TEST(AtomicQueueTest, ShouldImitateGstAtomicQueueStructByGpointerAsTemplate)
+{
+       RefPtr<AtomicQueue<gpointer> > queue = AtomicQueue<gpointer>::create(2);
+       int* data = new int(5);
+       GstElement* element = gst_element_factory_make("fakesrc", "dummy-name");
+       queue->push(data);
+       queue->push(element);
+
+       int* new_data = static_cast<int*>(queue->pop());
+       GstElement* new_element = static_cast<GstElement*>(queue->pop());
+       ASSERT_EQ(*new_data, *data);
+       ASSERT_TRUE(GST_IS_ELEMENT(element));
+       ASSERT_EQ(new_element, element);
+       EXPECT_STREQ("dummy-name", gst_element_get_name(new_element));
+       delete new_data;
+       ASSERT_EQ(1, GST_OBJECT_REFCOUNT(element));
+       gst_object_unref(element);
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]