Commit ec6fa72c authored by Jiří Techet's avatar Jiří Techet

Fix various problems with asynchronous tile loading

Signed-off-by: 's avatarJiří Techet <techet@gmail.com>
parent 1acc3858
......@@ -519,9 +519,9 @@ tile_rendered_cb (ChamplainTile *tile,
{
ChamplainMapSource *map_source = user_data->map_source;
GFile *file;
ChamplainFileCache *file_cache = CHAMPLAIN_FILE_CACHE (map_source);
ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
ChamplainFileCachePrivate *priv = file_cache->priv;
ChamplainFileCache *file_cache;
ChamplainMapSource *next_source;
ChamplainFileCachePrivate *priv;
GFileInfo *info = NULL;
GTimeVal modified_time = { 0, };
gchar *filename = NULL;
......@@ -529,15 +529,19 @@ tile_rendered_cb (ChamplainTile *tile,
// this frees user_data
g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, user_data);
if (!tile)
if (!map_source)
{
DEBUG ("Tile destroyed while loading");
goto cleanup;
DEBUG ("Map source destroyed while loading");
return;
}
next_source = champlain_map_source_get_next_source (map_source);
file_cache = CHAMPLAIN_FILE_CACHE (map_source);
priv = file_cache->priv;
if (data->error)
{
DEBUG ("Tile rendering failed: %s", filename);
DEBUG ("Tile rendering failed");
goto load_next;
}
......@@ -662,18 +666,15 @@ file_loaded_cb (GFile *file,
g_object_unref (file);
if (!tile)
if (!tile || !map_source)
{
DEBUG ("Tile destroyed while loading");
// data already destroyed by destroy_cb_data
return;
}
if (map_source)
g_object_remove_weak_pointer (G_OBJECT (map_source), (gpointer *) &user_data->map_source);
if (!map_source)
{
DEBUG ("Map source destroyed while loading");
// this destros the data by destroy_cb_data
g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, user_data);
if (tile)
g_object_remove_weak_pointer (G_OBJECT (tile), (gpointer *) &user_data->tile);
g_slice_free (FileLoadedData, user_data);
return;
}
......@@ -681,6 +682,9 @@ file_loaded_cb (GFile *file,
g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));
g_signal_connect_data (tile, "render-complete", G_CALLBACK (tile_rendered_cb),
user_data, (GClosureNotify) destroy_cb_data, 0);
champlain_renderer_set_data (renderer, contents, length);
champlain_renderer_render (renderer, tile);
}
......@@ -693,6 +697,8 @@ fill_tile (ChamplainMapSource *map_source,
g_return_if_fail (CHAMPLAIN_IS_FILE_CACHE (map_source));
g_return_if_fail (CHAMPLAIN_IS_TILE (tile));
ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
if (champlain_tile_get_state (tile) != CHAMPLAIN_STATE_LOADED)
{
FileLoadedData *user_data;
......@@ -711,17 +717,15 @@ fill_tile (ChamplainMapSource *map_source,
DEBUG ("fill of %s", filename);
g_signal_connect_data (tile, "render-complete", G_CALLBACK (tile_rendered_cb),
user_data, (GClosureNotify) destroy_cb_data, 0);
g_file_load_contents_async (file, NULL, (GAsyncReadyCallback) file_loaded_cb, user_data);
}
else
else if (CHAMPLAIN_IS_MAP_SOURCE (next_source))
champlain_map_source_fill_tile (next_source, tile);
else if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_LOADED)
{
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);
/* if we have some content, use the tile even if it wasn't validated */
champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE);
champlain_tile_display_content (tile);
}
}
......
......@@ -141,17 +141,33 @@ champlain_file_tile_source_load_map_data (ChamplainFileTileSource *self,
}
typedef struct
{
ChamplainMapSource *map_source;
} TileRenderedData;
static void
tile_rendered_cb (ChamplainTile *tile,
ChamplainRenderCallbackData *data,
ChamplainMapSource *map_source)
TileRenderedData *user_data)
{
ChamplainTileSource *tile_source = CHAMPLAIN_TILE_SOURCE (map_source);
ChamplainTileCache *tile_cache = champlain_tile_source_get_cache (tile_source);
ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
ChamplainMapSource *map_source = user_data->map_source;
ChamplainMapSource *next_source;
// frees user_data - must not be used later in the function
g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, map_source);
if (!map_source)
return;
next_source = champlain_map_source_get_next_source (map_source);
if (!data->error)
{
ChamplainTileSource *tile_source = CHAMPLAIN_TILE_SOURCE (map_source);
ChamplainTileCache *tile_cache = champlain_tile_source_get_cache (tile_source);
if (tile_cache && data->data)
champlain_tile_cache_store_tile (tile_cache, tile, data->data, data->size);
......@@ -161,9 +177,17 @@ tile_rendered_cb (ChamplainTile *tile,
}
else if (next_source)
champlain_map_source_fill_tile (next_source, tile);
}
g_object_unref (map_source);
g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, map_source);
static void
destroy_cb_data (TileRenderedData *data,
G_GNUC_UNUSED GClosure *closure)
{
if (data->map_source)
g_object_remove_weak_pointer (G_OBJECT (data->map_source), (gpointer *) &data->map_source);
g_slice_free (TileRenderedData, data);
}
......@@ -174,15 +198,33 @@ fill_tile (ChamplainMapSource *map_source,
g_return_if_fail (CHAMPLAIN_IS_FILE_TILE_SOURCE (map_source));
g_return_if_fail (CHAMPLAIN_IS_TILE (tile));
ChamplainRenderer *renderer;
ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
if (champlain_tile_get_state (tile) != CHAMPLAIN_STATE_LOADED)
{
ChamplainRenderer *renderer;
TileRenderedData *user_data;
renderer = champlain_map_source_get_renderer (map_source);
renderer = champlain_map_source_get_renderer (map_source);
g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));
g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));
user_data = g_slice_new (TileRenderedData);
user_data->map_source = map_source;
g_object_ref (map_source);
g_object_add_weak_pointer (G_OBJECT (map_source), (gpointer *) &user_data->map_source);
g_signal_connect (tile, "render-complete", G_CALLBACK (tile_rendered_cb), map_source);
g_signal_connect_data (tile, "render-complete", G_CALLBACK (tile_rendered_cb),
user_data, (GClosureNotify) destroy_cb_data, 0);
champlain_renderer_render (renderer, tile);
champlain_renderer_render (renderer, tile);
}
else if (CHAMPLAIN_IS_MAP_SOURCE (next_source))
champlain_map_source_fill_tile (next_source, tile);
else if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_LOADED)
{
/* if we have some content, use the tile even if it wasn't validated */
champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE);
champlain_tile_display_content (tile);
}
}
......@@ -128,7 +128,7 @@ render (ChamplainRenderer *renderer, ChamplainTile *tile)
g_warning ("Unable to load the pixbuf: %s", error->message);
g_error_free (error);
}
goto error;
}
gdk_pixbuf_loader_close (loader, &error);
......
......@@ -254,27 +254,50 @@ delete_queue_member (QueueMember *member, gpointer user_data)
}
typedef struct
{
ChamplainMapSource *map_source;
} TileRenderedData;
static void
tile_rendered_cb (ChamplainTile *tile,
ChamplainRenderCallbackData *data,
ChamplainMapSource *map_source)
TileRenderedData *user_data)
{
ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
ChamplainMapSource *map_source = user_data->map_source;
ChamplainMapSource *next_source;
// frees user_data - must not be used later in the function
g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, map_source);
if (!map_source)
return;
next_source = champlain_map_source_get_next_source (map_source);
if (!data->error)
{
if (CHAMPLAIN_IS_TILE_CACHE (next_source))
on_tile_filled (CHAMPLAIN_TILE_CACHE (next_source), tile);
champlain_tile_set_fade_in (tile, TRUE);
champlain_tile_set_fade_in (tile, FALSE);
champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE);
champlain_tile_display_content (tile);
}
else if (CHAMPLAIN_IS_MAP_SOURCE (next_source))
else if (next_source)
champlain_map_source_fill_tile (next_source, tile);
}
g_object_unref (map_source);
g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, map_source);
static void
destroy_cb_data (TileRenderedData *data,
G_GNUC_UNUSED GClosure *closure)
{
if (data->map_source)
g_object_remove_weak_pointer (G_OBJECT (data->map_source), (gpointer *) &data->map_source);
g_slice_free (TileRenderedData, data);
}
......@@ -300,6 +323,7 @@ fill_tile (ChamplainMapSource *map_source,
if (link)
{
QueueMember *member = link->data;
TileRenderedData *user_data;
move_queue_member_to_head (priv->queue, link);
......@@ -307,8 +331,14 @@ fill_tile (ChamplainMapSource *map_source,
g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));
g_object_ref (map_source);
g_signal_connect (tile, "render-complete", G_CALLBACK (tile_rendered_cb), map_source);
user_data = g_slice_new (TileRenderedData);
user_data->map_source = map_source;
g_object_add_weak_pointer (G_OBJECT (map_source), (gpointer *) &user_data->map_source);
g_signal_connect_data (tile, "render-complete", G_CALLBACK (tile_rendered_cb),
user_data, (GClosureNotify) destroy_cb_data, 0);
champlain_renderer_set_data (renderer, member->data, member->size);
champlain_renderer_render (renderer, tile);
......
......@@ -352,7 +352,8 @@ error:
callback_data.size = 0;
finish:
g_signal_emit_by_name (tile, "render-complete", &callback_data);
if (tile)
g_signal_emit_by_name (tile, "render-complete", &callback_data);
if (pixbuf)
g_object_unref (pixbuf);
......
......@@ -366,17 +366,33 @@ champlain_network_bbox_tile_source_load_map_data (
}
typedef struct
{
ChamplainMapSource *map_source;
} TileRenderedData;
static void
tile_rendered_cb (ChamplainTile *tile,
ChamplainRenderCallbackData *data,
ChamplainMapSource *map_source)
TileRenderedData *user_data)
{
ChamplainTileSource *tile_source = CHAMPLAIN_TILE_SOURCE (map_source);
ChamplainTileCache *tile_cache = champlain_tile_source_get_cache (tile_source);
ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
ChamplainMapSource *map_source = user_data->map_source;
ChamplainMapSource *next_source;
// frees user_data - must not be used later in the function
g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, map_source);
if (!map_source)
return;
next_source = champlain_map_source_get_next_source (map_source);
if (!data->error)
{
ChamplainTileSource *tile_source = CHAMPLAIN_TILE_SOURCE (map_source);
ChamplainTileCache *tile_cache = champlain_tile_source_get_cache (tile_source);
if (tile_cache && data->data)
champlain_tile_cache_store_tile (tile_cache, tile, data->data, data->size);
......@@ -386,9 +402,17 @@ tile_rendered_cb (ChamplainTile *tile,
}
else if (next_source)
champlain_map_source_fill_tile (next_source, tile);
}
g_object_unref (map_source);
g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, map_source);
static void
destroy_cb_data (TileRenderedData *data,
G_GNUC_UNUSED GClosure *closure)
{
if (data->map_source)
g_object_remove_weak_pointer (G_OBJECT (data->map_source), (gpointer *) &data->map_source);
g_slice_free (TileRenderedData, data);
}
......@@ -399,17 +423,35 @@ fill_tile (ChamplainMapSource *map_source,
g_return_if_fail (CHAMPLAIN_IS_NETWORK_BBOX_TILE_SOURCE (map_source));
g_return_if_fail (CHAMPLAIN_IS_TILE (tile));
ChamplainRenderer *renderer;
ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
if (champlain_tile_get_state (tile) != CHAMPLAIN_STATE_LOADED)
{
ChamplainRenderer *renderer;
TileRenderedData *user_data;
renderer = champlain_map_source_get_renderer (map_source);
renderer = champlain_map_source_get_renderer (map_source);
g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));
g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));
user_data = g_slice_new (TileRenderedData);
user_data->map_source = map_source;
g_object_ref (map_source);
g_object_add_weak_pointer (G_OBJECT (map_source), (gpointer *) &user_data->map_source);
g_signal_connect (tile, "render-complete", G_CALLBACK (tile_rendered_cb), map_source);
g_signal_connect_data (tile, "render-complete", G_CALLBACK (tile_rendered_cb),
user_data, (GClosureNotify) destroy_cb_data, 0);
champlain_renderer_render (renderer, tile);
champlain_renderer_render (renderer, tile);
}
else if (CHAMPLAIN_IS_MAP_SOURCE (next_source))
champlain_map_source_fill_tile (next_source, tile);
else if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_LOADED)
{
/* if we have some content, use the tile even if it wasn't validated */
champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE);
champlain_tile_display_content (tile);
}
}
......
......@@ -85,13 +85,13 @@ typedef struct
{
ChamplainMapSource *map_source;
ChamplainTile *tile;
} TileLoadedCallbackData;
} TileLoadedData;
typedef struct
{
ChamplainMapSource *map_source;
gchar *etag;
} TileRenderedCallbackData;
} TileRenderedData;
typedef struct
{
......@@ -524,41 +524,29 @@ get_tile_uri (ChamplainNetworkTileSource *tile_source,
static void
tile_destroyed_cb (G_GNUC_UNUSED ChamplainTile *tile,
TileDestroyedCbData *data)
{
if (data->map_source && data->msg)
{
DEBUG ("Canceling tile download");
ChamplainNetworkTileSourcePrivate *priv = CHAMPLAIN_NETWORK_TILE_SOURCE (data->map_source)->priv;
soup_session_cancel_message (priv->soup_session, data->msg, SOUP_STATUS_CANCELLED);
}
}
static void
destroy_cb_data (TileDestroyedCbData *data,
G_GNUC_UNUSED GClosure *closure)
{
if (data->map_source)
g_object_remove_weak_pointer (G_OBJECT (data->map_source), (gpointer *) &data->map_source);
g_slice_free (TileDestroyedCbData, data);
}
static void
tile_rendered_cb (ChamplainTile *tile, ChamplainRenderCallbackData *data, TileRenderedCallbackData *user_data)
tile_rendered_cb (ChamplainTile *tile,
ChamplainRenderCallbackData *data,
TileRenderedData *user_data)
{
ChamplainMapSource *map_source = user_data->map_source;
ChamplainTileSource *tile_source = CHAMPLAIN_TILE_SOURCE (map_source);
ChamplainTileCache *tile_cache = champlain_tile_source_get_cache (tile_source);
ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
gchar *etag = user_data->etag;
ChamplainMapSource *next_source;
gchar *etag;
etag = g_strdup (user_data->etag);
// frees user_data - must not be used later in the function
g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, map_source);
if (!map_source)
return;
next_source = champlain_map_source_get_next_source (map_source);
if (!data->error)
{
ChamplainTileSource *tile_source = CHAMPLAIN_TILE_SOURCE (map_source);
ChamplainTileCache *tile_cache = champlain_tile_source_get_cache (tile_source);
if (etag != NULL)
champlain_tile_set_etag (tile, etag);
......@@ -569,15 +557,24 @@ tile_rendered_cb (ChamplainTile *tile, ChamplainRenderCallbackData *data, TileRe
champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE);
champlain_tile_display_content (tile);
}
else
{
if (next_source)
champlain_map_source_fill_tile (next_source, tile);
}
else if (next_source)
champlain_map_source_fill_tile (next_source, tile);
g_free (etag);
}
g_object_unref (map_source);
g_slice_free (TileRenderedCallbackData, user_data);
g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, user_data);
static void
destroy_render_complete_data (TileRenderedData *data,
G_GNUC_UNUSED GClosure *closure)
{
if (data->map_source)
g_object_remove_weak_pointer (G_OBJECT (data->map_source), (gpointer *) &data->map_source);
if (data->etag)
g_free (data->etag);
g_slice_free (TileRenderedData, data);
}
......@@ -586,33 +583,40 @@ tile_loaded_cb (G_GNUC_UNUSED SoupSession *session,
SoupMessage *msg,
gpointer user_data)
{
TileLoadedCallbackData *callback_data = (TileLoadedCallbackData *) user_data;
TileLoadedData *callback_data = (TileLoadedData *) user_data;
ChamplainMapSource *map_source = callback_data->map_source;
ChamplainTileSource *tile_source = CHAMPLAIN_TILE_SOURCE (map_source);
ChamplainTileCache *tile_cache = champlain_tile_source_get_cache (tile_source);
ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
ChamplainTile *tile = callback_data->tile;
const gchar *etag;
TileRenderedCallbackData *data;
TileRenderedData *data;
ChamplainRenderer *renderer;
if (tile)
g_object_remove_weak_pointer (G_OBJECT (tile), (gpointer *) &callback_data->tile);
g_slice_free (TileLoadedCallbackData, callback_data);
if (map_source)
g_object_remove_weak_pointer (G_OBJECT (map_source), (gpointer *) &callback_data->map_source);
g_slice_free (TileLoadedData, callback_data);
DEBUG ("Got reply %d", msg->status_code);
if (!tile || msg->status_code == SOUP_STATUS_CANCELLED)
if (!tile)
{
if (!tile)
DEBUG ("Tile destroyed while loading");
else
DEBUG ("Download of tile %d, %d got cancelled",
champlain_tile_get_x (tile), champlain_tile_get_y (tile));
g_object_unref (map_source);
DEBUG ("Tile destroyed while loading");
return;
}
else if (msg->status_code == SOUP_STATUS_CANCELLED)
{
DEBUG ("Download of tile %d, %d got cancelled",
champlain_tile_get_x (tile), champlain_tile_get_y (tile));
return;
}
else if (!map_source)
{
DEBUG ("Map source destroyed");
return;
}
......@@ -637,13 +641,17 @@ tile_loaded_cb (G_GNUC_UNUSED SoupSession *session,
etag = soup_message_headers_get (msg->response_headers, "ETag");
DEBUG ("Received ETag %s", etag);
data = g_slice_new (TileRenderedCallbackData);
renderer = champlain_map_source_get_renderer (map_source);
g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));
data = g_slice_new (TileRenderedData);
data->map_source = map_source;
data->etag = g_strdup (etag);
renderer = champlain_map_source_get_renderer (map_source);
g_object_add_weak_pointer (G_OBJECT (map_source), (gpointer *) &data->map_source);
g_signal_connect (tile, "render-complete", G_CALLBACK (tile_rendered_cb), data);
g_signal_connect_data (tile, "render-complete", G_CALLBACK (tile_rendered_cb),
data, (GClosureNotify) destroy_render_complete_data, 0);
champlain_renderer_set_data (renderer, msg->response_body->data, msg->response_body->length);
champlain_renderer_render (renderer, tile);
......@@ -653,14 +661,40 @@ tile_loaded_cb (G_GNUC_UNUSED SoupSession *session,
load_next:
if (next_source)
champlain_map_source_fill_tile (next_source, tile);
g_object_unref (map_source);
return;
finish:
champlain_tile_set_fade_in (tile, TRUE);
champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE);
champlain_tile_display_content (tile);
g_object_unref (map_source);
}
static void
destroy_cb_data (TileDestroyedCbData *data,
G_GNUC_UNUSED GClosure *closure)
{
if (data->map_source)
g_object_remove_weak_pointer (G_OBJECT (data->map_source), (gpointer *) &data->map_source);
if (data->msg)
g_object_remove_weak_pointer (G_OBJECT (data->msg), (gpointer *) &data->msg);
g_slice_free (TileDestroyedCbData, data);
}
static void
tile_destroyed_cb (G_GNUC_UNUSED ChamplainTile *tile,
TileDestroyedCbData *data)
{
if (data->map_source && data->msg)
{
DEBUG ("Canceling tile download");
ChamplainNetworkTileSourcePrivate *priv = CHAMPLAIN_NETWORK_TILE_SOURCE (data->map_source)->priv;
soup_session_cancel_message (priv->soup_session, data->msg, SOUP_STATUS_CANCELLED);
}
}
......@@ -701,7 +735,7 @@ fill_tile (ChamplainMapSource *map_source,
if (!priv->offline)
{
TileLoadedCallbackData *callback_data;
TileLoadedData *callback_data;
SoupMessage *msg;
gchar *uri;
......@@ -749,12 +783,12 @@ fill_tile (ChamplainMapSource *map_source,
g_signal_connect_data (tile, "destroy", G_CALLBACK (tile_destroyed_cb),
tile_destroyed_cb_data, (GClosureNotify) destroy_cb_data, 0);
callback_data = g_slice_new (TileLoadedCallbackData);
callback_data = g_slice_new (TileLoadedData);
callback_data->tile = tile;
callback_data->map_source = map_source;
g_object_add_weak_pointer (G_OBJECT (tile), (gpointer *) &callback_data->tile);
g_object_ref (map_source);
g_object_add_weak_pointer (G_OBJECT (map_source), (gpointer *) &callback_data->map_source);
soup_session_queue_message (priv->soup_session, msg,
tile_loaded_cb,
......
......@@ -75,17 +75,33 @@ champlain_null_tile_source_new_full (ChamplainRenderer *renderer)
}
typedef struct
{
ChamplainMapSource *map_source;
} TileRenderedData;
static void
tile_rendered_cb (ChamplainTile *tile,
ChamplainRenderCallbackData *data,
ChamplainMapSource *map_source)
TileRenderedData *user_data)
{
ChamplainTileSource *tile_source = CHAMPLAIN_TILE_SOURCE (map_source);
ChamplainTileCache *tile_cache = champlain_tile_source_get_cache (tile_source);
ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
ChamplainMapSource *map_source = user_data->map_source;
ChamplainMapSource *next_source;
// frees user_data - must not be used later in the function
g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, map_source);
if (!map_source)
return;
next_source = champlain_map_source_get_next_source (map_source);
if (!data->error)
{
ChamplainTileSource *tile_source = CHAMPLAIN_TILE_SOURCE (map_source);
ChamplainTileCache *tile_cache = champlain_tile_source_get_cache (tile_source);
if (tile_cache && data->data)
champlain_tile_cache_store_tile (tile_cache, tile, data->data, data->size);
......@@ -95,9 +111,17 @@ tile_rendered_cb (ChamplainTile *tile,
}
else if (next_source)
champlain_map_source_fill_tile (next_source, tile);
}
g_object_unref (map_source);
g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, map_source);
static void
destroy_cb_data (TileRenderedData *data,
G_GNUC_UNUSED GClosure *closure)
{
if (data->map_source)
g_object_remove_weak_pointer (G_OBJECT (data->map_source), (gpointer *) &data->map_source);
g_slice_free (TileRenderedData, data);
}
......@@ -108,15 +132,34 @@ fill_tile (ChamplainMapSource *map_source,
g_return_if_fail (CHAMPLAIN_IS_NULL_TILE_SOURCE (map_source));
g_return_if_fail (CHAMPLAIN_IS_TILE (tile));
ChamplainRenderer *renderer;
ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
if (champlain_tile_get_state (tile) != CHAMPLAIN_STATE_LOADED)
{
ChamplainRenderer *renderer;
TileRenderedData *user_data;
renderer = champlain_map_source_get_renderer (map_source);
renderer = champlain_map_source_get_renderer (map_source);
g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));
g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));