Merge branch '252-classed-docs' into 'main'

gtype: Improve documentation for G_TYPE_IS_CLASSED and interfaces

Closes #252

See merge request GNOME/glib!3374
This commit is contained in:
Emmanuele Bassi 2023-04-13 14:52:47 +00:00
commit ee119b4f02
5 changed files with 74 additions and 28 deletions

View File

@ -294,7 +294,7 @@ ViewerFile *file = g_object_new (VIEWER_TYPE_FILE, NULL);
memory will be freed or returned to the object pool for this type.
Once the object has been freed, if it was the last instance of the type, the type's class
will be destroyed as described in <xref linkend="gtype-instantiatable-classed"/> and
<xref linkend="gtype-non-instantiatable-classed"/>.
<xref linkend="gtype-non-instantiatable-non-classed"/>.
</para>
<para>

View File

@ -599,7 +599,7 @@ B *b;
<row>
<!--entry>First call to <function><link linkend="g-type-create-instance">g_type_create_instance</link></function> for target type</entry-->
<entry>interface initialization, see
<xref linkend="gtype-non-instantiatable-classed-init"/></entry>
<xref linkend="gtype-non-instantiatable-non-classed-init"/></entry>
<entry></entry>
</row>
<row>
@ -610,7 +610,7 @@ B *b;
<row>
<entry morerows="2">Last call to <function><link linkend="g-type-free-instance">g_type_free_instance</link></function> for target type</entry>
<entry>interface destruction, see
<xref linkend="gtype-non-instantiatable-classed-dest"/></entry>
<xref linkend="gtype-non-instantiatable-non-classed-dest"/></entry>
<entry></entry>
</row>
<row>
@ -633,8 +633,8 @@ B *b;
</sect1>
<sect1 id="gtype-non-instantiatable-classed">
<title>Non-instantiatable classed types: interfaces</title>
<sect1 id="gtype-non-instantiatable-non-classed">
<title>Non-instantiatable non-classed types: interfaces</title>
<para>
This section covers the theory behind interfaces. See
@ -649,7 +649,7 @@ B *b;
be seen as a playback interface. Once you know what they do, you can
control your CD player, MP3 player or anything that uses these symbols.
To declare an interface you have to register a non-instantiatable
classed type which derives from
non-classed type which derives from
<link linkend="GTypeInterface"><type>GTypeInterface</type></link>. The following piece of code declares such an interface.
<informalexample><programlisting>
#define VIEWER_TYPE_EDITABLE viewer_editable_get_type ()
@ -792,7 +792,7 @@ struct _GInterfaceInfo
</programlisting></informalexample>
</para>
<sect2 id="gtype-non-instantiatable-classed-init">
<sect2 id="gtype-non-instantiatable-non-classed-init">
<title>Interface Initialization</title>
<para>
@ -937,7 +937,7 @@ viewer_editable_default_init (ViewerEditableInterface *iface)
</sect2>
<sect2 id="gtype-non-instantiatable-classed-dest">
<sect2 id="gtype-non-instantiatable-non-classed-dest">
<title>Interface Destruction</title>
<para>
@ -955,7 +955,7 @@ viewer_editable_default_init (ViewerEditableInterface *iface)
<para>
Again, it is important to understand, as in
<xref linkend="gtype-non-instantiatable-classed-init"/>,
<xref linkend="gtype-non-instantiatable-non-classed-init"/>,
that both <function>interface_finalize</function> and <function>base_finalize</function>
are invoked exactly once for the destruction of each implementation of an interface. Thus,
if you were to use one of these functions, you would need to use a static integer variable

View File

@ -854,7 +854,7 @@ b_method_to_call (B *obj, gint some_param)
<para>
The theory behind how GObject interfaces work is given in
<xref linkend="gtype-non-instantiatable-classed"/>; this section covers how to
<xref linkend="gtype-non-instantiatable-non-classed"/>; this section covers how to
define and implement an interface.
</para>

View File

