[glib/test/gobjectnew: 1/3] GType: add accessor for instance private offset



commit c30c0bb34d80013489897c49bef36cc56972d5d9
Author: Ryan Lortie <desrt desrt ca>
Date:   Tue Apr 23 10:38:23 2013 -0400

    GType: add accessor for instance private offset
    
    Since instance private data is now always at a constant offset to the
    instance pointer, we can add an accessor for it that doesn't also
    require an instance.
    
    The idea is that classes can call this from their class_init and store
    it in a file-scoped static variable and use that to find their private
    data on instances very quickly, without a priv pointer.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=698056

 docs/reference/gobject/gobject-sections.txt |    1 +
 gobject/gtype.c                             |   48 +++++++++++++++++++++++++++
 gobject/gtype.h                             |    2 +
 3 files changed, 51 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt
index a85699b..9a190e0 100644
--- a/docs/reference/gobject/gobject-sections.txt
+++ b/docs/reference/gobject/gobject-sections.txt
@@ -125,6 +125,7 @@ g_type_check_is_value_type
 g_type_check_value
 g_type_check_value_holds
 g_type_instance_get_private
+g_type_class_get_instance_private_offset
 g_type_class_get_private
 g_type_test_flags
 g_type_name_from_instance
diff --git a/gobject/gtype.c b/gobject/gtype.c
index c3f4374..6cd8ac4 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -4529,6 +4529,54 @@ g_type_instance_get_private (GTypeInstance *instance,
 }
 
 /**
+ * g_type_class_get_instance_private_offset: (skip)
+ * @g_class: a #GTypeClass
+ *
+ * Gets the offset of the private data for instances of @g_class.
+ *
+ * This is how many bytes you should add to the instance pointer of a
+ * class in order to get the private data for the type represented by
+ * @g_class.
+ *
+ * You can only call this function after you have registered a private
+ * data area for @g_class using g_type_class_add_private().
+ *
+ * Returns: the offset, in bytes
+ *
+ * Since: 2.38
+ **/
+gint
+g_type_class_get_instance_private_offset (gpointer g_class)
+{
+  GType instance_type;
+  guint16 parent_size;
+  TypeNode *node;
+
+  g_assert (g_class != NULL);
+
+  instance_type = ((GTypeClass *) g_class)->g_type;
+  node = lookup_type_node_I (instance_type);
+
+  g_assert (node != NULL);
+  g_assert (node->is_instantiatable);
+
+  if (NODE_PARENT_TYPE (node))
+    {
+      TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node));
+
+      parent_size = pnode->data->instance.private_size;
+    }
+  else
+    parent_size = 0;
+
+  if (node->data->instance.private_size == parent_size)
+    g_error ("g_type_class_get_instance_private_offset() called on class %s but it has no private data",
+             g_type_name (instance_type));
+
+  return -(gint) node->data->instance.private_size;
+}
+
+/**
  * g_type_add_class_private:
  * @class_type: GType of an classed type.
  * @private_size: size of private structure.
diff --git a/gobject/gtype.h b/gobject/gtype.h
index f6f6f93..a0a57f0 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -1294,6 +1294,8 @@ void      g_type_add_class_private      (GType                         class_type,
 GLIB_AVAILABLE_IN_ALL
 gpointer  g_type_class_get_private      (GTypeClass                *klass,
                                         GType                       private_type);
+GLIB_AVAILABLE_IN_2_38
+gint      g_type_class_get_instance_private_offset (gpointer         g_class);
 
 GLIB_AVAILABLE_IN_2_34
 void      g_type_ensure                 (GType                       type);


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