[gstreamermm] Gst::MiniObject: added a wrappers for the rest of nonexisting methods.



commit df45fb6b3046a66c4c78aafd044a87e393bccc94
Author: Marcin Kolny <marcin kolny gmail com>
Date:   Wed Oct 1 01:30:07 2014 +0200

    Gst::MiniObject: added a wrappers for the rest of nonexisting methods.
    
        * gstreamer/src/gst_extra_objects.defs: added extra class definition.
          for GstMiniObject struct.
        * gstreamer/src/miniobject.ccg:
        * gstreamer/src/miniobject.hg: added missing wrappers, also added
          QuarkData class, which should be used as a base class for data
          stored as a qdata.
        * tests/test-miniobject.cc: a few tests added, which check finalize
          notifier.

 gstreamer/src/gst_extra_objects.defs |    5 ++
 gstreamer/src/miniobject.ccg         |   59 ++++++++++++++++++++++++++++-
 gstreamer/src/miniobject.hg          |   61 +++++++++++++++++++++++++++++
 tests/test-miniobject.cc             |   70 ++++++++++++++++++++++++++++------
 4 files changed, 182 insertions(+), 13 deletions(-)
---
diff --git a/gstreamer/src/gst_extra_objects.defs b/gstreamer/src/gst_extra_objects.defs
index 7abacfe..8bd2b60 100644
--- a/gstreamer/src/gst_extra_objects.defs
+++ b/gstreamer/src/gst_extra_objects.defs
@@ -28,6 +28,11 @@
   (c-name "GstIterator")
 )
 
+(define-object MiniObject
+  (in-module "Gst")
+  (c-name "GstMiniObject")
+)
+
 (define-object PropertyProbe
   (in-module "Gst")
   (c-name "GstPropertyProbe")
diff --git a/gstreamer/src/miniobject.ccg b/gstreamer/src/miniobject.ccg
index 5692502..929c0a0 100644
--- a/gstreamer/src/miniobject.ccg
+++ b/gstreamer/src/miniobject.ccg
@@ -23,6 +23,8 @@
 namespace Gst
 {
 
+std::map<GstMiniObject*, MiniObject::SlotFinalizer*> MiniObject::finalizers;
+
 MiniObject::~MiniObject()
 {
     GstMiniObject *const gobject_ = reinterpret_cast<GstMiniObject*>(const_cast<MiniObject*>(this));
@@ -30,8 +32,16 @@ MiniObject::~MiniObject()
   // being destroyed as a result of weak reference notification no
   // unreferencing is done and thus no error is issued on unreferencing a mini
   // object with a reference of 0.
-  if(gobject_ && GST_MINI_OBJECT_REFCOUNT_VALUE(gobject_) > 0)
+  if (gobject_ && GST_MINI_OBJECT_REFCOUNT_VALUE(gobject_) > 0)
+  {
     gst_mini_object_unref(gobject_);
+  }
+
+  if (finalizers.find(gobject_) != finalizers.end())
+  {
+    delete finalizers[gobject_];
+    finalizers[gobject_] = NULL;
+  }
 }
 
 Glib::RefPtr<Gst::MiniObject> MiniObject::create_writable()
@@ -65,4 +75,51 @@ Glib::RefPtr<Gst::MiniObject> MiniObject::create_writable()
   }
 }
 
