Commit 782beb52 authored by Andreas Färber's avatar Andreas Färber Committed by Anthony Liguori
Browse files

qom: Extend documentation on QOM method concepts



Add a documentation section "Methods" and discuss among others how to
handle overriding virtual methods.

Clarify DeviceClass::realize documentation and refer to the above.

Signed-off-by: default avatarAndreas Färber <afaerber@suse.de>
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parent 781c0c33
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -60,14 +60,20 @@ struct VMStateDescription;
 * The @init callback is considered private to a particular bus implementation
 * (immediate abstract child types of TYPE_DEVICE). Derived leaf types set an
 * "init" callback on their parent class instead.
 *
 * Any type may override the @realize and/or @unrealize callbacks but needs
 * to call (and thus save) the parent type's implementation if so desired.
 * Usually this means storing the previous value of, e.g., @realized inside
 * the type's class structure and overwriting it with a function that first
 * invokes the stored callback, then performs any additional steps.
 * to call the parent type's implementation if keeping their functionality
 * is desired. Refer to QOM documentation for further discussion and examples.
 *
 * <note>
 *   <para>
 * If a type derived directly from TYPE_DEVICE implements @realize, it does
 * not need to implement @init and therefore does not need to store and call
 * #DeviceClass' default @realize callback.
 * For other types consult the documentation and implementation of the
 * respective parent types.
 *   </para>
 * </note>
 */
typedef struct DeviceClass {
    /*< private >*/
+101 −3
Original line number Diff line number Diff line
@@ -147,9 +147,9 @@ typedef struct InterfaceInfo InterfaceInfo;
 *   </programlisting>
 * </example>
 *
 * Introducing new virtual functions requires a class to define its own
 * struct and to add a .class_size member to the TypeInfo.  Each function
 * will also have a wrapper to call it easily:
 * Introducing new virtual methods requires a class to define its own
 * struct and to add a .class_size member to the #TypeInfo.  Each method
 * will also have a wrapper function to call it easily:
 *
 * <example>
 *   <title>Defining an abstract class</title>
@@ -186,6 +186,104 @@ typedef struct InterfaceInfo InterfaceInfo;
 * similar to normal types except for the fact that are only defined by
 * their classes and never carry any state.  You can dynamically cast an object
 * to one of its #Interface types and vice versa.
 *
 * # Methods #
 *
 * A <emphasis>method</emphasis> is a function within the namespace scope of
 * a class. It usually operates on the object instance by passing it as a
 * strongly-typed first argument.
 * If it does not operate on an object instance, it is dubbed
 * <emphasis>class method</emphasis>.
 *
 * Methods cannot be overloaded. That is, the #ObjectClass and method name
 * uniquely identity the function to be called; the signature does not vary
 * except for trailing varargs.
 *
 * Methods are always <emphasis>virtual</emphasis>. Overriding a method in
 * #TypeInfo.class_init of a subclass leads to any user of the class obtained
 * via OBJECT_GET_CLASS() accessing the overridden function.
 * The original function is not automatically invoked. It is the responsability
 * of the overriding class to determine whether and when to invoke the method
 * being overridden.
 *
 * To invoke the method being overridden, the preferred solution is to store
 * the original value in the overriding class before overriding the method.
 * This corresponds to |[ {super,base}.method(...) ]| in Java and C#
 * respectively; this frees the overriding class from hardcoding its parent
 * class, which someone might choose to change at some point.
 *
 * <example>
 *   <title>Overriding a virtual method</title>
 *   <programlisting>
 * typedef struct MyState MyState;
 *
 * typedef void (*MyDoSomething)(MyState *obj);
 *
 * typedef struct MyClass {
 *     ObjectClass parent_class;
 *
 *     MyDoSomething do_something;
 * } MyClass;
 *
 * static void my_do_something(MyState *obj)
 * {
 *     // do something
 * }
 *
 * static void my_class_init(ObjectClass *oc, void *data)
 * {
 *     MyClass *mc = MY_CLASS(oc);
 *
 *     mc->do_something = my_do_something;
 * }
 *
 * static const TypeInfo my_type_info = {
 *     .name = TYPE_MY,
 *     .parent = TYPE_OBJECT,
 *     .instance_size = sizeof(MyState),
 *     .class_size = sizeof(MyClass),
 *     .class_init = my_class_init,
 * };
 *
 * typedef struct DerivedClass {
 *     MyClass parent_class;
 *
 *     MyDoSomething parent_do_something;
 * } MyClass;
 *
 * static void derived_do_something(MyState *obj)
 * {
 *     DerivedClass *dc = DERIVED_GET_CLASS(obj);
 *
 *     // do something here
 *     dc->parent_do_something(obj);
 *     // do something else here
 * }
 *
 * static void derived_class_init(ObjectClass *oc, void *data)
 * {
 *     MyClass *mc = MY_CLASS(oc);
 *     DerivedClass *dc = DERIVED_CLASS(oc);
 *
 *     dc->parent_do_something = mc->do_something;
 *     mc->do_something = derived_do_something;
 * }
 *
 * static const TypeInfo derived_type_info = {
 *     .name = TYPE_DERIVED,
 *     .parent = TYPE_MY,
 *     .class_size = sizeof(DerivedClass),
 *     .class_init = my_class_init,
 * };
 *   </programlisting>
 * </example>
 *
 * Alternatively, object_class_by_name() can be used to obtain the class and
 * its non-overridden methods for a specific type. This would correspond to
 * |[ MyClass::method(...) ]| in C++.
 *
 * The first example of such a QOM method was #CPUClass.reset,
 * another example is #DeviceClass.realize.
 */