summaryrefslogtreecommitdiff
path: root/gir
diff options
context:
space:
mode:
authorJohan Dahlin <johan@gnome.org>2010-06-12 18:08:56 -0300
committerJohan Dahlin <johan@gnome.org>2010-07-09 10:15:45 -0300
commit1e9822c7817062a9b853269b9418fd78782090b5 (patch)
tree684a6bc8520db45c9d126d954d7b82921cb2a753 /gir
parent017727630d09a854b1c1a4767066fb675b139de9 (diff)
downloadgobject-introspection-1e9822c7817062a9b853269b9418fd78782090b5.tar.gz
Add support for non-GObject fundamental objects
This patch adds support for instantiable fundamental object types, which are not GObject based. This is mostly interesting for being able to support GstMiniObject's which are extensivly used in GStreamer. Includes a big test case to the Everything module (inspired by GstMiniObject) which should be used by language bindings who wishes to test this functionallity. This patch increases the size of the typelib and breaks compatibility with older typelibs. https://bugzilla.gnome.org/show_bug.cgi?id=568913
Diffstat (limited to 'gir')
-rw-r--r--gir/Everything-1.0-expected.gir101
-rw-r--r--gir/everything.c293
-rw-r--r--gir/everything.h55
3 files changed, 449 insertions, 0 deletions
diff --git a/gir/Everything-1.0-expected.gir b/gir/Everything-1.0-expected.gir
index 7fe9d1dc..4d3d2630 100644
--- a/gir/Everything-1.0-expected.gir
+++ b/gir/Everything-1.0-expected.gir
@@ -161,6 +161,107 @@ and/or use gtk-doc annotations. -->
c:type="GInitiallyUnownedClass"/>
</field>
</record>
+ <class name="TestFundamentalObject"
+ c:type="TestFundamentalObject"
+ abstract="1"
+ glib:type-name="TestFundamentalObject"
+ glib:get-type="test_fundamental_object_get_type"
+ glib:type-struct="TestFundamentalObjectClass"
+ glib:fundamental="1"
+ glib:ref-func="test_fundamental_object_ref"
+ glib:unref-func="test_fundamental_object_unref"
+ glib:set-value-func="test_value_set_fundamental_object"
+ glib:get-value-func="test_value_get_fundamental_object">
+ <method name="ref" c:identifier="test_fundamental_object_ref">
+ <return-value transfer-ownership="full">
+ <type name="TestFundamentalObject" c:type="TestFundamentalObject*"/>
+ </return-value>
+ </method>
+ <method name="unref" c:identifier="test_fundamental_object_unref">
+ <return-value transfer-ownership="none">
+ <type name="none" c:type="void"/>
+ </return-value>
+ </method>
+ <field name="instance">
+ <type name="GObject.TypeInstance" c:type="GTypeInstance"/>
+ </field>
+ <field name="refcount">
+ <type name="int" c:type="gint"/>
+ </field>
+ <field name="flags">
+ <type name="uint" c:type="guint"/>
+ </field>
+ </class>
+ <record name="TestFundamentalObjectClass"
+ c:type="TestFundamentalObjectClass"
+ glib:is-gtype-struct-for="TestFundamentalObject">
+ <field name="type_class">
+ <type name="GObject.TypeClass" c:type="GTypeClass"/>
+ </field>
+ <field name="copy">
+ <type name="TestFundamentalObjectCopyFunction"
+ c:type="TestFundamentalObjectCopyFunction"/>
+ </field>
+ <field name="finalize">
+ <type name="TestFundamentalObjectFinalizeFunction"
+ c:type="TestFundamentalObjectFinalizeFunction"/>
+ </field>
+ </record>
+ <callback name="TestFundamentalObjectCopyFunction"
+ c:type="TestFundamentalObjectCopyFunction">
+ <return-value transfer-ownership="full">
+ <type name="TestFundamentalObject" c:type="TestFundamentalObject*"/>
+ </return-value>
+ <parameters>
+ <parameter name="obj" transfer-ownership="none">
+ <type name="TestFundamentalObject" c:type="TestFundamentalObject*"/>
+ </parameter>
+ </parameters>
+ </callback>
+ <callback name="TestFundamentalObjectFinalizeFunction"
+ c:type="TestFundamentalObjectFinalizeFunction">
+ <return-value transfer-ownership="none">
+ <type name="none" c:type="void"/>
+ </return-value>
+ <parameters>
+ <parameter name="obj" transfer-ownership="none">
+ <type name="TestFundamentalObject" c:type="TestFundamentalObject*"/>
+ </parameter>
+ </parameters>
+ </callback>
+ <class name="TestFundamentalSubObject"
+ c:type="TestFundamentalSubObject"
+ parent="TestFundamentalObject"
+ glib:type-name="TestFundamentalSubObject"
+ glib:get-type="test_fundamental_sub_object_get_type"
+ glib:type-struct="TestFundamentalSubObjectClass"
+ glib:fundamental="1">
+ <constructor name="new" c:identifier="test_fundamental_sub_object_new">
+ <return-value transfer-ownership="full">
+ <type name="TestFundamentalSubObject"
+ c:type="TestFundamentalSubObject*"/>
+ </return-value>
+ <parameters>
+ <parameter name="data" transfer-ownership="none">
+ <type name="utf8" c:type="char*"/>
+ </parameter>
+ </parameters>
+ </constructor>
+ <field name="fundamental_object">
+ <type name="TestFundamentalObject" c:type="TestFundamentalObject"/>
+ </field>
+ <field name="data">
+ <type name="utf8" c:type="char*"/>
+ </field>
+ </class>
+ <record name="TestFundamentalSubObjectClass"
+ c:type="TestFundamentalSubObjectClass"
+ glib:is-gtype-struct-for="TestFundamentalSubObject">
+ <field name="fundamental_object_class">
+ <type name="TestFundamentalObjectClass"
+ c:type="TestFundamentalObjectClass"/>
+ </field>
+ </record>
<interface name="TestInterface"
c:type="EverythingTestInterface"
glib:type-name="EverythingTestInterface"
diff --git a/gir/everything.c b/gir/everything.c
index 2219667f..a2b4ef6c 100644
--- a/gir/everything.c
+++ b/gir/everything.c
@@ -1,5 +1,8 @@
#include <string.h>
#include <stdlib.h>
+#include <glib-object.h>
+#include <gobject/gvaluecollector.h>
+
#include "everything.h"
static gboolean abort_on_error = TRUE;
@@ -1896,6 +1899,296 @@ test_sub_obj_unset_bare (TestSubObj *obj)
test_obj_set_bare(TEST_OBJECT(obj), NULL);
}
+/* TestFundamental */
+
+TestFundamentalObject *
+test_fundamental_object_ref (TestFundamentalObject * fundamental_object)
+{
+ g_return_val_if_fail (fundamental_object != NULL, NULL);
+ g_atomic_int_inc (&fundamental_object->refcount);
+
+ return fundamental_object;
+}
+
+static void
+test_fundamental_object_free (TestFundamentalObject * fundamental_object)
+{
+ TestFundamentalObjectClass *mo_class;
+ test_fundamental_object_ref (fundamental_object);
+
+ mo_class = TEST_FUNDAMENTAL_OBJECT_GET_CLASS (fundamental_object);
+ mo_class->finalize (fundamental_object);
+
+ if (G_LIKELY (g_atomic_int_dec_and_test (&fundamental_object->refcount))) {
+ g_type_free_instance ((GTypeInstance *) fundamental_object);
+ }
+}
+
+void
+test_fundamental_object_unref (TestFundamentalObject * fundamental_object)
+{
+ g_return_if_fail (fundamental_object != NULL);
+ g_return_if_fail (fundamental_object->refcount > 0);
+
+ if (G_UNLIKELY (g_atomic_int_dec_and_test (&fundamental_object->refcount))) {
+ test_fundamental_object_free (fundamental_object);
+ }
+}
+
+static void
+test_fundamental_object_replace (TestFundamentalObject ** olddata, TestFundamentalObject * newdata)
+{
+ TestFundamentalObject *olddata_val;
+
+ g_return_if_fail (olddata != NULL);
+
+ olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
+
+ if (olddata_val == newdata)
+ return;
+
+ if (newdata)
+ test_fundamental_object_ref (newdata);
+
+ while (!g_atomic_pointer_compare_and_exchange ((gpointer *) olddata,
+ olddata_val, newdata)) {
+ olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
+ }
+
+ if (olddata_val)
+ test_fundamental_object_unref (olddata_val);
+}
+
+static void
+test_value_fundamental_object_init (GValue * value)
+{
+ value->data[0].v_pointer = NULL;
+}
+
+static void
+test_value_fundamental_object_free (GValue * value)
+{
+ if (value->data[0].v_pointer) {
+ test_fundamental_object_unref (TEST_FUNDAMENTAL_OBJECT_CAST (value->data[0].v_pointer));
+ }
+}
+
+static void
+test_value_fundamental_object_copy (const GValue * src_value, GValue * dest_value)
+{
+ if (src_value->data[0].v_pointer) {
+ dest_value->data[0].v_pointer =
+ test_fundamental_object_ref (TEST_FUNDAMENTAL_OBJECT_CAST (src_value->data[0].
+ v_pointer));
+ } else {
+ dest_value->data[0].v_pointer = NULL;
+ }
+}
+
+static gpointer
+test_value_fundamental_object_peek_pointer (const GValue * value)
+{
+ return value->data[0].v_pointer;
+}
+
+static gchar *
+test_value_fundamental_object_collect (GValue * value,
+ guint n_collect_values,
+ GTypeCValue * collect_values,
+ guint collect_flags)
+{
+ if (collect_values[0].v_pointer) {
+ value->data[0].v_pointer =
+ test_fundamental_object_ref (collect_values[0].v_pointer);
+ } else {
+ value->data[0].v_pointer = NULL;
+ }
+
+ return NULL;
+}
+
+static gchar *
+test_value_fundamental_object_lcopy (const GValue * value,
+ guint n_collect_values,
+ GTypeCValue * collect_values,
+ guint collect_flags)
+{
+ gpointer *fundamental_object_p = collect_values[0].v_pointer;
+
+ if (!fundamental_object_p) {
+ return g_strdup_printf ("value location for '%s' passed as NULL",
+ G_VALUE_TYPE_NAME (value));
+ }
+
+ if (!value->data[0].v_pointer)
+ *fundamental_object_p = NULL;
+ else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
+ *fundamental_object_p = value->data[0].v_pointer;
+ else
+ *fundamental_object_p = test_fundamental_object_ref (value->data[0].v_pointer);
+
+ return NULL;
+}
+
+static void
+test_fundamental_object_finalize (TestFundamentalObject * obj)
+{
+
+}
+
+static TestFundamentalObject *
+test_fundamental_object_copy_default (const TestFundamentalObject * obj)
+{
+ g_warning ("TestFundamentalObject classes must implement TestFundamentalObject::copy");
+ return NULL;
+}
+
+static void
+test_fundamental_object_class_init (gpointer g_class, gpointer class_data)
+{
+ TestFundamentalObjectClass *mo_class = TEST_FUNDAMENTAL_OBJECT_CLASS (g_class);
+
+ mo_class->copy = test_fundamental_object_copy_default;
+ mo_class->finalize = test_fundamental_object_finalize;
+}
+
+static void
+test_fundamental_object_init (GTypeInstance * instance, gpointer klass)
+{
+ TestFundamentalObject *fundamental_object = TEST_FUNDAMENTAL_OBJECT_CAST (instance);
+
+ fundamental_object->refcount = 1;
+}
+
+/**
+ * TestFundamentalObject:
+ *
+ * Ref Func: test_fundamental_object_ref
+ * Unref Func: test_fundamental_object_unref
+ * Set Value Func: test_value_set_fundamental_object
+ * Get Value Func: test_value_get_fundamental_object
+ */
+
+GType
+test_fundamental_object_get_type (void)
+{
+ static GType _test_fundamental_object_type = 0;
+
+ if (G_UNLIKELY (_test_fundamental_object_type == 0)) {
+ static const GTypeValueTable value_table = {
+ test_value_fundamental_object_init,
+ test_value_fundamental_object_free,
+ test_value_fundamental_object_copy,
+ test_value_fundamental_object_peek_pointer,
+ (char *) "p",
+ test_value_fundamental_object_collect,
+ (char *) "p",
+ test_value_fundamental_object_lcopy
+ };
+ static const GTypeInfo fundamental_object_info = {
+ sizeof (TestFundamentalObjectClass),
+ NULL, NULL,
+ test_fundamental_object_class_init,
+ NULL,
+ NULL,
+ sizeof (TestFundamentalObject),
+ 0,
+ (GInstanceInitFunc) test_fundamental_object_init,
+ &value_table
+ };
+ static const GTypeFundamentalInfo fundamental_object_fundamental_info = {
+ (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE |
+ G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE)
+ };
+
+ _test_fundamental_object_type = g_type_fundamental_next ();
+ g_type_register_fundamental (_test_fundamental_object_type, "TestFundamentalObject",
+ &fundamental_object_info, &fundamental_object_fundamental_info, G_TYPE_FLAG_ABSTRACT);
+
+ }
+
+ return _test_fundamental_object_type;
+}
+
+/**
+ * test_value_set_fundamental_object: (skip)
+ * @value:
+ * @fundamental_object:
+ */
+void
+test_value_set_fundamental_object (GValue * value, TestFundamentalObject * fundamental_object)
+{
+ gpointer *pointer_p;
+
+ g_return_if_fail (TEST_VALUE_HOLDS_FUNDAMENTAL_OBJECT (value));
+ g_return_if_fail (fundamental_object == NULL || TEST_IS_FUNDAMENTAL_OBJECT (fundamental_object));
+
+ pointer_p = &value->data[0].v_pointer;
+
+ test_fundamental_object_replace ((TestFundamentalObject **) pointer_p, fundamental_object);
+}
+
+/**
+ * test_value_get_fundamental_object: (skip)
+ * @value:
+ */
+TestFundamentalObject *
+test_value_get_fundamental_object (const GValue * value)
+{
+ g_return_val_if_fail (TEST_VALUE_HOLDS_FUNDAMENTAL_OBJECT (value), NULL);
+
+ return value->data[0].v_pointer;
+}
+
+static TestFundamentalObjectClass *parent_class = NULL;
+
+G_DEFINE_TYPE (TestFundamentalSubObject, test_fundamental_sub_object, TEST_TYPE_FUNDAMENTAL_OBJECT);
+
+static TestFundamentalSubObject *
+_test_fundamental_sub_object_copy (TestFundamentalSubObject * fundamental_sub_object)
+{
+ TestFundamentalSubObject *copy;
+
+ copy = test_fundamental_sub_object_new(NULL);
+ copy->data = g_strdup(fundamental_sub_object->data);
+ return copy;
+}
+
+static void
+test_fundamental_sub_object_finalize (TestFundamentalSubObject * fundamental_sub_object)
+{
+ g_return_if_fail (fundamental_sub_object != NULL);
+
+ g_free(fundamental_sub_object->data);
+ test_fundamental_object_unref (TEST_FUNDAMENTAL_OBJECT (fundamental_sub_object));
+}
+
+static void
+test_fundamental_sub_object_class_init (TestFundamentalSubObjectClass * klass)
+{
+ parent_class = g_type_class_peek_parent (klass);
+
+ klass->fundamental_object_class.copy = (TestFundamentalObjectCopyFunction) _test_fundamental_sub_object_copy;
+ klass->fundamental_object_class.finalize =
+ (TestFundamentalObjectFinalizeFunction) test_fundamental_sub_object_finalize;
+}
+
+static void
+test_fundamental_sub_object_init(TestFundamentalSubObject *object)
+{
+
+}
+
+TestFundamentalSubObject *
+test_fundamental_sub_object_new (const char * data)
+{
+ TestFundamentalSubObject *object;
+
+ object = (TestFundamentalSubObject *) g_type_create_instance (test_fundamental_sub_object_get_type());
+ object->data = g_strdup(data);
+ return object;
+}
+
/**
* test_callback:
diff --git a/gir/everything.h b/gir/everything.h
index 8a8b1e0d..55b26cdf 100644
--- a/gir/everything.h
+++ b/gir/everything.h
@@ -334,6 +334,61 @@ TestSubObj* test_sub_obj_new (void);
void test_sub_obj_unset_bare (TestSubObj *obj);
int test_sub_obj_instance_method (TestSubObj *obj);
+/* fundamental object */
+#define TEST_TYPE_FUNDAMENTAL_OBJECT (test_fundamental_object_get_type())
+#define TEST_IS_FUNDAMENTAL_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_FUNDAMENTAL_OBJECT))
+#define TEST_IS_FUNDAMENTAL_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_FUNDAMENTAL_OBJECT))
+#define TEST_FUNDAMENTAL_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_FUNDAMENTAL_OBJECT, TestFundamentalObjectClass))
+#define TEST_FUNDAMENTAL_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_FUNDAMENTAL_OBJECT, TestFundamentalObject))
+#define TEST_FUNDAMENTAL_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_FUNDAMENTAL_OBJECT, TestFundamentalObjectClass))
+#define TEST_FUNDAMENTAL_OBJECT_CAST(obj) ((TestFundamentalObject*)(obj))
+
+typedef struct _TestFundamentalObject TestFundamentalObject;
+typedef struct _TestFundamentalObjectClass TestFundamentalObjectClass;
+typedef TestFundamentalObject * (*TestFundamentalObjectCopyFunction) (const TestFundamentalObject *obj);
+typedef void (*TestFundamentalObjectFinalizeFunction) (TestFundamentalObject *obj);
+
+
+struct _TestFundamentalObject {
+ GTypeInstance instance;
+ gint refcount;
+ guint flags;
+};
+
+struct _TestFundamentalObjectClass {
+ GTypeClass type_class;
+
+ TestFundamentalObjectCopyFunction copy;
+ TestFundamentalObjectFinalizeFunction finalize;
+};
+
+GType test_fundamental_object_get_type (void);
+TestFundamentalObject* test_fundamental_object_ref (TestFundamentalObject *fundamental_object);
+void test_fundamental_object_unref (TestFundamentalObject *fundamental_object);
+
+#define TEST_VALUE_HOLDS_FUNDAMENTAL_OBJECT(value) (G_VALUE_HOLDS(value, TEST_TYPE_FUNDAMENTAL_OBJECT))
+
+void test_value_set_fundamental_object (GValue *value, TestFundamentalObject *fundamental_object);
+TestFundamentalObject* test_value_get_fundamental_object (const GValue *value);
+
+typedef struct _TestFundamentalSubObject TestFundamentalSubObject;
+typedef struct _TestFundamentalSubObjectClass TestFundamentalSubObjectClass;
+
+struct _TestFundamentalSubObject
+{
+ TestFundamentalObject fundamental_object;
+ char *data;
+};
+
+struct _TestFundamentalSubObjectClass {
+ TestFundamentalObjectClass fundamental_object_class;
+};
+
+GType test_fundamental_sub_object_get_type(void);
+
+TestFundamentalSubObject *
+test_fundamental_sub_object_new (const char *data);
+
/* callback */
typedef void (*TestSimpleCallback) (void);
typedef int (*TestCallback) (void);