[libchamplain] Fix asynchronous tile loading
- From: Pierre-Luc Beaudoin <plbeaudoin src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libchamplain] Fix asynchronous tile loading
- Date: Tue, 16 Feb 2010 21:29:03 +0000 (UTC)
commit e115ad56dabca6a2f8b1a882bfc6d8379d50ff54
Author: JiÅ?Ã Techet <techet gmail com>
Date: Sun Feb 14 13:21:46 2010 +0100
Fix asynchronous tile loading
When loading textures asynchronously, we have to check whether the
tile was loaded successfully in the callback.
Signed-off-by: JiÅ?Ã Techet <techet gmail com>
champlain/champlain-file-cache.c | 101 ++++++++++++++++++++++++++------------
champlain/champlain-view.c | 6 ++-
2 files changed, 75 insertions(+), 32 deletions(-)
---
diff --git a/champlain/champlain-file-cache.c b/champlain/champlain-file-cache.c
index 788a55e..0c8b915 100644
--- a/champlain/champlain-file-cache.c
+++ b/champlain/champlain-file-cache.c
@@ -225,7 +225,7 @@ init_cache (ChamplainFileCache *file_cache)
gint error;
g_print ("init! '%d'\n", champlain_tile_cache_get_persistent (tile_cache));
-
+
g_return_if_fail (create_cache_dir (priv->cache_dir));
if (champlain_tile_cache_get_persistent (tile_cache))
@@ -542,47 +542,42 @@ tile_is_expired (ChamplainFileCache *file_cache, ChamplainTile *tile)
return validate_cache;
}
-static void
-fill_tile (ChamplainMapSource *map_source,
- ChamplainTile *tile)
+typedef struct
{
- g_return_if_fail (CHAMPLAIN_IS_FILE_CACHE (map_source));
- g_return_if_fail (CHAMPLAIN_IS_TILE (tile));
+ ChamplainMapSource *map_source;
+ ChamplainTile *tile;
+ gchar *filename;
+ gulong handler;
+} TileLoadedCallbackData;
+static void
+tile_loaded_cb (ClutterTexture *texture,
+ const GError *error,
+ TileLoadedCallbackData *user_data)
+{
+ ChamplainMapSource *map_source = user_data->map_source;
+ gchar *filename = user_data->filename;
+ ChamplainTile *tile = user_data->tile;
ChamplainFileCache *file_cache = CHAMPLAIN_FILE_CACHE(map_source);
ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
ChamplainFileCachePrivate *priv = GET_PRIVATE (file_cache);
GFileInfo *info = NULL;
GFile *file = NULL;
- GError *gerror = NULL;
- ClutterActor *actor = NULL;
- gchar *filename = NULL;
+ ClutterActor *actor = CLUTTER_ACTOR(texture);
GTimeVal modified_time = {0,};
- if (champlain_tile_get_content (tile))
- /* Previous cache in the chain is validating its contents */
- goto load_next;
-
- filename = get_filename (file_cache, tile);
- DEBUG ("fill of %s", filename);
+ g_signal_handler_disconnect (texture, user_data->handler);
+ g_free (user_data);
- /* Load the cached version */
- actor = clutter_texture_new ();
- clutter_texture_set_load_async (CLUTTER_TEXTURE (actor), TRUE);
- clutter_texture_set_from_file (CLUTTER_TEXTURE (actor), filename, &gerror);
- if (actor)
+ if (error)
{
- champlain_tile_set_content (tile, actor, FALSE);
- champlain_tile_set_size (tile, champlain_map_source_get_tile_size (map_source));
- }
- else
- {
- DEBUG ("Failed to load tile %s, error: %s",
- filename, gerror->message);
- g_error_free (gerror);
+ DEBUG ("Failed to load tile %s, error: %s", filename, error->message);
goto load_next;
}
+ champlain_tile_set_content (tile, actor, FALSE);
+ champlain_tile_set_size (tile, champlain_map_source_get_tile_size (map_source));
+
/* Retrieve modification time */
file = g_file_new_for_path (filename);
info = g_file_query_info (file,
@@ -599,9 +594,7 @@ fill_tile (ChamplainMapSource *map_source,
/* Notify other caches that the tile has been filled */
if (CHAMPLAIN_IS_TILE_CACHE(next_source))
- {
- on_tile_filled (CHAMPLAIN_TILE_CACHE(next_source), tile);
- }
+ on_tile_filled (CHAMPLAIN_TILE_CACHE(next_source), tile);
if (tile_is_expired (file_cache, tile))
{
@@ -657,6 +650,52 @@ load_next:
cleanup:
sqlite3_reset (priv->stmt_select);
g_free (filename);
+ g_object_unref (tile);
+ g_object_unref (map_source);
+}
+
+static void
+fill_tile (ChamplainMapSource *map_source,
+ ChamplainTile *tile)
+{
+ g_return_if_fail (CHAMPLAIN_IS_FILE_CACHE (map_source));
+ g_return_if_fail (CHAMPLAIN_IS_TILE (tile));
+
+ if (!champlain_tile_get_content (tile))
+ {
+ ChamplainFileCache *file_cache = CHAMPLAIN_FILE_CACHE(map_source);
+ TileLoadedCallbackData *callback_data;
+ ClutterTexture *texture;
+
+ callback_data = g_new (TileLoadedCallbackData, 1);
+ callback_data->tile = tile;
+ callback_data->map_source = map_source;
+ callback_data->filename = get_filename (file_cache, tile);
+
+ DEBUG ("fill of %s", callback_data->filename);
+
+ /* Ref the tile as it may be freeing during the loading
+ * Unref when the loading is done.
+ */
+ g_object_ref (tile);
+ g_object_ref (map_source);
+
+ /* Load the cached version */
+ texture = CLUTTER_TEXTURE(clutter_texture_new ());
+ callback_data->handler = g_signal_connect (texture, "load-finished",
+ G_CALLBACK (tile_loaded_cb),
+ callback_data);
+ clutter_texture_set_load_async (texture, TRUE);
+ clutter_texture_set_from_file (texture, callback_data->filename, NULL);
+ }
+ else
+ {
+ ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
+
+ /* Previous cache in the chain is validating its contents */
+ if (CHAMPLAIN_IS_MAP_SOURCE(next_source))
+ champlain_map_source_fill_tile (next_source, tile);
+ }
}
static void
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index bed6b66..e75d4d9 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -333,7 +333,7 @@ update_viewport (ChamplainView *view,
g_object_notify (G_OBJECT (view), "latitude");
}
-static void
+static void
panning_completed (TidyFingerScroll *scroll,
ChamplainView *view)
{
@@ -2389,6 +2389,7 @@ view_load_visible_tiles (ChamplainView *view)
champlain_tile_get_actor (tile), NULL);
champlain_zoom_level_add_tile (level, tile);
+ champlain_tile_set_state (tile, CHAMPLAIN_STATE_LOADING);
champlain_map_source_fill_tile (priv->map_source, tile);
g_object_unref (tile);
@@ -2497,7 +2498,10 @@ view_reload_tiles_cb (ChamplainMapSource *map_source,
continue;
if (champlain_tile_get_state (tile) != CHAMPLAIN_STATE_LOADING)
+ {
+ champlain_tile_set_state (tile, CHAMPLAIN_STATE_LOADING);
champlain_map_source_fill_tile (priv->map_source, tile);
+ }
}
view_update_state (view);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]