+void MiniObject::set_qdata(GQuark quark, QuarkData *data)
+{
+  gst_mini_object_set_qdata(gobj(), quark, static_cast<gpointer>(data), &MiniObject::destroy_qdata);
+}
+
+void MiniObject::destroy_qdata(gpointer qdata)
+{
+  QuarkData *data = static_cast<QuarkData*>(qdata);
+  delete data;
+}
+
+QuarkData* MiniObject::get_qdata(GQuark quark) const
+{
+  gpointer qdata = gst_mini_object_get_qdata(const_cast<GstMiniObject*>(gobj()), quark);
+  return static_cast<QuarkData*>(qdata);
+}
+
+void MiniObject::add_finalize_notifier(const SlotFinalizer& slot)
+{
+  SlotFinalizer *finalizer = new SlotFinalizer(slot);
+  if (finalizers.find(gobj()) != finalizers.end())
+  {
+    delete finalizers[gobj()];
+    finalizers[gobj()] = finalizer;
+  }
+  else
+  {
+    finalizers.insert(std::make_pair(gobj(), finalizer));
+  }
+  gst_mini_object_weak_ref(gobj(), &MiniObject::MiniObject_Finalizer_gstreamermm_callback, 
static_cast<gpointer>(finalizer));
+}
+
+void MiniObject::MiniObject_Finalizer_gstreamermm_callback(gpointer userdata, GstMiniObject *obj)
+{
+  (*static_cast<SlotFinalizer*>(userdata))();
+}
+
+void MiniObject::remove_finalize_notifier()
+{
+  if (finalizers.find(gobj()) != finalizers.end())
+  {
+    gst_mini_object_weak_unref(gobj(), &MiniObject::MiniObject_Finalizer_gstreamermm_callback, 
finalizers[gobj()]);
+    delete finalizers[gobj()];
+    finalizers[gobj()] = NULL;
+  }
+}
+
 } //namespace Gst
diff --git a/gstreamer/src/miniobject.hg b/gstreamer/src/miniobject.hg
index b10bab4..ef059f3 100644
--- a/gstreamer/src/miniobject.hg
+++ b/gstreamer/src/miniobject.hg
@@ -19,6 +19,7 @@
 
 #include <gst/gst.h>
 #include <glibmm/value.h>
+#include <sigc++/sigc++.h>
 
 _DEFS(gstreamermm,gst)
 
@@ -28,6 +29,14 @@ namespace Gst
 _WRAP_ENUM(MiniObjectFlags, GstMiniObjectFlags)
 _WRAP_ENUM(LockFlags, GstLockFlags)
 
+/** This is a base class for data which represents qdata.
+ */
+class QuarkData
+{
+public:
+  virtual ~QuarkData(){}
+};
+
 /** This is a base class for some gstreamermm objects.
  * It is similar to Glib::Object but has no GObject property or signal support.
  */
@@ -37,10 +46,16 @@ class MiniObject
   _IGNORE(gst_mini_object_ref, gst_mini_object_unref)
 
 public:
+  typedef sigc::slot< void > SlotFinalizer;
+
   ~MiniObject();
   _MEMBER_GET(flags, flags, guint, guint)
   _MEMBER_SET(flags, flags, guint, guint)
 
+  _MEMBER_GET(refcount, refcount, gint, gint)
+
+  _MEMBER_GET(lockstate, lockstate, gint, gint)
+
   _WRAP_METHOD(bool lock(LockFlags flags), gst_mini_object_lock)
   _WRAP_METHOD(void unlock(LockFlags flags), gst_mini_object_unlock)
   _WRAP_METHOD(bool is_writable() const, gst_mini_object_is_writable)
@@ -56,8 +71,54 @@ public:
    */
   Glib::RefPtr<MiniObject> create_writable();
 
+  /** This sets an opaque, named pointer on a miniobject.
+   * The name is specified through a #GQuark (retrived e.g. via
+   * g_quark_from_static_string()), and the pointer
+   * can be gotten back with get_qdata().
+   * Setting a previously set user data pointer, overrides (frees)
+   * the old pointer set, using NULL as pointer essentially
+   * removes the data stored.
+   * @param quark a GQuark, naming the user data pointer.
+   * @param data an opaque user data pointer.
+   */
+  void set_qdata(GQuark quark, QuarkData *data);
+  _IGNORE(gst_mini_object_set_qdata)
+
+  /** This function gets back user data pointers stored via
+   * set_qdata().
+   * @param quark a GQuark, naming the user data pointer.
+   * @return the user data pointer set, or NULL.
+   */
+  QuarkData* get_qdata(GQuark quark) const;
+  _IGNORE(gst_mini_object_get_qdata)
+
+#m4 _CONVERSION(`gpointer',`QuarkData*',`static_cast<QuarkData*>($3)')
+  _WRAP_METHOD(QuarkData* steal_qdata(GQuark quark), gst_mini_object_steal_qdata)
+
   // Copying a mini object can be achieved by assignment.
   _IGNORE(gst_mini_object_copy)
