qemu-devel
[Top][All Lists]
Advanced

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

Re: [PATCH 2/4] qom: provide convenient macros for declaring and definin


From: Eduardo Habkost
Subject: Re: [PATCH 2/4] qom: provide convenient macros for declaring and defining types
Date: Tue, 11 Aug 2020 14:22:06 -0400

I've just noticed this:

On Thu, Jul 23, 2020 at 07:14:08PM +0100, Daniel P. Berrangé wrote:
> When creating new QOM types, there is a lot of boilerplate code that
> must be repeated using a standard pattern. This is tedious to write
> and liable to suffer from subtle inconsistencies. Thus it would
> benefit from some simple automation.
> 
> QOM was loosely inspired by GLib's GObject, and indeed GObject suffers
> from the same burden of boilerplate code, but has long provided a set of
> macros to eliminate this burden in the source implementation. More
> recently it has also provided a set of macros to eliminate this burden
> in the header declaration.
> 
> In GLib there are the G_DECLARE_* and G_DEFINE_* family of macros
> for the header declaration and source implementation respectively:
> 
>   https://developer.gnome.org/gobject/stable/chapter-gobject.html
>   https://developer.gnome.org/gobject/stable/howto-gobject.html
> 
> This patch takes inspiration from GObject to provide the equivalent
> functionality for QOM.
> 
> In the header file, instead of:
> 
>     typedef struct MyDevice MyDevice;
>     typedef struct MyDeviceClass MyDeviceClass;
> 
>     G_DEFINE_AUTOPTR_CLEANUP_FUNC(MyDeviceClass, object_unref)

Isn't this supposed to be
  G_DEFINE_AUTOPTR_CLEANUP_FUNC(MyDevice, object_unref)
?

> 
>     #define MY_DEVICE_GET_CLASS(void *obj) \
>             OBJECT_GET_CLASS(MyDeviceClass, obj, TYPE_MY_DEVICE)
>     #define MY_DEVICE_CLASS(void *klass) \
>             OBJECT_CLASS_CHECK(MyDeviceClass, klass, TYPE_MY_DEVICE)
>     #define MY_DEVICE(void *obj)
>             OBJECT_CHECK(MyDevice, obj, TYPE_MY_DEVICE)
> 
>     struct MyDeviceClass {
>         DeviceClass parent_class;
>     };
> 
> We now have
> 
>     OBJECT_DECLARE_SIMPLE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
> 
> In cases where the class needs some virtual methods, it can be left
> to be implemented manually using
> 
>     OBJECT_DECLARE_TYPE(MyDevice, my_device, MY_DEVICE)
> 
> Note that these macros are including support for g_autoptr() for the
> object types, which is something previously only supported for variables
> declared as the base Object * type.
[...]
> + * <example>
> + *   <title>Expansion from declaring a simple type</title>
> + *   <programlisting>
> + *     typedef struct MyDevice MyDevice;
> + *     typedef struct MyDeviceClass MyDeviceClass;
> + *
> + *     G_DEFINE_AUTOPTR_CLEANUP_FUNC(MyDeviceClass, object_unref)
> + *
> + *     #define MY_DEVICE_GET_CLASS(void *obj) \
> + *             OBJECT_GET_CLASS(MyDeviceClass, obj, TYPE_MY_DEVICE)
> + *     #define MY_DEVICE_CLASS(void *klass) \
> + *             OBJECT_CLASS_CHECK(MyDeviceClass, klass, TYPE_MY_DEVICE)
> + *     #define MY_DEVICE(void *obj)
> + *             OBJECT_CHECK(MyDevice, obj, TYPE_MY_DEVICE)
> + *
> + *     struct MyDeviceClass {
> + *         DeviceClass parent_class;
> + *     };
> + *   </programlisting>
> + * </example>
[...]
> +#define OBJECT_DECLARE_TYPE(ModuleObjName, module_obj_name, MODULE_OBJ_NAME) 
> \
> +    typedef struct ModuleObjName ModuleObjName; \
> +    typedef struct ModuleObjName##Class ModuleObjName##Class; \
> +    \
> +    G_DEFINE_AUTOPTR_CLEANUP_FUNC(ModuleObjName##Class, object_unref) \
> +    \
> +    static inline G_GNUC_UNUSED ModuleObjName##Class * \
> +    MODULE_OBJ_NAME##_GET_CLASS(void *obj) \
> +    { return OBJECT_GET_CLASS(ModuleObjName##Class, obj, \
> +                              TYPE_##MODULE_OBJ_NAME); } \
> +    \
> +    static inline G_GNUC_UNUSED ModuleObjName##Class * \
> +    MODULE_OBJ_NAME##_CLASS(void *klass) \
> +    { return OBJECT_CLASS_CHECK(ModuleObjName##Class, klass, \
> +                                TYPE_##MODULE_OBJ_NAME); } \
> +    \
> +    static inline G_GNUC_UNUSED ModuleObjName * \
> +    MODULE_OBJ_NAME(void *obj) \
> +    { return OBJECT_CHECK(ModuleObjName, obj, \
> +                          TYPE_##MODULE_OBJ_NAME); }
> +
[...]

-- 
Eduardo




reply via email to

[Prev in Thread] Current Thread [Next in Thread]