This functions allows to walk the classes in a custom order rather than
in hashtable order.

Signed-off-by: Andreas Färber <afaer...@suse.de>
Cc: Anthony Liguori <anth...@codemonkey.ws>
Cc: Peter Maydell <peter.mayd...@linaro.org>
---
 include/qemu/object.h |    6 ++++++
 qom/object.c          |   43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/include/qemu/object.h b/include/qemu/object.h
index 5179c0c..ab3597a 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -560,6 +560,12 @@ ObjectClass *object_class_by_name(const char *typename);
 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
                           const char *implements_type, bool include_abstract,
                           void *opaque);
+
+void object_class_foreach_ordered(void (*fn)(ObjectClass *klass, void *opaque),
+                                  const char *implements_type,
+                                  bool include_abstract, void *opaque,
+                                  GCompareFunc compfn);
+
 /**
  * object_ref:
  * @obj: the object
diff --git a/qom/object.c b/qom/object.c
index 2f05ca8..dbfd6a4 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -570,6 +570,49 @@ void object_class_foreach(void (*fn)(ObjectClass *klass, 
void *opaque),
     g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
 }
 
+typedef struct OCFSData {
+    void (*fn)(ObjectClass *klass, void *opaque);
+    void *opaque;
+    GTree *classes;
+} OCFSData;
+
+static void object_class_foreach_ordered_sort(ObjectClass *klass,
+                                              void *opaque)
+{
+    OCFSData *data = opaque;
+
+    g_tree_insert(data->classes, klass, NULL);
+}
+
+static gboolean object_class_foreach_ordered_tramp(gpointer key,
+                                                   gpointer value,
+                                                   gpointer data)
+{
+    ObjectClass *klass = key;
+    OCFSData *d = data;
+
+    d->fn(klass, d->opaque);
+
+    return FALSE;
+}
+
+void object_class_foreach_ordered(void (*fn)(ObjectClass *klass, void *opaque),
+                                  const char *implements_type,
+                                  bool include_abstract, void *opaque,
+                                  GCompareFunc compfn)
+{
+    OCFSData data = {
+        .fn = fn,
+        .opaque = opaque,
+    };
+
+    data.classes = g_tree_new(compfn);
+    object_class_foreach(object_class_foreach_ordered_sort,
+                         implements_type, include_abstract, &data);
+    g_tree_foreach(data.classes, object_class_foreach_ordered_tramp, &data);
+    g_tree_destroy(data.classes);
+}
+
 void object_ref(Object *obj)
 {
     obj->ref++;
-- 
1.7.7


Reply via email to