[anjuta] symbol-db: fixed some issues related to local-view
- From: Massimo Cora' <mcora src gnome org>
- To: svn-commits-list gnome org
- Subject: [anjuta] symbol-db: fixed some issues related to local-view
- Date: Tue, 21 Jul 2009 17:47:30 +0000 (UTC)
commit 5ee8e6cbb09400543ce6cd92b14bc8c4a9e06ff9
Author: Massimo Corà <mcora src gnome org>
Date: Tue Jul 21 19:45:36 2009 +0200
symbol-db: fixed some issues related to local-view
we can have a weird behaviour updating the buffer if we're not paying the right attention:
a timeout scan could have been launched and a millisecond later the user could
have switched editor: we'll be getting the symbol inserted in the previous
editor into the new one's view, creating confusion.
plugins/symbol-db/plugin.c | 135 +++++++++++++++++++++--------
plugins/symbol-db/plugin.h | 10 ++-
plugins/symbol-db/symbol-db-engine-core.c | 6 +-
plugins/symbol-db/symbol-db-prefs.c | 2 +-
plugins/symbol-db/symbol-db-view-locals.c | 106 ++++++++++++++++++++---
5 files changed, 205 insertions(+), 54 deletions(-)
---
diff --git a/plugins/symbol-db/plugin.c b/plugins/symbol-db/plugin.c
index 21e8e3b..def1b52 100644
--- a/plugins/symbol-db/plugin.c
+++ b/plugins/symbol-db/plugin.c
@@ -351,33 +351,6 @@ enable_view_signals (SymbolDBPlugin *sdb_plugin, gboolean enable, gboolean force
}
}
-static void
-on_editor_buffer_symbol_update_scan_end (SymbolDBEngine *dbe, gint process_id,
- gpointer data)
-{
- SymbolDBPlugin *sdb_plugin;
- gint i;
-
- sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (data);
-
- /* search for the proc id */
- for (i = 0; i < sdb_plugin->buffer_update_ids->len; i++)
- {
- if (g_ptr_array_index (sdb_plugin->buffer_update_ids, i) == GINT_TO_POINTER (process_id))
- {
- gchar *str;
- /* hey we found it */
- /* remove both the items */
- g_ptr_array_remove_index (sdb_plugin->buffer_update_ids, i);
-
- str = (gchar*)g_ptr_array_remove_index (sdb_plugin->buffer_update_files,
- i);
- /* we can now free it */
- g_free (str);
- }
- }
-}
-
static gboolean
on_editor_buffer_symbols_update_timeout (gpointer user_data)
{
@@ -491,6 +464,76 @@ on_editor_buffer_symbols_update_timeout (gpointer user_data)
}
static void
+on_editor_buffer_symbol_update_scan_end (SymbolDBEngine *dbe, gint process_id,
+ gpointer data)
+{
+ SymbolDBPlugin *sdb_plugin;
+ gint i;
+
+ sdb_plugin = ANJUTA_PLUGIN_SYMBOL_DB (data);
+
+ /* search for the proc id */
+ for (i = 0; i < sdb_plugin->buffer_update_ids->len; i++)
+ {
+ if (g_ptr_array_index (sdb_plugin->buffer_update_ids, i) == GINT_TO_POINTER (process_id))
+ {
+ gchar *str;
+ /* hey we found it */
+ /* remove both the items */
+ g_ptr_array_remove_index (sdb_plugin->buffer_update_ids, i);
+
+ str = (gchar*)g_ptr_array_remove_index (sdb_plugin->buffer_update_files,
+ i);
+ /* we can now free it */
+ g_free (str);
+ }
+ }
+
+ /* was the updating of view-locals symbols blocked while we were scanning?
+ * e.g. was the editor switched? */
+ if (sdb_plugin->buffer_update_semaphore == TRUE)
+ {
+ GFile *file;
+ gchar *local_path;
+ gboolean tags_update;
+ if (!IANJUTA_IS_EDITOR (sdb_plugin->current_editor))
+ return;
+
+ file = ianjuta_file_get_file (IANJUTA_FILE (sdb_plugin->current_editor),
+ NULL);
+
+ if (file == NULL)
+ return;
+
+ local_path = g_file_get_path (file);
+
+ if (local_path == NULL)
+ {
+ g_critical ("local_path == NULL");
+ return;
+ }
+
+ symbol_db_view_locals_update_list (
+ SYMBOL_DB_VIEW_LOCALS (sdb_plugin->dbv_view_tree_locals),
+ sdb_plugin->sdbe_project, local_path, FALSE);
+
+ /* add a default timeout to the updating of buffer symbols */
+ tags_update = anjuta_preferences_get_bool (sdb_plugin->prefs, BUFFER_AUTOSCAN);
+
+ if (tags_update)
+ {
+ sdb_plugin->buf_update_timeout_id =
+ g_timeout_add_seconds (TIMEOUT_INTERVAL_SYMBOLS_UPDATE,
+ on_editor_buffer_symbols_update_timeout,
+ sdb_plugin);
+ }
+
+ g_free (local_path);
+
+ }
+}
+
+static void
on_editor_destroy (SymbolDBPlugin *sdb_plugin, IAnjutaEditor *editor)
{
const gchar *uri;
@@ -639,10 +682,33 @@ value_added_current_editor (AnjutaPlugin *plugin, const char *name,
g_critical ("local_path == NULL");
return;
}
+
+ /* we can have a weird behaviour here if we're not paying the right attention:
+ * A timeout scan could have been launched and a millisecond later the user could
+ * have switched editor: we'll be getting the symbol inserted in the previous
+ * editor into the new one's view.
+ */
+ if (sdb_plugin->buffer_update_files->len > 0)
+ {
+ sdb_plugin->buffer_update_semaphore = TRUE;
+ }
+ else
+ {
+ symbol_db_view_locals_update_list (
+ SYMBOL_DB_VIEW_LOCALS (sdb_plugin->dbv_view_tree_locals),
+ sdb_plugin->sdbe_project, local_path, FALSE);
+
+ /* add a default timeout to the updating of buffer symbols */
+ tags_update = anjuta_preferences_get_bool (sdb_plugin->prefs, BUFFER_AUTOSCAN);
- symbol_db_view_locals_update_list (
- SYMBOL_DB_VIEW_LOCALS (sdb_plugin->dbv_view_tree_locals),
- sdb_plugin->sdbe_project, local_path, FALSE);
+ if (tags_update)
+ {
+ sdb_plugin->buf_update_timeout_id =
+ g_timeout_add_seconds (TIMEOUT_INTERVAL_SYMBOLS_UPDATE,
+ on_editor_buffer_symbols_update_timeout,
+ plugin);
+ }
+ }
if (g_hash_table_lookup (sdb_plugin->editor_connected, editor) == NULL)
{
@@ -673,14 +739,6 @@ value_added_current_editor (AnjutaPlugin *plugin, const char *name,
g_free (uri);
g_free (local_path);
- /* add a default timeout to the updating of buffer symbols */
- tags_update = anjuta_preferences_get_bool (sdb_plugin->prefs, BUFFER_AUTOSCAN);
-
- if (tags_update)
- sdb_plugin->buf_update_timeout_id =
- g_timeout_add_seconds (TIMEOUT_INTERVAL_SYMBOLS_UPDATE,
- on_editor_buffer_symbols_update_timeout,
- plugin);
sdb_plugin->need_symbols_update = FALSE;
}
@@ -2180,6 +2238,7 @@ symbol_db_activate (AnjutaPlugin *plugin)
*/
sdb_plugin->buffer_update_files = g_ptr_array_new ();
sdb_plugin->buffer_update_ids = g_ptr_array_new ();
+ sdb_plugin->buffer_update_semaphore = FALSE;
sdb_plugin->is_offline_scanning = FALSE;
sdb_plugin->is_project_importing = FALSE;
diff --git a/plugins/symbol-db/plugin.h b/plugins/symbol-db/plugin.h
index c435766..c4edceb 100644
--- a/plugins/symbol-db/plugin.h
+++ b/plugins/symbol-db/plugin.h
@@ -72,6 +72,12 @@ struct _SymbolDBPlugin {
GTimer *update_timer;
GPtrArray *buffer_update_files;
GPtrArray *buffer_update_ids;
+ gboolean buffer_update_semaphore; /* it monitors the update status of the
+ * buffer _and_ the editor switching.
+ * A new page cannot be updated with the
+ * new view-locals symbols if a scanning
+ * is in progress
+ */
guint editor_watch_id;
gchar *project_root_uri;
gchar *project_root_dir;
@@ -130,7 +136,9 @@ struct _SymbolDBPlugin {
gchar *current_scanned_package;
GList *session_packages;
- GTree *proc_id_tree;
+ GTree *proc_id_tree; /* the scan processes'll receive an id from
+ * the symbol engine when scan-end happens.
+ * Track them here */
gboolean is_project_importing; /* refreshes or resumes after abort */
gboolean is_project_updating; /* makes up to date symbols of the project's files */
diff --git a/plugins/symbol-db/symbol-db-engine-core.c b/plugins/symbol-db/symbol-db-engine-core.c
index 779017d..9f0c8e7 100644
--- a/plugins/symbol-db/symbol-db-engine-core.c
+++ b/plugins/symbol-db/symbol-db-engine-core.c
@@ -5984,12 +5984,12 @@ symbol_db_engine_update_buffer_symbols (SymbolDBEngine * dbe, const gchar *proje
/* in case we didn't have any good buffer to scan...*/
ret_id = -1;
- /* it may happens that no buffer is correctly set up */
+ /* it may happen that no buffer is correctly set up */
if (real_files_on_db->len > 0)
{
/* data will be freed when callback will be called. The signal will be
- * disconnected too, don't worry about disconnecting it by hand.
- */
+ * disconnected too, don't worry about disconnecting it by hand.
+ */
g_signal_connect (G_OBJECT (dbe), "scan-end",
G_CALLBACK (on_scan_update_buffer_end), real_files_list);
diff --git a/plugins/symbol-db/symbol-db-prefs.c b/plugins/symbol-db/symbol-db-prefs.c
index 2a1952c..9e00e82 100644
--- a/plugins/symbol-db/symbol-db-prefs.c
+++ b/plugins/symbol-db/symbol-db-prefs.c
@@ -358,7 +358,7 @@ sdb_prefs_init1 (SymbolDBPrefs *sdbp)
{
SymbolDBPrefsPriv *priv;
/* GtkWidget *fchooser;*/
- gchar *ctags_value;
+/* gchar *ctags_value;*/
priv = sdbp->priv;
diff --git a/plugins/symbol-db/symbol-db-view-locals.c b/plugins/symbol-db/symbol-db-view-locals.c
index be68abc..b53db9a 100644
--- a/plugins/symbol-db/symbol-db-view-locals.c
+++ b/plugins/symbol-db/symbol-db-view-locals.c
@@ -51,8 +51,8 @@ typedef struct _WaitingForSymbol {
typedef struct _TraverseData {
SymbolDBViewLocals *dbvl;
- SymbolDBEngine *dbe;
-
+ void *data;
+
} TraverseData;
typedef struct _FileSymbolsStatus {
@@ -74,7 +74,8 @@ struct _SymbolDBViewLocalsPriv {
GTree *nodes_displayed;
GTree *waiting_for;
- GQueue *symbols_inserted_ids;
+ GQueue *symbols_inserted_ids;
+ GTree *nodes_not_yet_removed; /* this'll remain active across views */
gboolean display_nothing;
gboolean recv_signals;
@@ -220,6 +221,12 @@ symbol_db_view_locals_clear_cache (SymbolDBViewLocals *dbvl)
priv->waiting_for = NULL;
}
+ if (priv->nodes_not_yet_removed)
+ {
+ g_tree_destroy (priv->nodes_not_yet_removed);
+ priv->nodes_not_yet_removed = NULL;
+ }
+
store = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (dbvl)));
if (store != NULL)
g_object_unref (store);
@@ -274,7 +281,7 @@ sdb_view_locals_init (SymbolDBViewLocals *dbvl)
g_return_if_fail (dbvl != NULL);
- DEBUG_PRINT ("%s", "sdb_view_locals_init ()");
+ /*DEBUG_PRINT ("%s", "sdb_view_locals_init ()");*/
dbvl->priv = g_new0 (SymbolDBViewLocalsPriv, 1);
priv = dbvl->priv;
@@ -282,6 +289,10 @@ sdb_view_locals_init (SymbolDBViewLocals *dbvl)
priv->current_local_file_path = NULL;
priv->nodes_displayed = NULL;
priv->waiting_for = NULL;
+ priv->nodes_not_yet_removed = g_tree_new_full ((GCompareDataFunc)&symbol_db_gtree_compare_func,
+ NULL,
+ NULL,
+ NULL);
priv->symbols_inserted_ids = NULL;
priv->insert_handler = 0;
priv->scan_end_handler = 0;
@@ -490,7 +501,7 @@ traverse_on_scan_end (gpointer key, gpointer value, gpointer data)
tdata = (TraverseData *)data;
- dbe = tdata->dbe;
+ dbe = SYMBOL_DB_ENGINE (tdata->data);
dbvl = tdata->dbvl;
g_return_val_if_fail (dbe != NULL, FALSE);
@@ -843,7 +854,7 @@ consume_symbols_inserted_queue_idle_destroy (gpointer data)
tdata = (TraverseData *)data;
dbvl = tdata->dbvl;
- dbe = tdata->dbe;
+ dbe = SYMBOL_DB_ENGINE (tdata->data);
g_return_if_fail (dbvl != NULL);
priv = dbvl->priv;
@@ -889,7 +900,7 @@ consume_symbols_inserted_queue_idle (gpointer data)
tdata = (TraverseData *)data;
dbvl = tdata->dbvl;
- dbe = tdata->dbe;
+ dbe = SYMBOL_DB_ENGINE (tdata->data);
g_return_val_if_fail (dbvl != NULL, FALSE);
priv = dbvl->priv;
@@ -1039,7 +1050,7 @@ on_scan_end (SymbolDBEngine *dbe, gint process_id, gpointer data)
tdata = g_new (TraverseData, 1);
tdata->dbvl = dbvl;
- tdata->dbe = dbe;
+ tdata->data = dbe;
/*DEBUG_PRINT ("%s", "locals: on_scan_end");*/
if (priv->symbols_inserted_ids != NULL)
@@ -1117,11 +1128,14 @@ on_symbol_removed (SymbolDBEngine *dbe, gint symbol_id, gpointer data)
return;
}
- /*DEBUG_PRINT ("on_symbol_removed (): -local- %d", symbol_id);*/
+ /* DEBUG_PRINT ("-local- %d", symbol_id); */
row_ref = g_tree_lookup (priv->nodes_displayed, GINT_TO_POINTER (symbol_id));
if (sdb_view_locals_get_iter_from_row_ref (dbvl, row_ref, &iter) == FALSE)
{
+ /* DEBUG_PRINT ("found no row...."); */
+ g_tree_insert (priv->nodes_not_yet_removed, GINT_TO_POINTER (symbol_id),
+ GINT_TO_POINTER (symbol_id));
return;
}
@@ -1174,6 +1188,8 @@ on_symbol_inserted (SymbolDBEngine *dbe, gint symbol_id, gpointer data)
{
return;
}
+
+ /* DEBUG_PRINT ("-local- %d", symbol_id); */
/* save the symbol_id to be added in the queue and just return */
g_queue_push_head (priv->symbols_inserted_ids, GINT_TO_POINTER (symbol_id));
@@ -1309,6 +1325,44 @@ symbol_db_view_locals_display_nothing (SymbolDBViewLocals *dbvl,
}
}
+static gboolean
+traverse_check_for_unremoved_symbols (gpointer key, gpointer value, gpointer data)
+{
+ SymbolDBViewLocals *dbvl;
+ SymbolDBViewLocalsPriv *priv;
+ GtkTreeIter iter;
+ GtkTreeRowReference *row_ref;
+ GList *removed_items = NULL;
+ TraverseData *tdata;
+
+ tdata = (TraverseData *)data;
+
+ dbvl = tdata->dbvl;
+ removed_items = tdata->data;
+
+ priv = dbvl->priv;
+
+ row_ref = g_tree_lookup (priv->nodes_displayed, GINT_TO_POINTER (key));
+ if (sdb_view_locals_get_iter_from_row_ref (dbvl, row_ref, &iter) == FALSE)
+ {
+ tdata->data = removed_items;
+ /* nothing found */
+ /* continue traversing */
+ return FALSE;
+ }
+
+ do_recurse_subtree_and_remove (dbvl, &iter);
+
+ /* we've removed something. Save it in the list so later the items
+ * can be removed from the gtree.
+ */
+ removed_items = g_list_prepend (removed_items, key);
+
+ tdata->data = removed_items;
+ /* continue traversing */
+ return FALSE;
+}
+
void
symbol_db_view_locals_update_list (SymbolDBViewLocals *dbvl, SymbolDBEngine *dbe,
const gchar* filepath, gboolean force_update)
@@ -1441,13 +1495,43 @@ symbol_db_view_locals_update_list (SymbolDBViewLocals *dbvl, SymbolDBEngine *dbe
tdata = g_new0 (TraverseData, 1);
tdata->dbvl = dbvl;
- tdata->dbe = dbe;
+ tdata->data = dbe;
priv->insertion_idle_handler = g_idle_add_full (G_PRIORITY_LOW,
(GSourceFunc) consume_symbols_inserted_queue_idle,
(gpointer) tdata,
(GDestroyNotify) consume_symbols_inserted_queue_idle_destroy);
- }
+ }
+
+ /* fine, but some symbol-remove signals can have been left. Check if they
+ * can be removed
+ */
+ GList *removed_list;
+ TraverseData *tdata;
+
+ tdata = g_new0 (TraverseData, 1);
+ tdata->dbvl = dbvl;
+
+ g_tree_foreach (priv->nodes_not_yet_removed,
+ traverse_check_for_unremoved_symbols, tdata);
+
+ /* the result */
+ removed_list = tdata->data;
+
+ /* have we removed something? We'll know that checking the list */
+ if (removed_list != NULL)
+ {
+ GList *node = removed_list;
+ while (node != NULL)
+ {
+ g_tree_remove (priv->nodes_not_yet_removed, node->data);
+
+ node = node->next;
+ }
+ }
+
+ g_list_free (removed_list);
+ g_free (tdata);
}
else
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]