[gstreamermm] Gst::AtomicQueue: wrapped GstAtomicQueue module.
- From: Marcin Kolny <mkolny src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gstreamermm] Gst::AtomicQueue: wrapped GstAtomicQueue module.
- Date: Tue, 19 Aug 2014 16:53:51 +0000 (UTC)
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]