[Workman-devel] [PATCH] Add calls to WorkmanPlugin functions

Josh Poimboeuf jpoimboe at redhat.com
Tue Apr 2 20:23:27 UTC 2013


Add calls throughout libworkman to call into the plugin where needed.
For the setter functions, this also requres updating any local data
structures afterwards.
---
 workman/workman-attribute.c         | 28 ++++++++++----
 workman/workman-consumer.c          | 74 +++++++++++++++++++++++++++++++++----
 workman/workman-manager.c           | 70 ++++++++++++++++++++++++++++-------
 workman/workman-manager.h           |  2 +-
 workman/workman-object.c            | 26 +++++++++----
 workman/workman-partition-private.h |  4 ++
 workman/workman-partition.c         | 63 ++++++++++++++++++++++++++++++-
 7 files changed, 229 insertions(+), 38 deletions(-)

diff --git a/workman/workman-attribute.c b/workman/workman-attribute.c
index 8fd00f4..6bd54e3 100644
--- a/workman/workman-attribute.c
+++ b/workman/workman-attribute.c
@@ -269,24 +269,38 @@ GVariant *workman_attribute_get_value(WorkmanAttribute *attr)
  * Returns: %TRUE if the operation succeeded
  */
 gboolean
-workman_attribute_set_value(WorkmanAttribute *attr,
+workman_attribute_set_value(WorkmanAttribute *self,
                             GVariant *value,
                             GError **error)
 {
+    WorkmanPlugin *plugin;
+    gboolean ret;
+
     g_return_val_if_fail(value != NULL, FALSE);
+    g_return_val_if_fail(self->priv->writable, FALSE);
 
-    if (attr->priv->value) {
-        const GVariantType *old_type = g_variant_get_type(attr->priv->value);
+    /* Make sure the new type matches the previous type */
+    if (self->priv->value) {
+        const GVariantType *old_type = g_variant_get_type(self->priv->value);
         const GVariantType *new_type = g_variant_get_type(value);
 
         g_return_val_if_fail(g_variant_type_equal(old_type, new_type),
                              FALSE);
-
-        g_variant_unref(attr->priv->value);
     }
 
-    attr->priv->value = value;
-    g_variant_ref_sink(attr->priv->value);
+    /* Tell the plugin to change the value */
+    plugin = workman_object_get_plugin(self->priv->object);
+    g_return_val_if_fail(plugin, FALSE);
+
+    ret = workman_plugin_update_attribute(plugin, self, value, error);
+    g_object_unref(plugin);
+    if (!ret)
+        return FALSE;
+
+    /* Update our object accordingly */
+    g_variant_unref(self->priv->value);
+    self->priv->value = value;
+    g_variant_ref_sink(self->priv->value);
 
     return TRUE;
 }
diff --git a/workman/workman-consumer.c b/workman/workman-consumer.c
index b99b74c..6a9fb55 100644
--- a/workman/workman-consumer.c
+++ b/workman/workman-consumer.c
@@ -24,6 +24,8 @@
 
 #include "workman.h"
 #include "workman-consumer-private.h"
+#include "workman-object-private.h"
+#include "workman-partition-private.h"
 
 G_DEFINE_TYPE(WorkmanConsumer, workman_consumer, WORKMAN_TYPE_OBJECT);
 
@@ -189,16 +191,54 @@ workman_consumer_set_partition_priv(WorkmanConsumer *self,
 }
 
 gboolean
-workman_consumer_set_partition(WorkmanConsumer *consumer,
+workman_consumer_set_partition(WorkmanConsumer *self,
                                WorkmanState state,
                                WorkmanPartition *partition,
                                GError **error)
 {
-    /* TODO:
-     * - ensure state is compatible with consumer and partition states
-     * - call plugin->set_parent
-     * - update private data structure
-     */
+    WorkmanObject *self_obj, *part_obj;
+    WorkmanState self_state, part_state;
+    WorkmanPlugin *plugin;
+    gboolean ret;
+
+    /* Make sure the states are consistent */
+    self_obj = WORKMAN_OBJECT(self);
+    self_state = workman_object_get_state(self_obj, NULL);
+    g_return_val_if_fail(self_state & state, FALSE);
+
+    part_obj = WORKMAN_OBJECT(partition);
+    part_state = workman_object_get_state(part_obj, NULL);
+    g_return_val_if_fail(part_state & state, FALSE);
+
+    /* Tell the plugin to set the consumer's new partition */
+    plugin = workman_object_get_plugin(self_obj);
+    g_return_val_if_fail(plugin, FALSE);
+
+    ret = workman_plugin_set_object_parent(plugin,
+                                           state,
+                                           self_obj,
+                                           part_obj,
+                                           error);
+    g_object_unref(plugin);
+
+    if (!ret)
+        return FALSE;
+
+    /* Update the object pointers to match reality */
+    if (state & WORKMAN_STATE_ACTIVE)
+        workman_partition_remove_consumer_priv(self->priv->partition_active,
+                                               WORKMAN_STATE_ACTIVE,
+                                               self);
+
+    if (state & WORKMAN_STATE_PERSISTENT)
+        workman_partition_remove_consumer_priv(self->priv->partition_persistent,
+                                               WORKMAN_STATE_PERSISTENT,
+                                               self);
+
+    workman_consumer_set_partition_priv(self, state, partition);
+    workman_partition_add_consumer_priv(partition, state, self);
+
+    return TRUE;
 }
 
 
@@ -240,8 +280,26 @@ gboolean
 workman_consumer_refresh_processes(WorkmanConsumer *self,
                                    GError **error)
 {
-    /* TODO: call plugin */
-    return FALSE;
+    GList *tmp_list;
+    GError *tmp_error = NULL;
+
+    WorkmanObject *object = WORKMAN_OBJECT(self);
+    WorkmanPlugin *plugin = workman_object_get_plugin(object);
+    g_return_val_if_fail(plugin, FALSE);
+
+    /* Call the plugin */
+    tmp_list = workman_plugin_get_object_processes(plugin, object, &tmp_error);
+    g_object_unref(plugin);
+    if (tmp_error) {
+        g_propagate_error(error, tmp_error);
+        return FALSE;
+    }
+
+    /* Refresh our local process list */
+    g_boxed_free(WORKMAN_TYPE_PROCESS_LIST, self->priv->processes);
+    self->priv->processes = g_boxed_copy(WORKMAN_TYPE_PROCESS_LIST, tmp_list);
+
+    return TRUE;
 }
 
 
diff --git a/workman/workman-manager.c b/workman/workman-manager.c
index 1e46e4d..4a8e910 100644
--- a/workman/workman-manager.c
+++ b/workman/workman-manager.c
@@ -181,13 +181,50 @@ workman_manager_get_default(GError **error)
  * Returns: (transfer full): the new partition
  */
 WorkmanPartition *
-workman_manager_add_partition(WorkmanManager *mgr,
-                              const gchar *name,
+workman_manager_add_partition(WorkmanManager *self,
                               WorkmanState state,
+                              const gchar *name,
                               WorkmanPartition *parent,
                               GError **error)
 {
-    /* TODO: call add_partition on each plugin until one succeeds */
+    GList *p;
+    WorkmanState child_state;
+    WorkmanObject *parent_obj = WORKMAN_OBJECT(parent);
+
+    /* Make sure the states are consistent */
+    child_state = workman_object_get_state(parent_obj, NULL);
+    g_return_val_if_fail(child_state & state, NULL);
+
+    /* Call add_partition on each plugin until one succeeds */
+    for (p = self->priv->plugins; p; p = p->next) {
+        GError *tmp_error = NULL;
+        WorkmanPlugin *plugin = WORKMAN_PLUGIN(p->data);
+        WorkmanPartition *part;
+
+        part = WORKMAN_PARTITION(workman_plugin_add_object(plugin,
+                                                           state,
+                                                           name,
+                                                           parent_obj,
+                                                           &tmp_error));
+        if (tmp_error) {
+            g_propagate_error(error, tmp_error);
+            return NULL;
+        }
+
+        if (!part)
+            continue;
+
+        /*
+         * The partition was successfully added.  Update our data structures
+         * accordingly and return the new partition.
+         * */
+        if (parent)
+            workman_partition_add_child_priv(parent, state, part);
+
+        self->priv->objects = g_list_append(self->priv->objects, part);
+        return g_object_ref(part);
+    }
+
     return NULL;
 }
 
@@ -199,7 +236,10 @@ workman_manager_remove_partition(WorkmanManager *self,
 {
     WorkmanObject *object;
     WorkmanState obj_state;
+    WorkmanPlugin *plugin;
+    WorkmanPartition *parent;
     GList *list = NULL;
+    gboolean ret;
 
     object = WORKMAN_OBJECT(partition);
     obj_state = workman_object_get_state(object, error);
@@ -218,12 +258,19 @@ workman_manager_remove_partition(WorkmanManager *self,
         return FALSE;
     }
 
-    /* TODO:
+    /* Call the plugin to make the change */
     plugin = workman_object_get_plugin(object);
-    ret = workman_plugin_remove_partition(plugin, partition, state, error);
+    ret = workman_plugin_remove_object(plugin, state, object, error);
+    g_object_unref(plugin);
     if (!ret)
         return FALSE;
-    */
+
+    /* Update our data structures to match the new reality */
+    parent = workman_partition_get_parent(partition, state, NULL);
+    if (parent) {
+        workman_partition_remove_child_priv(parent, state, partition);
+        g_object_unref(parent);
+    }
 
     if (obj_state == state || state == WORKMAN_STATE_ALL) {
         self->priv->objects = g_list_remove(self->priv->objects, object);
@@ -300,7 +347,7 @@ gboolean
 workman_manager_refresh_objects(WorkmanManager *self,
                                 GError **error)
 {
-    GList *o = NULL, *plugin_objs = NULL;
+    GList *o, *p, *plugin_objs = NULL;
     WorkmanManagerPrivate *priv = self->priv;
 
      /*
@@ -315,7 +362,6 @@ workman_manager_refresh_objects(WorkmanManager *self,
      */
 
     /* Get all objects from all plugins */
-    /* TODO:
     for (p = priv->plugins; p; p = p->next) {
         GError *tmp_error = NULL;
         WorkmanPlugin *plugin = WORKMAN_PLUGIN(p->data);
@@ -329,26 +375,24 @@ workman_manager_refresh_objects(WorkmanManager *self,
             return FALSE;
         }
     }
-    */
 
     g_boxed_free(WORKMAN_TYPE_OBJECT_LIST, priv->objects);
     priv->objects = NULL;
 
     /* Copy all plugin-owned objects, ignoring placeholder objects */
-    /* TODO:
     for (o = plugin_objs; o; o = o->next) {
         WorkmanObject *object = WORKMAN_OBJECT(o->data);
-        if (workman_object_get_plugin(o, NULL)) {
+        WorkmanPlugin *plugin = workman_object_get_plugin(object);
+        if (plugin) {
 
             g_object_unref(plugin);
 
             g_return_val_if_fail(!g_list_find(priv->objects, object), FALSE);
 
-            priv->objs = g_list_append(priv->objs, object);
+            priv->objects = g_list_append(priv->objects, object);
             g_object_ref(object);
         }
     }
-    */
 
     /*
      * Now go through the consumers and translate their placeholder partition
diff --git a/workman/workman-manager.h b/workman/workman-manager.h
index 8b9927f..da45ff3 100644
--- a/workman/workman-manager.h
+++ b/workman/workman-manager.h
@@ -68,8 +68,8 @@ GType workman_manager_get_type(void);
 WorkmanManager *workman_manager_get_default(GError **error);
 
 WorkmanPartition *workman_manager_add_partition(WorkmanManager *mgr,
-                                                const gchar *name,
                                                 WorkmanState state,
+                                                const gchar *name,
                                                 WorkmanPartition *parent,
                                                 GError **error);
 
diff --git a/workman/workman-object.c b/workman/workman-object.c
index b8ad679..b5bcee8 100644
--- a/workman/workman-object.c
+++ b/workman/workman-object.c
@@ -260,15 +260,27 @@ gboolean workman_object_refresh_attributes(WorkmanObject *self,
                                            WorkmanState state,
                                            GError **error)
 {
-    /* TODO: call plugin->get_attributes and update obj->priv->attributes */
-}
+    GList *tmp_list;
+    GError *tmp_error = NULL;
+
+    g_return_val_if_fail(self->priv->plugin, FALSE);
+
+    /* Get the attributes from the plugin */
+    tmp_list = workman_plugin_get_object_attributes(self->priv->plugin,
+                                                    state,
+                                                    self,
+                                                    &tmp_error);
+    if (tmp_error) {
+        g_propagate_error(error, tmp_error);
+        return FALSE;
+    }
 
+    /* Update our attribute list accordingly */
+    g_boxed_free(WORKMAN_TYPE_ATTRIBUTE_LIST, self->priv->attributes);
+    self->priv->attributes = g_boxed_copy(WORKMAN_TYPE_ATTRIBUTE_LIST,
+                                          tmp_list);
 
-gboolean workman_object_save_attributes(WorkmanObject *self,
-                                        WorkmanState state,
-                                        GError **error)
-{
-    /* TODO: call plugin->update_attribute for each changed attribute */
+    return TRUE;
 }
 
 
diff --git a/workman/workman-partition-private.h b/workman/workman-partition-private.h
index 2edf441..ee36c1a 100644
--- a/workman/workman-partition-private.h
+++ b/workman/workman-partition-private.h
@@ -45,6 +45,10 @@ void workman_partition_remove_child_priv(WorkmanPartition *partition,
                                          WorkmanState state,
                                          WorkmanPartition *child);
 
+void workman_partition_set_parent_priv(WorkmanPartition *partition,
+                                       WorkmanState state,
+                                       WorkmanPartition *parent);
+
 WorkmanPartition *workman_partition_new(const gchar *name,
                                         WorkmanState state,
                                         GList *attributes,
diff --git a/workman/workman-partition.c b/workman/workman-partition.c
index 76243ca..6f31d89 100644
--- a/workman/workman-partition.c
+++ b/workman/workman-partition.c
@@ -23,6 +23,7 @@
 #include <config.h>
 
 #include "workman.h"
+#include "workman-object-private.h"
 #include "workman-partition-private.h"
 
 G_DEFINE_TYPE(WorkmanPartition, workman_partition, WORKMAN_TYPE_OBJECT);
@@ -323,8 +324,49 @@ workman_partition_set_parent(WorkmanPartition *self,
                              WorkmanPartition *parent,
                              GError **error)
 {
-    /* TODO: call plugin->set_parent and update obj->priv->parent */
-    return FALSE;
+    WorkmanObject *self_obj, *parent_obj;
+    WorkmanState self_state, parent_state;
+    WorkmanPlugin *plugin;
+    gboolean ret;
+
+    /* Make sure the states are consistent */
+    self_obj = WORKMAN_OBJECT(self);
+    self_state = workman_object_get_state(self_obj, NULL);
+    g_return_val_if_fail(self_state & state, FALSE);
+
+    parent_obj = WORKMAN_OBJECT(parent);
+    parent_state = workman_object_get_state(parent_obj, NULL);
+    g_return_val_if_fail(parent_state & state, FALSE);
+
+    /* Tell the plugin to move the partition */
+    plugin = workman_object_get_plugin(self_obj);
+    g_return_val_if_fail(plugin, FALSE);
+
+    ret = workman_plugin_set_object_parent(plugin,
+                                           state,
+                                           self_obj,
+                                           parent_obj,
+                                           error);
+    g_object_unref(plugin);
+
+    if (!ret)
+        return FALSE;
+
+    /* Update the object pointers to match reality */
+    if (state & WORKMAN_STATE_ACTIVE)
+        workman_partition_remove_child_priv(self->priv->parent_active,
+                                            WORKMAN_STATE_ACTIVE,
+                                            self);
+
+    if (state & WORKMAN_STATE_PERSISTENT)
+        workman_partition_remove_child_priv(self->priv->parent_persistent,
+                                            WORKMAN_STATE_PERSISTENT,
+                                            self);
+
+    workman_partition_set_parent_priv(self, state, parent);
+    workman_partition_add_child_priv(parent, state, self);
+
+    return TRUE;
 }
 
 
@@ -408,6 +450,23 @@ workman_partition_remove_consumer_priv(WorkmanPartition *self,
 
 
 void
+workman_partition_set_parent_priv(WorkmanPartition *self,
+                                  WorkmanState state,
+                                  WorkmanPartition *parent)
+{
+    if (state & WORKMAN_STATE_ACTIVE) {
+        g_object_unref(self->priv->parent_active);
+        self->priv->parent_active = g_object_ref(parent);
+    }
+
+    if (state & WORKMAN_STATE_PERSISTENT) {
+        g_object_unref(self->priv->parent_persistent);
+        self->priv->parent_persistent = g_object_ref(parent);
+    }
+}
+
+
+void
 workman_partition_add_child_priv(WorkmanPartition *self,
                                  WorkmanState state,
                                  WorkmanPartition *child)
-- 
1.7.11.7




More information about the Workman-devel mailing list