mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 23:33:54 -06:00
qom: Reimplement Interfaces
The current implementation of Interfaces is poorly designed. Each interface that an object implements ends up being an object that's tracked by the implementing object. There's all sorts of gymnastics to deal with casting between these objects. But an interface shouldn't be associated with an Object. Interfaces are global to a class. This patch moves all Interface knowledge to ObjectClass eliminating the relationship between Object and Interfaces. Interfaces are now abstract (as they should be) but this is okay. Interfaces essentially act as additional parents for the classes and are treated as such. With this new implementation, we should fully support derived interfaces including reimplementing an inherited interface. PC: Rebased against qom-next merge Jun-2012. PC: Removed replication of cast logic for interfaces, i.e. there is only one cast function - object_dynamic_cast() (and object_dynamic_cast_assert()) Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com> Acked-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
This commit is contained in:
parent
669b498301
commit
33e95c6328
2 changed files with 118 additions and 152 deletions
|
@ -239,6 +239,7 @@ struct ObjectClass
|
|||
{
|
||||
/*< private >*/
|
||||
Type type;
|
||||
GSList *interfaces;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -260,7 +261,6 @@ struct Object
|
|||
{
|
||||
/*< private >*/
|
||||
ObjectClass *class;
|
||||
GSList *interfaces;
|
||||
QTAILQ_HEAD(, ObjectProperty) properties;
|
||||
uint32_t ref;
|
||||
Object *parent;
|
||||
|
@ -386,6 +386,16 @@ struct TypeInfo
|
|||
#define OBJECT_GET_CLASS(class, obj, name) \
|
||||
OBJECT_CLASS_CHECK(class, object_get_class(OBJECT(obj)), name)
|
||||
|
||||
/**
|
||||
* InterfaceInfo:
|
||||
* @type: The name of the interface.
|
||||
*
|
||||
* The information associated with an interface.
|
||||
*/
|
||||
struct InterfaceInfo {
|
||||
const char *type;
|
||||
};
|
||||
|
||||
/**
|
||||
* InterfaceClass:
|
||||
* @parent_class: the base class
|
||||
|
@ -396,27 +406,31 @@ struct TypeInfo
|
|||
struct InterfaceClass
|
||||
{
|
||||
ObjectClass parent_class;
|
||||
};
|
||||
|
||||
/**
|
||||
* InterfaceInfo:
|
||||
* @type: The name of the interface.
|
||||
* @interface_initfn: This method is called during class initialization and is
|
||||
* used to initialize an interface associated with a class. This function
|
||||
* should initialize any default virtual functions for a class and/or override
|
||||
* virtual functions in a parent class.
|
||||
*
|
||||
* The information associated with an interface.
|
||||
*/
|
||||
struct InterfaceInfo
|
||||
{
|
||||
const char *type;
|
||||
|
||||
void (*interface_initfn)(ObjectClass *class, void *data);
|
||||
/*< private >*/
|
||||
ObjectClass *concrete_class;
|
||||
};
|
||||
|
||||
#define TYPE_INTERFACE "interface"
|
||||
|
||||
/**
|
||||
* INTERFACE_CLASS:
|
||||
* @klass: class to cast from
|
||||
* Returns: An #InterfaceClass or raise an error if cast is invalid
|
||||
*/
|
||||
#define INTERFACE_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(InterfaceClass, klass, TYPE_INTERFACE)
|
||||
|
||||
/**
|
||||
* INTERFACE_CHECK:
|
||||
* @interface: the type to return
|
||||
* @obj: the object to convert to an interface
|
||||
* @name: the interface type name
|
||||
*
|
||||
* Returns: @obj casted to @interface if cast is valid, otherwise raise error.
|
||||
*/
|
||||
#define INTERFACE_CHECK(interface, obj, name) \
|
||||
((interface *)object_dynamic_cast_assert(OBJECT((obj)), (name)))
|
||||
|
||||
/**
|
||||
* object_new:
|
||||
* @typename: The name of the type of the object to instantiate.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue