mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 23:16:14 +01:00
docs: Move boxed type documentation to Markdown
And add some additional new content and examples. Helps: #3037
This commit is contained in:
parent
1a090564d2
commit
24e93078d3
113
docs/reference/gobject/boxed.md
Normal file
113
docs/reference/gobject/boxed.md
Normal file
@ -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()`.
|
@ -42,6 +42,7 @@ show_class_hierarchy = true
|
|||||||
urlmap_file = "urlmap.js"
|
urlmap_file = "urlmap.js"
|
||||||
# The same order will be used when generating the index
|
# The same order will be used when generating the index
|
||||||
content_files = [
|
content_files = [
|
||||||
|
"boxed.md",
|
||||||
]
|
]
|
||||||
content_images = [
|
content_images = [
|
||||||
]
|
]
|
||||||
|
@ -71,6 +71,7 @@ endif
|
|||||||
|
|
||||||
# gi-docgen version
|
# gi-docgen version
|
||||||
expand_content_files = [
|
expand_content_files = [
|
||||||
|
'boxed.md',
|
||||||
]
|
]
|
||||||
|
|
||||||
gobject_gir = meson.current_source_dir() / 'GObject-2.0.gir'
|
gobject_gir = meson.current_source_dir() / 'GObject-2.0.gir'
|
||||||
|
@ -33,35 +33,6 @@
|
|||||||
#include "gvaluearray.h"
|
#include "gvaluearray.h"
|
||||||
#include "gvaluecollector.h"
|
#include "gvaluecollector.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION:gboxed
|
|
||||||
* @short_description: A mechanism to wrap opaque C structures registered
|
|
||||||
* by the type system
|
|
||||||
* @see_also: #GParamSpecBoxed, g_param_spec_boxed()
|
|
||||||
* @title: Boxed Types
|
|
||||||
*
|
|
||||||
* #GBoxed 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 #GBoxedCopyFunc) and how to free them (a #GBoxedFreeFunc);
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* #GBoxed is 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().
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void /* keep this function in sync with gvalue.c */
|
static inline void /* keep this function in sync with gvalue.c */
|
||||||
value_meminit (GValue *value,
|
value_meminit (GValue *value,
|
||||||
GType value_type)
|
GType value_type)
|
||||||
|
Loading…
Reference in New Issue
Block a user