[grilo] [core] Added grl_multiple_cancel
- From: Iago Toral Quiroga <itoral src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [grilo] [core] Added grl_multiple_cancel
- Date: Mon, 14 Jun 2010 15:04:58 +0000 (UTC)
commit b4f8f0708fe0a1e86129fdef4ebd2ba8d0830ab9
Author: Iago Toral Quiroga <itoral igalia com>
Date: Wed Jun 2 10:18:55 2010 +0200
[core] Added grl_multiple_cancel
src/grl-multiple.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++----
src/grl-multiple.h | 2 +
2 files changed, 94 insertions(+), 7 deletions(-)
---
diff --git a/src/grl-multiple.c b/src/grl-multiple.c
index 8e979fc..eb0ac6a 100644
--- a/src/grl-multiple.c
+++ b/src/grl-multiple.c
@@ -32,7 +32,9 @@ struct MultipleSearchData {
GHashTable *table;
guint remaining;
GList *search_ids;
+ GList *sources;
guint search_id;
+ gboolean cancelled;
GrlMediaSourceResultCb user_callback;
gpointer user_data;
};
@@ -42,6 +44,13 @@ struct CallbackData {
gpointer user_data;
};
+/* ================= Globals ================= */
+
+static GHashTable *pending_operations = NULL;
+static gint multiple_search_id = 1;
+
+/* ================ Utitilies ================ */
+
static void
free_multiple_search_data (struct MultipleSearchData *msd)
{
@@ -88,11 +97,14 @@ multiple_search_cb (GrlMediaSource *source,
struct MultipleSearchData *msd = (struct MultipleSearchData *) user_data;
guint source_remaining;
guint diff;
+ gboolean emit;
g_debug ("multiple:remaining == %u, source:remaining = %u (%s)",
msd->remaining, remaining,
grl_metadata_source_get_name (GRL_METADATA_SOURCE (source)));
+ /* --- Update remaining count --- */
+
source_remaining = GPOINTER_TO_INT (g_hash_table_lookup (msd->table,
(gpointer) source));
if (remaining != -1) {
@@ -105,21 +117,53 @@ multiple_search_cb (GrlMediaSource *source,
msd->remaining -= diff;
- msd->user_callback (source,
- msd->search_id,
- media,
- msd->remaining,
- msd->user_data,
- NULL);
+ /* --- Manage NULL results --- */
+
+ if (remaining == 0 && media == NULL && msd->remaining > 0) {
+ /* A source emitted a NULL result to finish its search operation
+ we don't want to relay this to the client (unless this is the
+ last one in the multiple search) */
+ emit = FALSE;
+ } else {
+ emit = TRUE;
+ }
+
+ /* --- Cancelation management --- */
+
+ if (msd->cancelled) {
+ g_debug ("operation is cancelled or already finished, skipping result!");
+ if (media) {
+ g_object_unref (media);
+ media = NULL;
+ }
+ if (msd->remaining > 0) {
+ /* Do not emit if operation was cancelled, only let the last
+ result through */
+ emit = FALSE;
+ }
+ }
+
+ /* --- Result emission --- */
+ if (emit) {
+ msd->user_callback (source,
+ msd->search_id,
+ media,
+ msd->remaining,
+ msd->user_data,
+ NULL);
+ }
if (msd->remaining == 0) {
g_debug ("Multiple operation finished (%u)", msd->search_id);
free_multiple_search_data (msd);
} else {
+ /* Next remaining value expected is one unit less */
msd->remaining--;
}
}
+/* ================ API ================ */
+
guint
grl_multiple_search (const gchar *text,
const GList *keys,
@@ -140,6 +184,10 @@ grl_multiple_search (const gchar *text,
g_return_val_if_fail (text != NULL, 0);
g_return_val_if_fail (callback != NULL, 0);
+ if (!pending_operations) {
+ pending_operations = g_hash_table_new (g_direct_hash, g_direct_equal);
+ }
+
registry = grl_plugin_registry_get_instance ();
sources = grl_plugin_registry_get_sources_by_operations (registry,
GRL_OP_SEARCH,
@@ -163,6 +211,7 @@ grl_multiple_search (const gchar *text,
msd->remaining = count - 1;
msd->user_callback = callback;
msd->user_data = user_data;
+ msd->search_id = multiple_search_id++;
/* Execute multiple search */
for (n = 0; sources[n]; n++) {
@@ -173,7 +222,6 @@ grl_multiple_search (const gchar *text,
if (n == 0) {
c = first_count;
- msd->search_id = grl_media_source_gen_browse_id (source);
} else {
c = individual_count;
}
@@ -189,11 +237,48 @@ grl_multiple_search (const gchar *text,
msd);
g_debug ("Operation %u: Searching %u items in %s",
id, c, grl_metadata_source_get_name (GRL_METADATA_SOURCE (source)));
+
msd->search_ids = g_list_prepend (msd->search_ids, GINT_TO_POINTER (id));
+ msd->sources = g_list_prepend (msd->sources, source);
}
}
+ g_hash_table_insert (pending_operations, GINT_TO_POINTER (msd->search_id),
+ msd);
+
g_free (sources);
return msd->search_id;
}
+
+void
+grl_multiple_cancel (guint search_id)
+{
+ g_debug ("grl_multiple_cancel");
+
+ struct MultipleSearchData *msd;
+ GList *sources, *ids;
+
+ if (!pending_operations) {
+ return;
+ }
+
+ msd = (struct MultipleSearchData *)
+ g_hash_table_lookup (pending_operations, GINT_TO_POINTER (search_id));
+ if (!msd) {
+ g_debug ("Tried to cancel invalid or already cancelled "\
+ "multiple operation. Skipping...");
+ return;
+ }
+
+ sources = msd->sources;
+ ids = msd->search_ids;
+ while (sources) {
+ grl_media_source_cancel (GRL_MEDIA_SOURCE (sources->data),
+ GPOINTER_TO_INT (ids->data));
+ sources = g_list_next (sources);
+ ids = g_list_next (ids);
+ }
+
+ msd->cancelled = TRUE;
+}
diff --git a/src/grl-multiple.h b/src/grl-multiple.h
index f6842f1..966c4cf 100644
--- a/src/grl-multiple.h
+++ b/src/grl-multiple.h
@@ -39,4 +39,6 @@ guint grl_multiple_search (const gchar *text,
gpointer user_data);
+void grl_multiple_cancel (guint search_id);
+
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]