background: Add "added" signal to CcBackgroundXml

So that the front-end can load the wallpapers piece-meal, and
avoid overloading the UI on startup.
This commit is contained in:
Bastien Nocera 2011-02-12 02:37:04 +00:00
parent 415d4c1111
commit c2e84e2c8a
2 changed files with 69 additions and 6 deletions

View file

@ -30,13 +30,26 @@
#include "cc-background-item.h" #include "cc-background-item.h"
#include "cc-background-xml.h" #include "cc-background-xml.h"
/* The number of items we signal as "added" before
* returning to the main loop */
#define NUM_ITEMS_PER_BATCH 1
struct CcBackgroundXmlPrivate struct CcBackgroundXmlPrivate
{ {
GHashTable *wp_hash; GHashTable *wp_hash;
GAsyncQueue *item_added_queue;
guint item_added_id;
}; };
#define CC_BACKGROUND_XML_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_BACKGROUND_XML, CcBackgroundXmlPrivate)) #define CC_BACKGROUND_XML_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_BACKGROUND_XML, CcBackgroundXmlPrivate))
enum {
ADDED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
static void cc_background_xml_class_init (CcBackgroundXmlClass *klass); static void cc_background_xml_class_init (CcBackgroundXmlClass *klass);
static void cc_background_xml_init (CcBackgroundXml *background_item); static void cc_background_xml_init (CcBackgroundXml *background_item);
static void cc_background_xml_finalize (GObject *object); static void cc_background_xml_finalize (GObject *object);
@ -113,6 +126,37 @@ enum_string_to_value (GType type,
return value->value; return value->value;
} }
static gboolean
idle_emit (CcBackgroundXml *xml)
{
GObject *item;
guint i = NUM_ITEMS_PER_BATCH;
g_async_queue_lock (xml->priv->item_added_queue);
while (i > 0 && (item = g_async_queue_try_pop_unlocked (xml->priv->item_added_queue)) != NULL) {
g_signal_emit (G_OBJECT (xml), signals[ADDED], 0, item);
g_object_unref (item);
i--;
}
xml->priv->item_added_id = 0;
g_async_queue_unlock (xml->priv->item_added_queue);
return (g_async_queue_length (xml->priv->item_added_queue) > 0);
}
static void
emit_added_in_idle (CcBackgroundXml *xml,
GObject *object)
{
g_async_queue_lock (xml->priv->item_added_queue);
g_async_queue_push_unlocked (xml->priv->item_added_queue, object);
if (xml->priv->item_added_id == 0)
xml->priv->item_added_id = g_idle_add ((GSourceFunc) idle_emit, xml);
g_async_queue_unlock (xml->priv->item_added_queue);
}
#define NONE "(none)" #define NONE "(none)"
#define UNSET_FLAG(flag) G_STMT_START{ (flags&=~(flag)); }G_STMT_END #define UNSET_FLAG(flag) G_STMT_START{ (flags&=~(flag)); }G_STMT_END
#define SET_FLAG(flag) G_STMT_START{ (flags|=flag); }G_STMT_END #define SET_FLAG(flag) G_STMT_START{ (flags|=flag); }G_STMT_END
@ -249,6 +293,7 @@ cc_background_xml_load_xml (CcBackgroundXml *xml,
g_object_set (G_OBJECT (item), "flags", flags, NULL); g_object_set (G_OBJECT (item), "flags", flags, NULL);
g_hash_table_insert (xml->priv->wp_hash, id, item); g_hash_table_insert (xml->priv->wp_hash, id, item);
/* Don't free ID, we added it to the hash table */ /* Don't free ID, we added it to the hash table */
emit_added_in_idle (xml, g_object_ref (item));
} }
} }
xmlFreeDoc (wplist); xmlFreeDoc (wplist);
@ -499,6 +544,14 @@ cc_background_xml_finalize (GObject *object)
g_hash_table_destroy (xml->priv->wp_hash); g_hash_table_destroy (xml->priv->wp_hash);
xml->priv->wp_hash = NULL; xml->priv->wp_hash = NULL;
} }
if (xml->priv->item_added_id != 0) {
g_source_remove (xml->priv->item_added_id);
xml->priv->item_added_id = 0;
}
if (xml->priv->item_added_queue) {
g_async_queue_unref (xml->priv->item_added_queue);
xml->priv->item_added_queue = NULL;
}
} }
static void static void
@ -508,6 +561,14 @@ cc_background_xml_class_init (CcBackgroundXmlClass *klass)
object_class->finalize = cc_background_xml_finalize; object_class->finalize = cc_background_xml_finalize;
signals[ADDED] = g_signal_new ("added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, CC_TYPE_BACKGROUND_ITEM);
g_type_class_add_private (klass, sizeof (CcBackgroundXmlPrivate)); g_type_class_add_private (klass, sizeof (CcBackgroundXmlPrivate));
} }
@ -519,6 +580,7 @@ cc_background_xml_init (CcBackgroundXml *xml)
g_str_equal, g_str_equal,
(GDestroyNotify) g_free, (GDestroyNotify) g_free,
(GDestroyNotify) g_object_unref); (GDestroyNotify) g_object_unref);
xml->priv->item_added_queue = g_async_queue_new_full ((GDestroyNotify) g_object_unref);
} }
CcBackgroundXml * CcBackgroundXml *

View file

@ -36,17 +36,18 @@ G_BEGIN_DECLS
typedef struct CcBackgroundXmlPrivate CcBackgroundXmlPrivate; typedef struct CcBackgroundXmlPrivate CcBackgroundXmlPrivate;
typedef struct
{
GObjectClass parent_class;
} CcBackgroundXmlClass;
typedef struct typedef struct
{ {
GObject parent; GObject parent;
CcBackgroundXmlPrivate *priv; CcBackgroundXmlPrivate *priv;
} CcBackgroundXml; } CcBackgroundXml;
typedef struct
{
GObjectClass parent_class;
void (*added) (CcBackgroundXml *xml, GObject *item);
} CcBackgroundXmlClass;
GType cc_background_xml_get_type (void); GType cc_background_xml_get_type (void);
CcBackgroundXml *cc_background_xml_new (void); CcBackgroundXml *cc_background_xml_new (void);