@@ -17,7 +17,7 @@
typedef struct InterfaceImpl
{
const char *parent;
- void (*interface_initfn)(ObjectClass *class);
+ void (*interface_initfn)(ObjectClass *class, void *data);
Type type;
} InterfaceImpl;
@@ -33,8 +33,10 @@ typedef struct TypeImpl
void (*base_init)(ObjectClass *klass);
void (*base_finalize)(ObjectClass *klass);
- void (*class_init)(ObjectClass *klass);
- void (*class_finalize)(ObjectClass *klass);
+ void (*class_init)(ObjectClass *klass, void *data);
+ void (*class_finalize)(ObjectClass *klass, void *data);
+
+ void *class_data;
void (*instance_init)(Object *obj);
void (*instance_finalize)(Object *obj);
@@ -61,6 +63,8 @@ Type type_register_static(const TypeInfo *info)
assert(info->name != NULL);
+ printf("Added type %s -> %s\n", info->name, info->parent);
+
ti->name = info->name;
ti->parent = info->parent;
ti->type = type;
@@ -73,6 +77,7 @@ Type type_register_static(const TypeInfo *info)
ti->class_init = info->class_init;
ti->class_finalize = info->class_finalize;
+ ti->class_data = info->class_data;
ti->instance_init = info->instance_init;
ti->instance_finalize = info->instance_finalize;
@@ -114,6 +119,7 @@ static Type type_register_anonymous(const TypeInfo *info)
ti->class_init = info->class_init;
ti->class_finalize = info->class_finalize;
+ ti->class_data = info->class_data;
ti->instance_init = info->instance_init;
ti->instance_finalize = info->instance_finalize;
@@ -237,7 +243,7 @@ static void type_class_init(TypeImpl *ti)
}
if (ti->class_init) {
- ti->class_init(ti->class);
+ ti->class_init(ti->class, ti->class_data);
}
}
@@ -27,6 +27,8 @@ typedef struct InterfaceClass InterfaceClass;
typedef struct Interface Interface;
typedef struct InterfaceInfo InterfaceInfo;
+#define TYPE_OBJECT NULL
+
/**
* @ObjectClass:
*
@@ -183,7 +185,7 @@ struct TypeInfo
* to allow a class to set its default virtual method pointers. This is
* also the function to use to override virtual methods from a parent class.
*/
- void (*class_init)(ObjectClass *klass);
+ void (*class_init)(ObjectClass *klass, void *data);
/**
* @class_finalize
@@ -191,7 +193,15 @@ struct TypeInfo
* This function is called during class destruction and is meant to release
* and dynamic parameters allocated by @class_init.
*/
- void (*class_finalize)(ObjectClass *klass);
+ void (*class_finalize)(ObjectClass *klass, void *data);
+
+ /**
+ * @class_data
+ *
+ * Data to pass to the @class_init and @class_finalize functions. This can
+ * be useful when building dynamic classes.
+ */
+ void *class_data;
/**
* Interfaces
@@ -306,7 +316,7 @@ struct InterfaceInfo
* initialize any default virtual functions for a class and/or override
* virtual functions in a parent class.
*/
- void (*interface_initfn)(ObjectClass *class);
+ void (*interface_initfn)(ObjectClass *class, void *data);
};
#define TYPE_INTERFACE "interface"
@@ -44,12 +44,23 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name,
const BusInfo *info);
static BusState *qbus_find(const char *path);
+#define TYPE_DEVICE "device"
+#define DEVICE(obj) OBJECT_CHECK(DeviceState, (obj), TYPE_DEVICE)
+
/* Register a new device type. */
void qdev_register(DeviceInfo *info)
{
+ TypeInfo type_info = {};
+
assert(info->size >= sizeof(DeviceState));
assert(!info->next);
+ type_info.name = info->name;
+ type_info.parent = TYPE_DEVICE;
+ type_info.instance_size = info->size;
+
+ type_register_static(&type_info);
+
info->next = device_info_list;
device_info_list = info;
}
@@ -86,7 +97,7 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
Property *prop;
assert(bus->info == info->bus_info);
- dev = g_malloc0(info->size);
+ dev = DEVICE(object_new(info->name));
dev->info = info;
dev->parent_bus = bus;
qdev_prop_set_defaults(dev, dev->info->props);
@@ -484,7 +495,7 @@ void qdev_free(DeviceState *dev)
prop->info->free(dev, prop);
}
}
- g_free(dev);
+ object_delete(OBJECT(dev));
}
void qdev_machine_creation_done(void)
@@ -1515,3 +1526,18 @@ void qdev_property_add_str(DeviceState *dev, const char *name,
qdev_property_release_str,
prop, errp);
}
+
+static TypeInfo device_type_info = {
+ .name = TYPE_DEVICE,
+ .parent = TYPE_OBJECT,
+ .instance_size = sizeof(DeviceState),
+ .abstract = true,
+ .class_size = sizeof(DeviceClass),
+};
+
+static void init_qdev(void)
+{
+ type_register_static(&device_type_info);
+}
+
+device_init(init_qdev);