@ -268,7 +268,7 @@ G_BEGIN_DECLS
*
* Checks if @type is a fundamental type.
*
* Returns: %TRUE on success
* Returns: %TRUE is @type is fundamental
*/
#define G_TYPE_IS_FUNDAMENTAL(type) ((type) <= G_TYPE_FUNDAMENTAL_MAX)
/**
@ -279,7 +279,7 @@ G_BEGIN_DECLS
* inherited) from another type (this holds true for all non-fundamental
* types).
*
* Returns: %TRUE on success
* Returns: %TRUE if @type is derived
*/
#define G_TYPE_IS_DERIVED(type) ((type) > G_TYPE_FUNDAMENTAL_MAX)
/**
@ -295,7 +295,7 @@ G_BEGIN_DECLS
* with the difference that GType interfaces are not derivable (but see
* g_type_interface_add_prerequisite() for an alternative).
*
* Returns: %TRUE on success
* Returns: %TRUE if @type is an interface
*/
#define G_TYPE_IS_INTERFACE(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_INTERFACE)
/**
@ -304,7 +304,16 @@ G_BEGIN_DECLS
*
* Checks if @type is a classed type.
*
* Returns: %TRUE on success
* A classed type has an associated #GTypeClass which can be derived to store
* class-wide virtual function pointers and data for all instances of the type.
* This allows for subclassing. All #GObjects are classed; none of the scalar
* fundamental types built into GLib are classed.
*
* Interfaces are not classed: while their #GTypeInterface struct could be
* considered similar to #GTypeClass, and classes can derive interfaces,
* #GTypeInterface doesnt allow for subclassing.
*
* Returns: %TRUE if @type is classed
*/
#define G_TYPE_IS_CLASSED(type) (g_type_test_flags ((type), G_TYPE_FLAG_CLASSED))
/**
@ -314,7 +323,7 @@ G_BEGIN_DECLS
* Checks if @type can be instantiated. Instantiation is the
* process of creating an instance (object) of this type.
*
* Returns: %TRUE on success
* Returns: %TRUE if @type is instantiatable
*/
#define G_TYPE_IS_INSTANTIATABLE(type) (g_type_test_flags ((type), G_TYPE_FLAG_INSTANTIATABLE))
/**
@ -324,7 +333,7 @@ G_BEGIN_DECLS
* Checks if @type is a derivable type. A derivable type can
* be used as the base class of a flat (single-level) class hierarchy.
*
* Returns: %TRUE on success
* Returns: %TRUE if @type is derivable
*/
#define G_TYPE_IS_DERIVABLE(type) (g_type_test_flags ((type), G_TYPE_FLAG_DERIVABLE))
/**
@ -334,7 +343,7 @@ G_BEGIN_DECLS
* Checks if @type is a deep derivable type. A deep derivable type
* can be used as the base class of a deep (multi-level) class hierarchy.
*
* Returns: %TRUE on success
* Returns: %TRUE if @type is deep derivable
*/
#define G_TYPE_IS_DEEP_DERIVABLE(type) (g_type_test_flags ((type), G_TYPE_FLAG_DEEP_DERIVABLE))
/**
@ -345,7 +354,7 @@ G_BEGIN_DECLS
* instantiated and is normally used as an abstract base class for
* derived classes.
*
* Returns: %TRUE on success
* Returns: %TRUE if @type is abstract
*/
#define G_TYPE_IS_ABSTRACT(type) (g_type_test_flags ((type), G_TYPE_FLAG_ABSTRACT))
/**
@ -356,7 +365,7 @@ G_BEGIN_DECLS
* a value table, but can't be used for g_value_init() and is normally used as
* an abstract base type for derived value types.
*
* Returns: %TRUE on success
* Returns: %TRUE if @type is an abstract value type
*/
#define G_TYPE_IS_VALUE_ABSTRACT(type) (g_type_test_flags ((type), G_TYPE_FLAG_VALUE_ABSTRACT))
/**
@ -365,7 +374,7 @@ G_BEGIN_DECLS
*
* Checks if @type is a value type and can be used with g_value_init().
*
* Returns: %TRUE on success
* Returns: %TRUE if @type is a value type
*/
#define G_TYPE_IS_VALUE_TYPE(type) (g_type_check_is_value_type (type))
/**
@ -374,7 +383,7 @@ G_BEGIN_DECLS
*
* Checks if @type has a #GTypeValueTable.
*
* Returns: %TRUE on success
* Returns: %TRUE if @type has a value table
*/
#define G_TYPE_HAS_VALUE_TABLE(type) (g_type_value_table_peek (type) != NULL)
/**
@ -384,7 +393,7 @@ G_BEGIN_DECLS
* Checks if @type is a final type. A final type cannot be derived any
* further.
*
* Returns: %TRUE on success
* Returns: %TRUE if @type is final
*
* Since: 2.70
*/
@ -497,7 +506,7 @@ struct _GTypeQuery
*
* This macro should only be used in type implementations.
*
* Returns: %TRUE on success
* Returns: %TRUE if @instance is valid
*/
#define G_TYPE_CHECK_INSTANCE(instance) (_G_TYPE_CHI ((GTypeInstance*) (instance)))
/**
@ -525,7 +534,7 @@ struct _GTypeQuery
*
* This macro should only be used in type implementations.
*
* Returns: %TRUE on success
* Returns: %TRUE if @instance is an instance of @g_type
*/
#define G_TYPE_CHECK_INSTANCE_TYPE(instance, g_type) (_G_TYPE_CIT ((instance), (g_type)))
/**
@ -538,7 +547,7 @@ struct _GTypeQuery
*
* This macro should only be used in type implementations.
*
* Returns: %TRUE on success
* Returns: %TRUE if @instance is an instance of @g_type
*/
#define G_TYPE_CHECK_INSTANCE_FUNDAMENTAL_TYPE(instance, g_type) (_G_TYPE_CIFT ((instance), (g_type)))
/**
@ -594,7 +603,7 @@ struct _GTypeQuery
*
* This macro should only be used in type implementations.
*
* Returns: %TRUE on success
* Returns: %TRUE if @g_class is a class structure of @g_type
*/
#define G_TYPE_CHECK_CLASS_TYPE(g_class, g_type) (_G_TYPE_CCT ((g_class), (g_type)))
/**
@ -606,7 +615,7 @@ struct _GTypeQuery
*
* This macro should only be used in type implementations.
*
* Returns: %TRUE on success
* Returns: %TRUE if @value is initialized
*/
#define G_TYPE_CHECK_VALUE(value) (_G_TYPE_CHV ((value)))
/**
@ -619,7 +628,7 @@ struct _GTypeQuery
*
* This macro should only be used in type implementations.
*
* Returns: %TRUE on success
* Returns: %TRUE if @value has been initialized to hold values of type @g_type
*/
#define G_TYPE_CHECK_VALUE_TYPE(value, g_type) (_G_TYPE_CVH ((value), (g_type)))
/**

View File

@ -3,6 +3,42 @@
#include <glib-object.h>
typedef struct
{
GTypeInterface g_iface;
} TestInterfaceInterface;
GType test_interface_get_type (void);
#define TEST_TYPE_INTERFACE test_interface_get_type ()
G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_INVALID)
static void
test_interface_default_init (TestInterfaceInterface *iface)
{
}
static void
test_type_flags_interface (void)
{
g_assert_false (G_TYPE_IS_ABSTRACT (TEST_TYPE_INTERFACE));
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_ABSTRACT));
g_assert_false (G_TYPE_IS_CLASSED (TEST_TYPE_INTERFACE));
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_CLASSED));
g_assert_false (G_TYPE_IS_DEEP_DERIVABLE (TEST_TYPE_INTERFACE));
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_DEEP_DERIVABLE));
g_assert_true (G_TYPE_IS_DERIVABLE (TEST_TYPE_INTERFACE));
g_assert_true (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_DERIVABLE));
g_assert_false (G_TYPE_IS_FINAL (TEST_TYPE_INTERFACE));
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_FINAL));
g_assert_false (G_TYPE_IS_INSTANTIATABLE (TEST_TYPE_INTERFACE));
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_INSTANTIATABLE));
}
#define TEST_TYPE_FINAL (test_final_get_type())
G_DECLARE_FINAL_TYPE (TestFinal, test_final, TEST, FINAL, GObject)
@ -201,6 +237,7 @@ main (int argc, char *argv[])
g_setenv ("G_ENABLE_DIAGNOSTIC", "1", TRUE);
g_test_add_func ("/type/flags/interface", test_type_flags_interface);
g_test_add_func ("/type/flags/final", test_type_flags_final);
g_test_add_func ("/type/flags/final/instance-check", test_type_flags_final_instance_check);
g_test_add_func ("/type/flags/deprecated", test_type_flags_deprecated);