[vte] lib: Add RefPtr type for holding a GObject



commit d282b59690df3edf164274a082792d4b1a87bae6
Author: Christian Persch <chpe src gnome org>
Date:   Mon Apr 23 20:51:18 2018 +0200

    lib: Add RefPtr type for holding a GObject

 src/Makefile.am    |   19 +++++++-
 src/refptr-test.cc |  135 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/refptr.hh      |   38 +++++++++++++++
 src/vteinternal.hh |    1 +
 src/vtetypes.hh    |    1 +
 5 files changed, 193 insertions(+), 1 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 39ce8c8..7c13a5e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -76,6 +76,7 @@ libvte_@VTE_API_MAJOR_VERSION@_@VTE_API_MINOR_VERSION@_la_SOURCES = \
        pty.cc \
        reaper.cc \
        reaper.hh \
+       refptr.hh \
        ring.cc \
        ring.hh \
        vte.cc \
@@ -186,7 +187,7 @@ vteresources.cc: vte.gresource.xml Makefile $(shell $(GLIB_COMPILE_RESOURCES) --
 
 # Misc unit tests and utilities
 
-noinst_PROGRAMS += parser-cat slowcat test-modes test-tabstops test-parser
+noinst_PROGRAMS += parser-cat slowcat test-modes test-tabstops test-parser test-refptr
 noinst_SCRIPTS = decset osc window
 EXTRA_DIST += $(noinst_SCRIPTS)
 
@@ -209,6 +210,7 @@ dist_check_SCRIPTS = \
 TESTS = \
        test-modes \
        test-parser \
+       test-refptr \
        test-tabstops \
        reaper \
        test-vtetypes \
@@ -350,6 +352,21 @@ test_tabstops_LDADD = \
        $(GLIB_LIBS) \
        $(NULL)
 
+test_refptr_SOURCES = \
+       refptr.hh \
+       refptr-test.cc \
+       $(NULL)
+test_refptr_CPPFLAGS = \
+       -I$(builddir) \
+       -I$(srcdir) \
+       $(AM_CPPFLAGS)
+test_refptr_CXXFLAGS = \
+       $(GOBJECT_CFLAGS) \
+       $(AM_CXXFLAGS)
+test_refptr_LDADD = \
+       $(GOBJECT_LIBS) \
+       $(NULL)
+
 test_vtetypes_SOURCES = \
        vtetypes.cc \
        vtetypes.hh \
diff --git a/src/refptr-test.cc b/src/refptr-test.cc
new file mode 100644
index 0000000..41e4b6e
--- /dev/null
+++ b/src/refptr-test.cc
@@ -0,0 +1,135 @@
+/*
+ * Copyright © 2018 Christian Persch
+ *
+ * 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 3 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 General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "refptr.hh"
+
+/* Test object */
+
+typedef struct _TestObject      TestObject;
+typedef struct _TestObjectClass TestObjectClass;
+
+struct _TestObject {
+        GObject parent_instance;
+};
+
+struct _TestObjectClass{
+        GObjectClass parent_class;
+};
+
+static GType test_object_get_type(void);
+
+G_DEFINE_TYPE(TestObject, test_object, G_TYPE_OBJECT)
+
+static void
+test_object_init(TestObject* object)
+{
+}
+
+static void
+test_object_finalize(GObject *object)
+{
+        G_OBJECT_CLASS(test_object_parent_class)->finalize(object);
+}
+
+static void
+test_object_class_init(TestObjectClass* klass)
+{
+        GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
+        gobject_class->finalize = test_object_finalize;
+}
+
+static TestObject*
+test_object_new(void)
+{
+        return reinterpret_cast<TestObject*>(g_object_new(test_object_get_type(),
+                                                          nullptr));
+}
+
+/* Tests */
+
+typedef union {
+        TestObject* obj;
+        void* ptr;
+} obj_t;
+
+static void
+test_glib_refptr(void)
+{
+        obj_t obj1;
+        obj1.obj = test_object_new();
+        g_object_add_weak_pointer(G_OBJECT(obj1.obj), &obj1.ptr);
+        vte::glib::RefPtr<TestObject> ptr1 = obj1.obj;
+        g_assert_true(ptr1.get() == obj1.obj);
+
+        auto ptr2 = std::move(ptr1);
+        g_assert_true(ptr1.get() == nullptr);
+        g_assert_true(ptr2.get() == obj1.obj);
+
+        obj_t obj2;
+        obj2.obj = test_object_new();
+        g_object_add_weak_pointer(G_OBJECT(obj2.obj), &obj2.ptr);
+        g_assert_nonnull(obj2.ptr);
+        ptr2 = obj2.obj;
+        g_assert_null(obj1.ptr);
+        g_assert_true(ptr2.get() == obj2.obj);
+        g_assert_nonnull(obj2.ptr);
+
+        ptr2 = nullptr;
+        g_assert_null(obj2.ptr);
+
+        obj_t obj3;
+        obj3.obj = test_object_new();
+        g_object_add_weak_pointer(G_OBJECT(obj3.obj), &obj3.ptr);
+        g_assert_nonnull(obj3.ptr);
+        vte::glib::RefPtr<TestObject> ptr3 = obj3.obj;
+        TestObject* obj4 = ptr3.release();
+        g_assert_null(ptr3.get());
+        g_assert_nonnull(obj4);
+        g_object_unref(obj4);
+        g_assert_null(obj3.ptr);
+
+        obj_t obj5;
+        obj5.obj = test_object_new();
+        g_object_add_weak_pointer(G_OBJECT(obj5.obj), &obj5.ptr);
+        g_assert_nonnull(obj5.ptr);
+        vte::glib::RefPtr<TestObject> ptr5{obj5.obj};
+
+        obj_t obj6;
+        obj6.obj = test_object_new();
+        g_object_add_weak_pointer(G_OBJECT(obj6.obj), &obj6.ptr);
+        g_assert_nonnull(obj6.ptr);
+
+        ptr5.reset(obj6.obj);
+        g_assert_null(obj5.ptr);
+
+        ptr5.reset();
+        g_assert_null(obj6.ptr);
+        g_assert_null(ptr5.get());
+}
+
+int
+main(int argc,
+     char* argv[])
+{
+        g_test_init(&argc, &argv, nullptr);
+
+        g_test_add_func("/vte/glib/refptr", test_glib_refptr);
+
+        return g_test_run();
+}
diff --git a/src/refptr.hh b/src/refptr.hh
new file mode 100644
index 0000000..ae7a96d
--- /dev/null
+++ b/src/refptr.hh
@@ -0,0 +1,38 @@
+/*
+ * Copyright © 2018 Christian Persch
+ *
+ * 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 3 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 General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <memory>
+#include <glib-object.h>
+
+namespace vte {
+
+namespace glib {
+
+template <typename T>
+class RefPtr : public std::unique_ptr<T, decltype(&g_object_unref)>
+{
+private:
+        using base_type = std::unique_ptr<T, decltype(&g_object_unref)>;
+
+public:
+        RefPtr(T* obj = nullptr) : base_type{obj, &g_object_unref} { }
+};
+
+} // namespace glib
+} // namespace vte
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 548edb0..a2c525a 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -30,6 +30,7 @@
 #include "parser-glue.hh"
 #include "modes.hh"
 #include "tabstops.hh"
+#include "refptr.hh"
 
 #include "vtepcre2.h"
 #include "vteregexinternal.hh"
diff --git a/src/vtetypes.hh b/src/vtetypes.hh
index 885c2fb..54d9f42 100644
--- a/src/vtetypes.hh
+++ b/src/vtetypes.hh
@@ -22,6 +22,7 @@
 #include <errno.h>
 
 #include <cstdint>
+#include <memory>
 
 #ifdef VTE_DEBUG
 #define IFDEF_DEBUG(str) str


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