[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