the 'struct MyDeviceClass' definition.
To implement the type, the OBJECT_DEFINE macro family is available.
-In the simple case the OBJECT_DEFINE_TYPE macro is suitable:
+For the simplest case of a leaf class which doesn't need any of its
+own virtual functions (i.e. which was declared with OBJECT_DECLARE_SIMPLE_TYPE)
+the OBJECT_DEFINE_SIMPLE_TYPE macro is suitable:
.. code-block:: c
:caption: Defining a simple type
- OBJECT_DEFINE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
+ OBJECT_DEFINE_SIMPLE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
This is equivalent to the following:
.instance_size = sizeof(MyDevice),
.instance_init = my_device_init,
.instance_finalize = my_device_finalize,
- .class_size = sizeof(MyDeviceClass),
.class_init = my_device_class_init,
};
system, and the three standard methods now need to be implemented
along with any other logic required for the type.
+If the class needs its own virtual methods, or has some other
+per-class state it needs to store in its own class struct,
+then you can use the OBJECT_DEFINE_TYPE macro. This does the
+same thing as OBJECT_DEFINE_SIMPLE_TYPE, but it also sets the
+class_size of the type to the size of the class struct.
+
+.. code-block:: c
+ :caption: Defining a type which needs a class struct
+
+ OBJECT_DEFINE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
+
If the type needs to implement one or more interfaces, then the
-OBJECT_DEFINE_TYPE_WITH_INTERFACES() macro can be used instead.
-This accepts an array of interface type names.
+OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES() and
+OBJECT_DEFINE_TYPE_WITH_INTERFACES() macros can be used instead.
+These accept an array of interface type names. The difference between
+them is that the former is for simple leaf classes that don't need
+a class struct, and the latter is for when you will be defining
+a class struct.
.. code-block:: c
:caption: Defining a simple type implementing interfaces
+ OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(MyDevice, my_device,
+ MY_DEVICE, DEVICE,
+ { TYPE_USER_CREATABLE },
+ { NULL })
+
+.. code-block:: c
+ :caption: Defining a type implementing interfaces
+
OBJECT_DEFINE_TYPE_WITH_INTERFACES(MyDevice, my_device,
MY_DEVICE, DEVICE,
{ TYPE_USER_CREATABLE },
/**
- * OBJECT_DEFINE_TYPE_EXTENDED:
+ * DO_OBJECT_DEFINE_TYPE_EXTENDED:
* @ModuleObjName: the object name with initial caps
* @module_obj_name: the object name in lowercase with underscore separators
* @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
* @PARENT_MODULE_OBJ_NAME: the parent object name in uppercase with underscore
* separators
* @ABSTRACT: boolean flag to indicate whether the object can be instantiated
+ * @CLASS_SIZE: size of the type's class
* @...: list of initializers for "InterfaceInfo" to declare implemented interfaces
*
- * This macro is typically used in a source file, and will:
- *
- * - declare prototypes for _finalize, _class_init and _init methods
- * - declare the TypeInfo struct instance
- * - provide the constructor to register the type
- *
- * After using this macro, implementations of the _finalize, _class_init,
- * and _init methods need to be written. Any of these can be zero-line
- * no-op impls if no special logic is required for a given type.
- *
- * This macro should rarely be used, instead one of the more specialized
- * macros is usually a better choice.
+ * This is the base macro used to implement all the OBJECT_DEFINE_*
+ * macros. It should never be used directly in a source file.
*/
-#define OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
- MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
- ABSTRACT, ...) \
+#define DO_OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
+ MODULE_OBJ_NAME, \
+ PARENT_MODULE_OBJ_NAME, \
+ ABSTRACT, CLASS_SIZE, ...) \
static void \
module_obj_name##_finalize(Object *obj); \
static void \
.instance_align = __alignof__(ModuleObjName), \
.instance_init = module_obj_name##_init, \
.instance_finalize = module_obj_name##_finalize, \
- .class_size = sizeof(ModuleObjName##Class), \
+ .class_size = CLASS_SIZE, \
.class_init = module_obj_name##_class_init, \
.abstract = ABSTRACT, \
.interfaces = (InterfaceInfo[]) { __VA_ARGS__ } , \
} \
type_init(module_obj_name##_register_types);
+/**
+ * OBJECT_DEFINE_TYPE_EXTENDED:
+ * @ModuleObjName: the object name with initial caps
+ * @module_obj_name: the object name in lowercase with underscore separators
+ * @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
+ * @PARENT_MODULE_OBJ_NAME: the parent object name in uppercase with underscore
+ * separators
+ * @ABSTRACT: boolean flag to indicate whether the object can be instantiated
+ * @...: list of initializers for "InterfaceInfo" to declare implemented interfaces
+ *
+ * This macro is typically used in a source file, and will:
+ *
+ * - declare prototypes for _finalize, _class_init and _init methods
+ * - declare the TypeInfo struct instance
+ * - provide the constructor to register the type
+ *
+ * After using this macro, implementations of the _finalize, _class_init,
+ * and _init methods need to be written. Any of these can be zero-line
+ * no-op impls if no special logic is required for a given type.
+ *
+ * This macro should rarely be used, instead one of the more specialized
+ * macros is usually a better choice.
+ */
+#define OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
+ MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
+ ABSTRACT, ...) \
+ DO_OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
+ MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
+ ABSTRACT, sizeof(ModuleObjName##Class), \
+ __VA_ARGS__)
+
/**
* OBJECT_DEFINE_TYPE:
* @ModuleObjName: the object name with initial caps
MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
true, { NULL })
+/**
+ * OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES:
+ * @ModuleObjName: the object name with initial caps
+ * @module_obj_name: the object name in lowercase with underscore separators
+ * @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
+ * @PARENT_MODULE_OBJ_NAME: the parent object name in uppercase with underscore
+ * separators
+ *
+ * This is a variant of OBJECT_DEFINE_TYPE_EXTENDED, which is suitable for
+ * the case of a non-abstract type, with interfaces, and with no requirement
+ * for a class struct.
+ */
+#define OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(ModuleObjName, \
+ module_obj_name, \
+ MODULE_OBJ_NAME, \
+ PARENT_MODULE_OBJ_NAME, ...) \
+ DO_OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
+ MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
+ false, 0, __VA_ARGS__)
+
+/**
+ * OBJECT_DEFINE_SIMPLE_TYPE:
+ * @ModuleObjName: the object name with initial caps
+ * @module_obj_name: the object name in lowercase with underscore separators
+ * @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
+ * @PARENT_MODULE_OBJ_NAME: the parent object name in uppercase with underscore
+ * separators
+ *
+ * This is a variant of OBJECT_DEFINE_TYPE_EXTENDED, which is suitable for
+ * the common case of a non-abstract type, without any interfaces, and with
+ * no requirement for a class struct. If you declared your type with
+ * OBJECT_DECLARE_SIMPLE_TYPE then this is probably the right choice for
+ * defining it.
+ */
+#define OBJECT_DEFINE_SIMPLE_TYPE(ModuleObjName, module_obj_name, \
+ MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME) \
+ OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(ModuleObjName, module_obj_name, \
+ MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, { NULL })
+
/**
* struct TypeInfo:
* @name: The name of the type.