[anjuta/newproject] Change IAnjutaProject interface, reload should work now
- From: Sebastien Granjoux <sgranjoux src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta/newproject] Change IAnjutaProject interface, reload should work now
- Date: Wed, 5 May 2010 20:21:19 +0000 (UTC)
commit 6b0a806236550f97c6c3501e065bc57d0bdd3576
Author: Sébastien Granjoux <seb sfo free fr>
Date: Mon May 3 22:39:16 2010 +0200
Change IAnjutaProject interface, reload should work now
libanjuta/interfaces/libanjuta.idl | 28 ++-
plugins/am-project/am-project.c | 19 ++
plugins/dir-project/dir-project.c | 231 +++++++++---------
plugins/dir-project/dir-project.h | 1 +
plugins/project-manager/plugin.c | 18 --
plugins/project-manager/project.c | 483 ++++++++++++++++++++----------------
6 files changed, 433 insertions(+), 347 deletions(-)
---
diff --git a/libanjuta/interfaces/libanjuta.idl b/libanjuta/interfaces/libanjuta.idl
index e54e750..e125342 100644
--- a/libanjuta/interfaces/libanjuta.idl
+++ b/libanjuta/interfaces/libanjuta.idl
@@ -3079,10 +3079,11 @@ interface IAnjutaProject
/**
* IAnjutaProject::project_updated:
* @obj: Self
+ * @node: Updated node.
*
* This signal is emitted when the project is changed.
*/
- void ::project_updated ();
+ void ::node_updated (gpointer node);
/**
* ianjuta_project_load_node:
@@ -3109,6 +3110,31 @@ interface IAnjutaProject
AnjutaProjectNode *save_node (AnjutaProjectNode *node);
/**
+ * ianjuta_project_new_node:
+ * @obj: Self
+ * @parent: Parent
+ * @type: Node type
+ * @file: Optional file object for the node
+ * @name: Optional name for the node
+ * @err: Error propagation and reporting
+ *
+ * Create a new node
+ *
+ * Return value: The new node, NULL if error
+ */
+ AnjutaProjectNode *new_node (AnjutaProjectNode *parent, AnjutaProjectNodeType type, GFile *file, const gchar *name);
+
+ /**
+ * ianjuta_project_free_node:
+ * @obj: Self
+ * @node: Node
+ * @err: Error propagation and reporting
+ *
+ * Free an already existing node
+ */
+ void free_node (AnjutaProjectNode *node);
+
+ /**
* ianjuta_project_new_root_node:
* @obj: Self
* @file: Project file or directory
diff --git a/plugins/am-project/am-project.c b/plugins/am-project/am-project.c
index 3ad80eb..7010c82 100644
--- a/plugins/am-project/am-project.c
+++ b/plugins/am-project/am-project.c
@@ -3284,6 +3284,23 @@ iproject_save_node (IAnjutaProject *obj, AnjutaProjectNode *node, GError **error
}
static AnjutaProjectNode *
+iproject_new_node (IAnjutaProject *obj, AnjutaProjectNode *parent, AnjutaProjectNodeType type, GFile *file, const gchar *name, GError **err)
+{
+ AnjutaProjectNode *node;
+
+ node = project_node_new (AMP_PROJECT (obj), ANJUTA_PROJECT_ROOT, file, name);
+ node->parent = parent;
+
+ return node;
+}
+
+static AnjutaProjectNode *
+iproject_free_node (IAnjutaProject *obj, AnjutaProjectNode *node, GError **err)
+{
+ project_node_destroy (AMP_PROJECT (obj), node);
+}
+
+static AnjutaProjectNode *
iproject_new_root_node (IAnjutaProject *obj, GFile *file, GError **err)
{
return project_node_new (AMP_PROJECT (obj), ANJUTA_PROJECT_ROOT, file, NULL);
@@ -3358,6 +3375,8 @@ iproject_iface_init(IAnjutaProjectIface* iface)
iface->configure_node = iproject_configure_node;
iface->load_node = iproject_load_node;
iface->save_node = iproject_save_node;
+ iface->new_node = iproject_new_node;
+ iface->free_node = iproject_free_node;
iface->new_root_node = iproject_new_root_node;
iface->add_file_node = iproject_add_file_node;
iface->add_name_node = iproject_add_name_node;
diff --git a/plugins/dir-project/dir-project.c b/plugins/dir-project/dir-project.c
index 847117b..29c46d9 100644
--- a/plugins/dir-project/dir-project.c
+++ b/plugins/dir-project/dir-project.c
@@ -76,6 +76,8 @@ typedef struct _DirGroupData DirGroupData;
struct _DirGroupData {
AnjutaProjectNodeData base;
+ GFileMonitor *monitor;
+ GObject *emitter;
};
typedef struct _DirTargetData DirTargetData;
@@ -135,109 +137,27 @@ static GObject *parent_class;
/* Helper functions
*---------------------------------------------------------------------------*/
-/*
- * File monitoring support --------------------------------
- * FIXME: review these
- */
static void
-monitor_cb (GFileMonitor *monitor,
+on_file_changed (GFileMonitor *monitor,
GFile *file,
GFile *other_file,
GFileMonitorEvent event_type,
gpointer data)
{
- DirProject *project = data;
-
- g_return_if_fail (project != NULL && DIR_IS_PROJECT (project));
+ AnjutaProjectNode *node = data;
+ g_message ("on_file_changed %s type %d emitter %p node %p proxy %d", g_file_get_path (file), event_type, DIR_GROUP_DATA (node)->emitter, node, NODE_DATA (node)->type & ANJUTA_PROJECT_PROXY);
switch (event_type) {
case G_FILE_MONITOR_EVENT_CHANGED:
case G_FILE_MONITOR_EVENT_DELETED:
- /* monitor will be removed here... is this safe? */
- //dir_project_reload (project, NULL);
- g_signal_emit_by_name (G_OBJECT (project), "project-updated");
+ case G_FILE_MONITOR_EVENT_CREATED:
+ g_signal_emit_by_name (DIR_GROUP_DATA (node)->emitter, "node-updated", node);
break;
default:
break;
}
}
-
-static void
-monitor_add (DirProject *project, GFile *file)
-{
- GFileMonitor *monitor = NULL;
-
- g_return_if_fail (project != NULL);
- g_return_if_fail (project->monitors != NULL);
-
- if (file == NULL)
- return;
-
- monitor = g_hash_table_lookup (project->monitors, file);
- if (!monitor) {
- gboolean exists;
-
- /* FIXME clarify if uri is uri, path or both */
- exists = g_file_query_exists (file, NULL);
-
- if (exists) {
- monitor = g_file_monitor_file (file,
- G_FILE_MONITOR_NONE,
- NULL,
- NULL);
- if (monitor != NULL)
- {
- g_signal_connect (G_OBJECT (monitor),
- "changed",
- G_CALLBACK (monitor_cb),
- project);
- g_hash_table_insert (project->monitors,
- g_object_ref (file),
- monitor);
- }
- }
- }
-}
-
-static void
-monitors_remove (DirProject *project)
-{
- g_return_if_fail (project != NULL);
-
- if (project->monitors)
- g_hash_table_destroy (project->monitors);
- project->monitors = NULL;
-}
-
-static void
-group_hash_foreach_monitor (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- DirGroup *group_node = value;
- DirProject *project = user_data;
-
- monitor_add (project, DIR_GROUP_DATA(group_node)->base.file);
-}
-
-static void
-monitors_setup (DirProject *project)
-{
- g_return_if_fail (project != NULL);
-
- monitors_remove (project);
-
- /* setup monitors hash */
- project->monitors = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
- (GDestroyNotify) g_file_monitor_cancel);
-
- monitor_add (project, project->root_file);
-
- if (project->groups)
- g_hash_table_foreach (project->groups, group_hash_foreach_monitor, project);
-}
-
/* Root objects
*---------------------------------------------------------------------------*/
@@ -272,9 +192,10 @@ dir_root_free (AnjutaProjectNode *node)
*---------------------------------------------------------------------------*/
static DirGroup*
-dir_group_new (GFile *file)
+dir_group_new (GFile *file, GObject *emitter)
{
DirGroupData *group = NULL;
+ DirGroup *node;
g_return_val_if_fail (file != NULL, NULL);
@@ -283,8 +204,24 @@ dir_group_new (GFile *file)
group->base.file = g_object_ref (file);
group->base.state = ANJUTA_PROJECT_CAN_ADD_GROUP |
ANJUTA_PROJECT_CAN_REMOVE;
+
+ group->emitter = emitter;
+
+ node = g_node_new (group);
+
+ /* Connect monitor if file exist */
+ if (g_file_query_exists (file, NULL))
+ {
+ group->monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
+
+ g_signal_connect (G_OBJECT (group->monitor),
+ "changed",
+ G_CALLBACK (on_file_changed),
+ node);
+ }
+ g_message ("new group %p monitor %p", node, group->monitor);
- return g_node_new (group);
+ return node;
}
static void
@@ -292,8 +229,10 @@ dir_group_free (DirGroup *node)
{
DirGroupData *group = (DirGroupData *)node->data;
+ if (group->monitor != NULL) g_file_monitor_cancel (group->monitor);
if (group->base.file) g_object_unref (group->base.file);
g_slice_free (DirGroupData, group);
+ g_message ("free group %p monitor %p", node, group->monitor);
g_node_destroy (node);
}
@@ -380,13 +319,33 @@ project_node_destroy (DirProject *project, AnjutaProjectNode *g_node)
}
static AnjutaProjectNode *
-project_node_new (DirProject *project, AnjutaProjectNodeType type, GFile *file, const gchar *name)
+project_node_new (DirProject *project, AnjutaProjectNode *parent, AnjutaProjectNodeType type, GFile *file, const gchar *name, GError **error)
{
AnjutaProjectNode *node = NULL;
switch (type & ANJUTA_PROJECT_TYPE_MASK) {
case ANJUTA_PROJECT_GROUP:
- node = dir_group_new (file);
+ if (file == NULL)
+ {
+ if (name == NULL)
+ {
+ g_set_error (error, IANJUTA_PROJECT_ERROR,
+ IANJUTA_PROJECT_ERROR_VALIDATION_FAILED,
+ _("Missing name"));
+ }
+ else
+ {
+ GFile *group_file;
+
+ group_file = g_file_get_child (anjuta_project_node_get_file (parent), name);
+ node = dir_group_new (group_file, G_OBJECT (project));
+ g_object_unref (group_file);
+ }
+ }
+ else
+ {
+ node = dir_group_new (file, G_OBJECT (project));
+ }
break;
case ANJUTA_PROJECT_SOURCE:
node = dir_source_new (file);
@@ -682,8 +641,11 @@ dir_pattern_stack_is_match (GList *stack, GFile *file)
return match;
}
-static gboolean
-dir_project_list_directory (DirProject *project, DirGroup* parent, GError **error)
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+static AnjutaProjectNode *
+dir_project_load_directory (DirProject *project, AnjutaProjectNode *parent, GError **error)
{
gboolean ok;
GFileEnumerator *enumerator;
@@ -716,18 +678,18 @@ dir_project_list_directory (DirProject *project, DirGroup* parent, GError **erro
/* Create a group for directory */
DirGroup *group;
- group = project_node_new (project, ANJUTA_PROJECT_GROUP, file, NULL);
+ group = project_node_new (project, NULL, ANJUTA_PROJECT_GROUP, file, NULL, NULL);
g_hash_table_insert (project->groups, g_file_get_uri (file), group);
anjuta_project_node_append (parent, group);
- ok = dir_project_list_directory (project, group, error);
- if (!ok) break;
+ group = dir_project_load_directory (project, group, error);
+ if (group == NULL) break;
}
else
{
/* Create a source for files */
DirSource *source;
- source = project_node_new (project, ANJUTA_PROJECT_SOURCE, file, NULL);
+ source = project_node_new (project, NULL, ANJUTA_PROJECT_SOURCE, file, NULL, NULL);
anjuta_project_node_append (parent, source);
}
}
@@ -735,12 +697,9 @@ dir_project_list_directory (DirProject *project, DirGroup* parent, GError **erro
g_object_unref (enumerator);
}
- return ok;
+ return parent;
}
-
-/* Public functions
- *---------------------------------------------------------------------------*/
-
+
static AnjutaProjectNode *
dir_project_load_root (DirProject *project, AnjutaProjectNode *node, GError **error)
{
@@ -765,7 +724,7 @@ dir_project_load_root (DirProject *project, AnjutaProjectNode *node, GError **er
return NULL;
}
- group = project_node_new (project, ANJUTA_PROJECT_GROUP, root_file, NULL);
+ group = project_node_new (project, NULL, ANJUTA_PROJECT_GROUP, root_file, NULL, NULL);
anjuta_project_node_append (node, group);
g_hash_table_insert (project->groups, g_file_get_uri (root_file), group);
@@ -774,9 +733,7 @@ dir_project_load_root (DirProject *project, AnjutaProjectNode *node, GError **er
project->sources = dir_push_pattern_list (NULL, g_object_ref (root_file), source_file, FALSE, NULL);
g_object_unref (source_file);
- dir_project_list_directory (project, group, NULL);
-
- monitors_setup (project);
+ dir_project_load_directory (project, group, NULL);
return node;
}
@@ -788,11 +745,40 @@ dir_project_load_node (DirProject *project, AnjutaProjectNode *node, GError **er
{
case ANJUTA_PROJECT_ROOT:
return dir_project_load_root (project, node, error);
+ case ANJUTA_PROJECT_GROUP:
+ return dir_project_load_directory (project, node, error);
default:
return NULL;
}
}
+static void
+foreach_node_save (AnjutaProjectNode *node,
+ gpointer data)
+{
+ gint type = anjuta_project_node_get_full_type (node);
+
+ if (type & ANJUTA_PROJECT_MODIFIED)
+ {
+ switch (anjuta_project_node_get_type (node))
+ {
+ case ANJUTA_PROJECT_GROUP:
+ g_file_make_directory_with_parents (anjuta_project_node_get_file (node), NULL, NULL);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+AnjutaProjectNode *
+dir_project_save_node (DirProject *project, AnjutaProjectNode *node, GError **error)
+{
+ anjuta_project_node_all_foreach (node, foreach_node_save, project);
+
+ return node;
+}
+
gboolean
dir_project_load (DirProject *project,
GFile *directory,
@@ -813,8 +799,6 @@ dir_project_load (DirProject *project,
void
dir_project_unload (DirProject *project)
{
- monitors_remove (project);
-
/* project data */
/*project_node_destroy (project, project->root_node);
project->root_node = NULL;*/
@@ -997,13 +981,29 @@ iproject_load_node (IAnjutaProject *obj, AnjutaProjectNode *node, GError **err)
static AnjutaProjectNode *
iproject_save_node (IAnjutaProject *obj, AnjutaProjectNode *node, GError **err)
{
- return NULL;
+ return dir_project_save_node (DIR_PROJECT (obj), node, err);
}
static AnjutaProjectNode *
-iproject_new_root_node (IAnjutaProject *obj, GFile *file, GError **err)
+iproject_new_node (IAnjutaProject *obj, AnjutaProjectNode *parent, AnjutaProjectNodeType type, GFile *file, const gchar *name, GError **error)
{
- return project_node_new (DIR_PROJECT (obj), ANJUTA_PROJECT_ROOT, file, NULL);
+ AnjutaProjectNode *node;
+
+ node = project_node_new (DIR_PROJECT (obj), parent, type | ANJUTA_PROJECT_MODIFIED, file, name, error);
+
+ return node;
+}
+
+static void
+iproject_free_node (IAnjutaProject *obj, AnjutaProjectNode *node, GError **err)
+{
+ project_node_destroy (DIR_PROJECT (obj), node);
+}
+
+static AnjutaProjectNode *
+iproject_new_root_node (IAnjutaProject *obj, GFile *file, GError **error)
+{
+ return project_node_new (DIR_PROJECT (obj), NULL, ANJUTA_PROJECT_ROOT, file, NULL, error);
}
static AnjutaProjectNode *
@@ -1025,7 +1025,7 @@ iproject_add_name_node (IAnjutaProject *obj, AnjutaProjectNode *parent, AnjutaPr
file = g_file_get_child (anjuta_project_node_get_file (parent), name);
if (g_file_make_directory (file, NULL, error))
{
- node = project_node_new (DIR_PROJECT (obj), type, file, NULL);
+ node = project_node_new (DIR_PROJECT (obj), NULL, type, file, NULL, NULL);
anjuta_project_node_append (parent, node);
}
g_object_unref (file);
@@ -1081,6 +1081,11 @@ iproject_get_node_info (IAnjutaProject *obj, GError **err)
static void
iproject_iface_init(IAnjutaProjectIface* iface)
{
+ iface->load_node = iproject_load_node;
+ iface->save_node = iproject_save_node;
+ iface->new_node = iproject_new_node;
+ iface->free_node = iproject_free_node;
+
iface->add_group = iproject_add_group;
iface->add_source = iproject_add_source;
iface->add_target = iproject_add_target;
@@ -1091,8 +1096,6 @@ iproject_iface_init(IAnjutaProjectIface* iface)
iface->get_target_types = iproject_get_target_types;
iface->load = iproject_load;
iface->refresh = iproject_refresh;
- iface->load_node = iproject_load_node;
- iface->save_node = iproject_save_node;
iface->new_root_node = iproject_new_root_node;
iface->add_file_node = iproject_add_file_node;
iface->add_name_node = iproject_add_name_node;
diff --git a/plugins/dir-project/dir-project.h b/plugins/dir-project/dir-project.h
index 12b0214..e82cf13 100644
--- a/plugins/dir-project/dir-project.h
+++ b/plugins/dir-project/dir-project.h
@@ -58,6 +58,7 @@ gint dir_project_probe (GFile *directory, GError **error);
gboolean dir_project_load (DirProject *project, GFile *directory, GError **error);
AnjutaProjectNode *dir_project_load_node (DirProject *project, AnjutaProjectNode *node, GError **error);
+AnjutaProjectNode *dir_project_save_node (DirProject *project, AnjutaProjectNode *node, GError **error);
gboolean dir_project_reload (DirProject *project, GError **error);
void dir_project_unload (DirProject *project);
diff --git a/plugins/project-manager/plugin.c b/plugins/project-manager/plugin.c
index e76c3b2..580f2d7 100644
--- a/plugins/project-manager/plugin.c
+++ b/plugins/project-manager/plugin.c
@@ -1224,7 +1224,6 @@ on_project_updated (AnjutaPmProject *project, GError *error, ProjectManagerPlugi
gchar *dirname;
dirname = anjuta_util_get_local_path_from_uri (plugin->project_root_uri);
- status = anjuta_shell_get_status (ANJUTA_PLUGIN (plugin)->shell, NULL);
if (error)
{
GtkWidget *toplevel;
@@ -1265,25 +1264,8 @@ on_project_updated (AnjutaPmProject *project, GError *error, ProjectManagerPlugi
}
}
}
- gchar *basename = g_path_get_basename (dirname);
-
- anjuta_status_progress_tick (status, NULL, _("Update project viewâ?¦"));
- update_ui (plugin);
- anjuta_shell_present_widget (ANJUTA_PLUGIN (plugin)->shell,
- plugin->scrolledwindow,
- NULL);
- anjuta_status_set_default (status, _("Project"), basename);
- g_free (basename);
}
g_free (dirname);
-
- if (plugin->busy)
- {
- anjuta_status_pop (status);
- anjuta_status_busy_pop (status);
- plugin->busy = FALSE;
- }
-
}
static void
diff --git a/plugins/project-manager/project.c b/plugins/project-manager/project.c
index 9f1fece..28fadd6 100644
--- a/plugins/project-manager/project.c
+++ b/plugins/project-manager/project.c
@@ -100,16 +100,23 @@ automatic reload.
typedef enum
{
- LOAD,
- UNLOAD,
+ LOAD = 0,
RELOAD,
- RELOAD_NODE,
- EXIT
+ ADD,
+ EXIT,
+ LAST_COMMAND
} PmCommand;
typedef struct _PmJob PmJob;
-typedef void (*PmJobCallback) (AnjutaPmProject *project, PmJob *job);
+typedef gboolean (*PmCommandFunc) (AnjutaPmProject *project, PmJob *job);
+
+typedef struct _PmCommandWork
+{
+ PmCommandFunc setup;
+ PmCommandFunc worker;
+ PmCommandFunc complete;
+} PmCommandWork;
struct _PmJob
{
@@ -117,7 +124,6 @@ struct _PmJob
GFile *file;
gchar *name;
AnjutaProjectNode *node;
- PmJobCallback callback;
GError *error;
AnjutaProjectNode *proxy;
GHashTable *map;
@@ -135,78 +141,41 @@ enum
static unsigned int signals[LAST_SIGNAL] = { 0 };
+/* Command functions
+ *---------------------------------------------------------------------------*/
+
+static PmCommandWork PmCommands[LAST_COMMAND];
+
+
+/* Forward declarations
+ *---------------------------------------------------------------------------*/
+
+static gboolean pm_project_idle_func (AnjutaPmProject *project);
+static gboolean pm_project_run_command (AnjutaPmProject *project);
+
/* Job functions
*---------------------------------------------------------------------------*/
static PmJob *
-pm_job_new (PmCommand command, GFile *file, const gchar *name, AnjutaProjectNode *node, PmJobCallback callback)
+pm_job_new (PmCommand command, AnjutaProjectNode *node)
{
PmJob *job;
job = g_new0 (PmJob, 1);
job->command = command;
- job->file = file != NULL ? g_object_ref (file) : NULL;
- job->name = name != NULL ? g_strdup (name) : NULL;
- if (node != NULL)
- {
- job->node = node;
- job->proxy = anjuta_project_proxy_new (node);
- g_message ("node %p proxy %p", job->node, job->proxy);
- }
- job->callback = callback;
+ job->node = node;
return job;
}
static void
-pm_free_node (AnjutaProjectNode *node, IAnjutaProject *project)
+pm_job_free (PmJob *job)
{
- gint type = anjuta_project_node_get_full_type (node);
-
- if (type & ANJUTA_PROJECT_PROXY)
- {
- g_message ("free proxy %p", node);
- anjuta_project_proxy_unref (node);
- }
- else
- {
- ianjuta_project_remove_node (project, node, NULL);
- }
-}
-
-static void
-pm_job_free (PmJob *job, IAnjutaProject *project)
-{
- if (job->file != NULL) g_object_unref (job->file);
- if (job->name != NULL) g_free (job->name);
if (job->error != NULL) g_error_free (job->error);
- if ((job->proxy != NULL) && (job->node != NULL))
- {
- g_message ("free proxy %p", job->node);
- anjuta_project_node_all_foreach (job->node, (AnjutaProjectNodeFunc)pm_free_node, project);
- }
if (job->map != NULL) g_hash_table_destroy (job->map);
}
-static void
-pm_project_push_command (AnjutaPmProject *project, PmCommand command, GFile *file, const gchar *name, AnjutaProjectNode *node, PmJobCallback callback)
-{
- PmJob *job;
-
- job = pm_job_new (command, file, name, node, callback);
-
- if (project->busy == 0)
- {
- project->busy++;
- g_async_queue_push (project->work_queue, job);
- }
- else
- {
- g_queue_push_tail (project->job_queue, job);
- }
-}
-
-/* Thread functions
+/* Worker thread functions
*---------------------------------------------------------------------------*/
static gint
@@ -244,7 +213,6 @@ pm_project_map_children (PmJob *job, AnjutaProjectNode *old_node, AnjutaProjectN
GList *same;
same = g_list_find_custom (children, old_node, (GCompareFunc)pm_project_compare_node);
- g_message ("find %p get %p", old_node, same->data);
if (same != NULL)
{
@@ -280,98 +248,74 @@ pm_project_map_node (PmJob *job)
}
}
}
-
-static gpointer
-pm_project_thread_main_loop (AnjutaPmProject *project)
+
+static gboolean
+pm_command_load_work (AnjutaPmProject *project, PmJob *job)
{
- PmJob *job;
+ AnjutaProjectNode *node;
- for (;;)
+ g_message ("thread load node %p", job->proxy);
+ node = ianjuta_project_load_node (project->project, job->proxy, &(job->error));
+ g_message ("thread load node complete");
+ if (job->error == NULL)
{
- AnjutaProjectNode *root;
- AnjutaProjectNode *node;
-
- job = (PmJob *)g_async_queue_pop (project->work_queue);
-
- switch (job->command)
- {
- case LOAD:
- root = ianjuta_project_new_root_node (project->project, job->file, NULL);
- node = ianjuta_project_load_node (project->project, root, &(job->error));
- g_message ("load get root %p node %p, error %p", root, node, job->error);
- if (job->error == NULL)
- {
- job->node = node;
- }
- else
- {
- ianjuta_project_remove_node (project->project, root, NULL);
- }
- break;
- case RELOAD:
- node = ianjuta_project_load_node (project->project, job->node, &(job->error));
- /*if (job->error == NULL)
- {
- job->node = node;
- }*/
- break;
- case RELOAD_NODE:
- g_message ("thread load node %p", job->proxy);
- node = ianjuta_project_load_node (project->project, job->proxy, &(job->error));
- g_message ("thread load node complete");
- if (job->error == NULL)
- {
- pm_project_map_node (job);
- }
- /*if (job->error == NULL)
- {
- job->node = node;
- }*/
- break;
- case EXIT:
- do
- {
- pm_job_free (job, project->project);
- job = (PmJob *)g_async_queue_try_pop (project->done_queue);
- }
- while (job != NULL);
- return NULL;
- default:
- break;
- }
- g_async_queue_push (project->done_queue, job);
+ pm_project_map_node (job);
}
+
+ return TRUE;
}
static gboolean
-pm_project_idle_func (AnjutaPmProject *project)
+pm_command_add_work (AnjutaPmProject *project, PmJob *job)
{
- PmJob *job;
+ AnjutaProjectNode *node;
+
+ node = ianjuta_project_save_node (project->project, job->node, &(job->error));
+
+ return TRUE;
+}
+static gboolean
+pm_command_exit_work (AnjutaPmProject *project, PmJob *job)
+{
+ g_return_val_if_fail (job != NULL, FALSE);
+ g_return_val_if_fail (job->node != NULL, FALSE);
+
+ /* Push job in complete queue as g_thread_exit will stop the thread
+ * immediatly */
+ g_async_queue_push (project->done_queue, job);
+ g_thread_exit (0);
+
+ return TRUE;
+}
+
+/* Run work function in worker thread */
+static gpointer
+pm_project_thread_main_loop (AnjutaPmProject *project)
+{
for (;;)
{
- job = (PmJob *)g_async_queue_try_pop (project->done_queue);
-
- if (job == NULL) return TRUE;
+ PmJob *job;
+ PmCommandFunc func;
+
+ /* Get new job */
+ job = (PmJob *)g_async_queue_pop (project->work_queue);
- if (job->callback != NULL)
- {
- job->callback (project, job);
- }
- pm_job_free (job, project->project);
- project->busy--;
- if (project->busy == 0)
+ /* Get work function and call it if possible */
+ func = PmCommands[job->command].worker;
+ if (func != NULL)
{
- job = g_queue_pop_head (project->job_queue);
- if (job != NULL)
- {
- project->busy = 1;
- g_async_queue_push (project->work_queue, job);
- }
+ func (project, job);
}
+
+ /* Push completed job in queue */
+ g_async_queue_push (project->done_queue, job);
}
}
+/* Main thread functions
+ *---------------------------------------------------------------------------*/
+
static gboolean
pm_project_start_thread (AnjutaPmProject *project, GError **error)
{
@@ -414,7 +358,7 @@ pm_project_stop_thread (AnjutaPmProject *project)
project->idle_func = 0;
// Request to terminate thread
- job = pm_job_new (EXIT, NULL, NULL, NULL, NULL);
+ job = pm_job_new (EXIT, NULL);
g_async_queue_push (project->work_queue, job);
g_thread_join (project->worker);
project->worker = NULL;
@@ -429,7 +373,7 @@ pm_project_stop_thread (AnjutaPmProject *project)
{
job = g_async_queue_try_pop (project->done_queue);
if (job == NULL) break;
- pm_job_free (job, project->project);
+ pm_job_free (job);
}
project->done_queue = NULL;
}
@@ -437,13 +381,59 @@ pm_project_stop_thread (AnjutaPmProject *project)
return TRUE;
}
-/* Public functions
- *---------------------------------------------------------------------------*/
+static void
+pm_free_node (AnjutaProjectNode *node, IAnjutaProject *project)
+{
+ gint type = anjuta_project_node_get_full_type (node);
+
+ if (type & ANJUTA_PROJECT_PROXY)
+ {
+ g_message ("free proxy %p", node);
+ anjuta_project_proxy_unref (node);
+ }
+ else
+ {
+ ianjuta_project_free_node (project, node, NULL);
+ }
+}
-static void on_pm_project_load_incomplete (AnjutaProjectNode *node, AnjutaPmProject *project);
+static void
+pm_project_push_command (AnjutaPmProject *project, PmCommand command, AnjutaProjectNode *node)
+{
+ PmJob *job;
+
+ job = pm_job_new (command, node);
+ g_queue_push_tail (project->job_queue, job);
+
+ pm_project_run_command (project);
+}
static void
-on_pm_project_reloaded_node (AnjutaPmProject *project, PmJob *job)
+on_pm_project_load_incomplete (AnjutaProjectNode *node, AnjutaPmProject *project)
+{
+ gint state = anjuta_project_node_get_state (node);
+
+ if ((state & ANJUTA_PROJECT_INCOMPLETE) && !(state & ANJUTA_PROJECT_LOADING))
+ {
+ project->incomplete_node++;
+ anjuta_project_node_set_state (node, ANJUTA_PROJECT_LOADING);
+ pm_project_push_command (project, RELOAD, node);
+ }
+}
+
+static gboolean
+pm_command_load_setup (AnjutaPmProject *project, PmJob *job)
+{
+ g_return_val_if_fail (job != NULL, FALSE);
+ g_return_val_if_fail (job->node != NULL, FALSE);
+
+ job->proxy = anjuta_project_proxy_new (job->node);
+
+ return TRUE;
+}
+
+static gboolean
+pm_command_load_complete (AnjutaPmProject *project, PmJob *job)
{
if (job->error != NULL)
{
@@ -456,15 +446,11 @@ on_pm_project_reloaded_node (AnjutaPmProject *project, PmJob *job)
else
{
g_message ("reloaded node");
- //g_object_set (G_OBJECT (project->model), "project", project, NULL);
- // Check for incompletely loaded object and load them
- if (anjuta_project_node_get_state (job->proxy) & ANJUTA_PROJECT_INCOMPLETE)
+ if (job->command == LOAD)
{
- project->incomplete_node--;
- g_message ("remaining node %d", project->incomplete_node);
+ g_object_set (G_OBJECT (project->model), "project", project, NULL);
+ project->incomplete_node = 0;
}
- anjuta_project_node_clear_state (job->proxy, ANJUTA_PROJECT_LOADING | ANJUTA_PROJECT_INCOMPLETE);
- anjuta_project_node_all_foreach (job->proxy, (AnjutaProjectNodeFunc)on_pm_project_load_incomplete, project);
if (project->root == job->node)
{
@@ -483,88 +469,145 @@ on_pm_project_reloaded_node (AnjutaPmProject *project, PmJob *job)
}
- if (project->incomplete_node == 0)
+ // Check for incompletely loaded object and load them
+ if (anjuta_project_node_get_state (job->proxy) & ANJUTA_PROJECT_INCOMPLETE)
{
- g_signal_emit (G_OBJECT (project), signals[LOADED], 0, NULL);
+ project->incomplete_node--;
+ g_message ("remaining node %d", project->incomplete_node);
}
- }
-}
-
-static void
-on_pm_project_reloaded (AnjutaPmProject *project, PmJob *job)
-{
- if (job->error != NULL)
- {
- g_warning ("unable to load node");
- pm_project_stop_thread (project);
- g_object_unref (project->project);
- project->project = NULL;
- g_signal_emit (G_OBJECT (project), signals[LOADED], 0, job->error);
- }
- else
- {
-#if 0
- //g_object_set (G_OBJECT (project->model), "project", project, NULL);
- // Check for incompletely loaded object and load them
- anjuta_project_node_clear_state (job->node, ANJUTA_PROJECT_LOADING | ANJUTA_PROJECT_INCOMPLETE);
- g_message ("remaining node %d", project->incomplete_node);
- project->incomplete_node--;
- anjuta_project_node_all_foreach (job->node, (AnjutaProjectNodeFunc)on_pm_project_load_incomplete, project);
- //g_signal_emit (G_OBJECT (project), signals[UPDATED], 0, job->error);
- gbf_project_model_update_tree (project->model, NULL, NULL, NULL);
+ anjuta_project_node_clear_state (job->proxy, ANJUTA_PROJECT_LOADING | ANJUTA_PROJECT_INCOMPLETE);
+ anjuta_project_node_all_foreach (job->proxy, (AnjutaProjectNodeFunc)on_pm_project_load_incomplete, project);
if (project->incomplete_node == 0)
{
- g_signal_emit (G_OBJECT (project), signals[LOADED], 0, NULL);
+ g_signal_emit (G_OBJECT (project), signals[job->command == LOAD ? LOADED : UPDATED], 0, NULL);
}
-#endif
}
+ anjuta_project_node_all_foreach (job->node, (AnjutaProjectNodeFunc)pm_free_node, project->project);
+
+ return TRUE;
}
-static void
-on_pm_project_load_incomplete (AnjutaProjectNode *node, AnjutaPmProject *project)
+static gboolean
+pm_command_add_setup (AnjutaPmProject *project, PmJob *job)
{
- gint state = anjuta_project_node_get_state (node);
+ AnjutaProjectNode *parent;
- if ((state & ANJUTA_PROJECT_INCOMPLETE) && !(state & ANJUTA_PROJECT_LOADING))
+ g_return_val_if_fail (job != NULL, FALSE);
+ g_return_val_if_fail (job->node != NULL, FALSE);
+
+ /* Add new node in project tree.
+ * It is safe to do it here because the worker thread is waiting */
+ parent = anjuta_project_node_parent (job->node);
+ g_message ("parent %p node name %s", parent, anjuta_project_node_get_name (job->node));
+ anjuta_project_node_insert_before (parent, NULL, job->node);
+
+ return TRUE;
+}
+
+static PmCommandWork PmCommands[LAST_COMMAND] = {
+ {pm_command_load_setup,
+ pm_command_load_work,
+ pm_command_load_complete},
+ {pm_command_load_setup,
+ pm_command_load_work,
+ pm_command_load_complete},
+ {pm_command_add_setup,
+ pm_command_add_work,
+ NULL},
+ {NULL,
+ pm_command_exit_work,
+ NULL}};
+
+/* Run a command in job queue */
+static gboolean
+pm_project_run_command (AnjutaPmProject *project)
+{
+ gboolean running = TRUE;
+
+ if (project->busy == 0)
{
- project->incomplete_node++;
- anjuta_project_node_set_state (node, ANJUTA_PROJECT_LOADING);
- pm_project_push_command (project, RELOAD_NODE, NULL, NULL, node, on_pm_project_reloaded_node);
+ /* Worker thread is waiting for new command, check job queue */
+ PmJob *job;
+
+ do
+ {
+ PmCommandFunc func;
+
+ /* Get next command */
+ job = g_queue_pop_head (project->job_queue);
+ running = job != NULL;
+ if (!running) break;
+
+ /* Get setup function and call it if possible */
+ func = PmCommands[job->command].setup;
+ if (func != NULL)
+ {
+ running = func (project, job);
+ }
+
+ if (running)
+ {
+ /* Execute work function in the worker thread */
+ project->busy = 1;
+
+ if (project->idle_func == 0)
+ {
+ project->idle_func = g_idle_add ((GSourceFunc) pm_project_idle_func, project);
+ }
+ g_async_queue_push (project->work_queue, job);
+ }
+ else
+ {
+ /* Discard command */
+ pm_job_free (job);
+ }
+ } while (!running);
}
+
+ return running;
}
-static void
-on_pm_project_loaded (AnjutaPmProject *project, PmJob *job)
+static gboolean
+pm_project_idle_func (AnjutaPmProject *project)
{
- if (job->error != NULL)
- {
- g_warning ("unable to load project");
- /* Unable to load project, destroy project object */
- pm_project_stop_thread (project);
- g_object_unref (project->project);
- project->project = NULL;
- g_signal_emit (G_OBJECT (project), signals[LOADED], 0, job->error);
- }
- else
+ gboolean running;
+
+ for (;;)
{
- g_message ("project loaded project root %p node %p", anjuta_pm_project_get_root (project), job->node);
- g_message ("root child %d", g_node_n_children (job->node));
- g_message ("root all nodes %d", g_node_n_nodes (job->node, G_TRAVERSE_ALL));
- project->root = job->node;
- g_object_set (G_OBJECT (project->model), "project", project, NULL);
- gbf_project_model_update_tree (project->model, project->root, NULL, NULL);
+ PmCommandFunc func;
+ PmJob *job;
- // Check for incompletely loaded object and load them
- project->incomplete_node = 0;
- anjuta_project_node_all_foreach (job->node, (AnjutaProjectNodeFunc)on_pm_project_load_incomplete, project);
- if (project->incomplete_node == 0)
+ /* Get completed command */
+ job = (PmJob *)g_async_queue_try_pop (project->done_queue);
+ if (job == NULL) break;
+
+ /* Get complete function and call it if possible */
+ func = PmCommands[job->command].complete;
+ if (func != NULL)
{
- g_signal_emit (G_OBJECT (project), signals[LOADED], 0, NULL);
+ running = func (project, job);
}
+ pm_job_free (job);
+ project->busy--;
}
+
+ running = pm_project_run_command (project);
+ if (!running) project->idle_func = 0;
+
+ return running;
}
+/* Public functions
+ *---------------------------------------------------------------------------*/
+
+static void
+on_node_updated (IAnjutaProject *sender, AnjutaProjectNode *node, AnjutaPmProject *project)
+{
+ g_message ("on node updated");
+ pm_project_push_command (project, RELOAD, node);
+}
+
gboolean
anjuta_pm_project_load (AnjutaPmProject *project, GFile *file, GError **error)
{
@@ -647,16 +690,22 @@ anjuta_pm_project_load (AnjutaPmProject *project, GFile *file, GError **error)
{
return FALSE;
}
-
- pm_project_push_command (project, LOAD, file, NULL, NULL, on_pm_project_loaded);
-
+ g_message ("connect node-update %p", project->project);
+ g_signal_connect (G_OBJECT (project->project),
+ "node-updated",
+ G_CALLBACK (on_node_updated),
+ project);
+
+ project->root = ianjuta_project_new_node (project->project, NULL, ANJUTA_PROJECT_ROOT, file, NULL, NULL);
+ pm_project_push_command (project, LOAD, project->root);
+
return TRUE;
}
-gboolean
+static gboolean
anjuta_pm_project_reload_node (AnjutaPmProject *project, AnjutaProjectNode *node, GError **error)
{
- pm_project_push_command (project, RELOAD, NULL, NULL, node, on_pm_project_reloaded);
+ pm_project_push_command (project, RELOAD, node);
return TRUE;
}
@@ -681,7 +730,8 @@ gboolean
anjuta_pm_project_refresh (AnjutaPmProject *project, GError **error)
{
g_message ("reload project");
- pm_project_push_command (project, RELOAD_NODE, NULL, NULL, project->root, on_pm_project_reloaded_node);
+
+ pm_project_push_command (project, RELOAD, project->root);
return TRUE;
}
@@ -722,9 +772,14 @@ anjuta_pm_project_get_packages (AnjutaPmProject *project)
AnjutaProjectNode *
anjuta_pm_project_add_group (AnjutaPmProject *project, AnjutaProjectNode *group, const gchar *name, GError **error)
{
+ AnjutaProjectNode *node;
+
g_return_val_if_fail (project->project != NULL, NULL);
- return ianjuta_project_add_name_node (project->project, group, NULL, ANJUTA_PROJECT_GROUP, name, error);
+ node = ianjuta_project_new_node (project->project, group, ANJUTA_PROJECT_GROUP, NULL, name, error);
+ pm_project_push_command (project, ADD, node);
+
+ return node;
}
AnjutaProjectNode *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]