+
+  /** Adds notifier when mini object is finalized
+   * @param slot notifier.
+   */
+  void add_finalize_notifier(const SlotFinalizer& slot);
+
+  /** Remove finalize notifier
+   */
+  void remove_finalize_notifier();
+
+  _IGNORE(gst_mini_object_weak_ref)
+  _IGNORE(gst_mini_object_weak_unref)
+
+private:
+  // In this class non-static member cannot exists, so there is a map
+  // with key = gobj() and value = handler.
+  static std::map<GstMiniObject*, SlotFinalizer*> finalizers;
+
+  static void destroy_qdata(gpointer qdata);
+
+  static void MiniObject_Finalizer_gstreamermm_callback(gpointer userdata, GstMiniObject *obj);
+
 };
 
 } // namespace Gst
diff --git a/tests/test-miniobject.cc b/tests/test-miniobject.cc
index dca5adb..f6cb05c 100644
--- a/tests/test-miniobject.cc
+++ b/tests/test-miniobject.cc
@@ -13,24 +13,70 @@ using Glib::RefPtr;
 
 TEST(MiniObjectTest, ShouldCorrectCreateWritableObjects)
 {
-       // we cannot create Gst::MiniObject object, so I used Gst::Buffer::create
-       // method to make an object.
-       RefPtr<MiniObject> obj = Buffer::create();
+  // we cannot create Gst::MiniObject object, so I used Gst::Buffer::create
+  // method to make an object.
+  RefPtr<MiniObject> obj = Buffer::create();
 
-       ASSERT_EQ(1, obj->gobj()->refcount);
+  ASSERT_EQ(1, obj->gobj()->refcount);
 
-       obj = obj->create_writable();
+  obj = obj->create_writable();
 
-       ASSERT_EQ(1, obj->gobj()->refcount);
+  ASSERT_EQ(1, obj->gobj()->refcount);
 
-       RefPtr<MiniObject> obj2 = obj;
+  RefPtr<MiniObject> obj2 = obj;
 
-       ASSERT_EQ(2, obj->gobj()->refcount);
-       ASSERT_EQ(2, obj2->gobj()->refcount);
+  ASSERT_EQ(2, obj->gobj()->refcount);
+  ASSERT_EQ(2, obj2->gobj()->refcount);
 
-       obj2 = obj->create_writable();
+  obj2 = obj->create_writable();
 
-       ASSERT_EQ(1, obj->gobj()->refcount);
-       ASSERT_EQ(1, obj2->gobj()->refcount);
+  ASSERT_EQ(1, obj->gobj()->refcount);
+  ASSERT_EQ(1, obj2->gobj()->refcount);
 }
 
+TEST(MiniObjectTest, CheckFinalizeNotifier)
+{
+  int finalize_cnt = 0;
+  {
+    RefPtr<Buffer> obj = Buffer::create();
+    obj->add_finalize_notifier([&finalize_cnt](){
+      finalize_cnt++;
+    });
+  }
+
+  ASSERT_EQ(1, finalize_cnt);
+}
+
+TEST(MiniObjectTest, ShouldCorrectRemoveFinalizeHandler)
+{
+  int finalize_cnt = 0;
+  {
+    RefPtr<Buffer> obj = Buffer::create();
+    obj->add_finalize_notifier([&finalize_cnt](){
+      finalize_cnt++;
+    });
+    obj->remove_finalize_notifier();
+  }
+
+  ASSERT_EQ(0, finalize_cnt);
+}
+
+TEST(MiniObjectTest, AddRemoveFinalizerHandlerCombination)
+{
+  int finalize_cnt = 0;
+  {
+    RefPtr<Buffer> obj = Buffer::create();
+    obj->add_finalize_notifier([&finalize_cnt](){
+      finalize_cnt++;
+    });
+    obj->remove_finalize_notifier();
+    obj->add_finalize_notifier([&finalize_cnt](){
+      finalize_cnt += 17;
+    });
+    obj->add_finalize_notifier([&finalize_cnt](){
+      finalize_cnt += 104;
+    });
+  }
+
+  ASSERT_EQ(104, finalize_cnt);
+}


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