[gtk/docs-gtk-org] gobject: Add a section on boxed types



commit 53917d9b978ed5d652312c951cf9b8c0743e495d
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Sat Nov 6 13:41:24 2021 +0000

    gobject: Add a section on boxed types
    
    Port the boxed types section blurb from the GObject reference to its own
    page, and expand it a bit.

 glib/gobject/boxed.md        | 113 +++++++++++++++++++++++++++++++++++++++++++
 glib/gobject/gobject.toml.in |   1 +
 glib/gobject/meson.build     |   2 +
 3 files changed, 116 insertions(+)
---
diff --git a/glib/gobject/boxed.md b/glib/gobject/boxed.md
new file mode 100644
index 0000000000..37918b5298
--- /dev/null
+++ b/glib/gobject/boxed.md
@@ -0,0 +1,113 @@
+Title: Boxed types
+
+# Boxed types
+
+A "boxed type" is a generic wrapper mechanism for arbitrary C structures.
+The only thing the type system needs to know about the structures is how to
+copy them (a [`callback@GObject.BoxedCopyFunc`]) and how to free them (a
+[`callback@GObject.BoxedFreeFunc`])—beyond that they are treated as opaque
+chunks of memory.
+
+Boxed types are useful for simple value-holder structures like rectangles or
+points. They can also be used for wrapping structures defined in non-GObject
+based libraries. They allow arbitrary structures to be handled in a uniform
+way, allowing uniform copying (or referencing) and freeing (or
+unreferencing) of them, and uniform representation of the type of the
+contained structure. In turn, this allows any type which can be boxed to be
+set as the data in a `GValue`, which allows for polymorphic handling of a much
+wider range of data types, and hence usage of such types as `GObject` property
+values.
+
+All boxed types inherit from the `G_TYPE_BOXED` fundamental type.
+
+It is very important to note that boxed types are **not** deeply
+inheritable: you cannot register a boxed type that inherits from another
+boxed type. This means you cannot create your own custom, parallel type
+hierarchy and map it to GType using boxed types. If you want to have deeply
+inheritable types without using GObject, you will need to use
+`GTypeInstance`.
+
+## Registering a new boxed type
+
+The recommended way to register a new boxed type is to use the
+[`func@GObject.DEFINE_BOXED_TYPE`] macro:
+
+```c
+// In the header
+
+#define EXAMPLE_TYPE_RECTANGLE (example_rectangle_get_type())
+
+typedef struct {
+  double x, y;
+  double width, height;
+} ExampleRectangle;
+
+GType
+example_rectangle_get_type (void);
+
+ExampleRectangle *
+example_rectangle_copy (ExampleRectangle *r);
+
+void
+example_rectangle_free (ExampleRectangle *r);
+
+// In the source
+G_DEFINE_BOXED_TYPE (ExampleRectangle, example_rectangle,
+                     example_rectangle_copy,
+                    example_rectangle_free)
+```
+
+Just like `G_DEFINE_TYPE` and `G_DEFINE_INTERFACE_TYPE`, the
+`G_DEFINE_BOXED_TYPE` macro will provide the definition of the `get_type()`
+function, which will call [`func@GObject.boxed_type_register_static`] with
+the given type name as well as the `GBoxedCopyFunc` and `GBoxedFreeFunc`
+functions.
+
+## Using boxed types
+
+### Object properties
+
+In order to use a boxed type with GObject properties you will need to
+register the property using [`func@GObject.param_spec_boxed`], e.g.
+
+```c
+obj_props[PROP_BOUNDS] =
+  g_param_spec_boxed ("bounds", NULL, NULL,
+                      EXAMPLE_TYPE_RECTANGLE,
+                     G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+```
+
+In the `set_property` implementation you can use `g_value_get_boxed()` to
+retrieve a pointer to the boxed type:
+
+```c
+switch (prop_id)
+  {
+  // ...
+  case PROP_BOUNDS:
+    example_object_set_bounds (self, g_value_get_boxed (value));
+    break;
+  // ...
+  }
+```
+
+Similarly, you can use `g_value_set_boxed()` in the implementation of the
+`get_property` virtual function:
+
+```c
+switch (prop_id)
+  {
+  // ...
+  case PROP_BOUNDS:
+    g_value_set_boxed (self, &self->bounds);
+    break;
+  // ...
+  }
+```
+
+## Reference counting
+
+Boxed types are designed so that reference counted types can be boxed. Use
+the type’s ‘ref’ function as the `GBoxedCopyFunc`, and its ‘unref’ function as
+the `GBoxedFreeFunc`. For example, for `GBytes`, the `GBoxedCopyFunc` is
+`g_bytes_ref()`, and the GBoxedFreeFunc is `g_bytes_unref()`.
diff --git a/glib/gobject/gobject.toml.in b/glib/gobject/gobject.toml.in
index c3459fd7e5..26b8faa0f1 100644
--- a/glib/gobject/gobject.toml.in
+++ b/glib/gobject/gobject.toml.in
@@ -38,6 +38,7 @@ content_files = [
   "concepts.md",
   "tutorial.md",
   "floating-refs.md",
+  "boxed.md",
 ]
 content_images = [
   "images/glue.png",
diff --git a/glib/gobject/meson.build b/glib/gobject/meson.build
index 90eceea835..442896625a 100644
--- a/glib/gobject/meson.build
+++ b/glib/gobject/meson.build
@@ -1,5 +1,7 @@
 expand_content_files = [
+  'boxed.md',
   'concepts.md',
+  'floating-refs.md',
   'tutorial.md',
 ]
 


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