[libchamplain] Rethink the tile destruction process once again



commit 737527e97adcc0086aff130b1a35298acc6ca59d
Author: JiÅ?í Techet <techet gmail com>
Date:   Tue Aug 17 01:31:14 2010 +0200

    Rethink the tile destruction process once again
    
    Instead of weak pointers ref and unref the tiles.
    
    Signed-off-by: JiÅ?í Techet <techet gmail com>

 champlain/champlain-file-cache.c               |   45 ++---------
 champlain/champlain-file-tile-source.c         |   39 ++-------
 champlain/champlain-memory-cache.c             |   35 ++-------
 champlain/champlain-memphis-renderer.c         |    8 +-
 champlain/champlain-network-bbox-tile-source.c |   35 ++-------
 champlain/champlain-network-tile-source.c      |  106 +++++++++--------------
 champlain/champlain-null-tile-source.c         |   35 ++-------
 champlain/champlain-view.c                     |   66 ++++-----------
 8 files changed, 93 insertions(+), 276 deletions(-)
---
diff --git a/champlain/champlain-file-cache.c b/champlain/champlain-file-cache.c
index 7ae233f..70b5910 100644
--- a/champlain/champlain-file-cache.c
+++ b/champlain/champlain-file-cache.c
@@ -526,14 +526,8 @@ tile_rendered_cb (ChamplainTile *tile,
   GTimeVal modified_time = { 0, };
   gchar *filename = NULL;
 
-  // this frees user_data
   g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, user_data);
-
-  if (!map_source)
-    {
-      DEBUG ("Map source destroyed while loading");
-      return;
-    }
+  g_slice_free (FileLoadedData, user_data);
 
   next_source = champlain_map_source_get_next_source (map_source);
   file_cache = CHAMPLAIN_FILE_CACHE (map_source);
@@ -624,20 +618,8 @@ load_next:
 
 cleanup:
   g_free (filename);
-}
-
-
-static void
-destroy_cb_data (FileLoadedData *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->tile)
-    g_object_remove_weak_pointer (G_OBJECT (data->tile), (gpointer *) &data->tile);
-
-  g_slice_free (FileLoadedData, data);
+  g_object_unref (tile);
+  g_object_unref (map_source);
 }
 
 
@@ -666,24 +648,11 @@ file_loaded_cb (GFile *file,
   
   g_object_unref (file);
 
-  if (!tile || !map_source)
-    {
-      if (map_source)
-        g_object_remove_weak_pointer (G_OBJECT (map_source), (gpointer *) &user_data->map_source);
-
-      if (tile)
-        g_object_remove_weak_pointer (G_OBJECT (tile), (gpointer *) &user_data->tile);
-
-      g_slice_free (FileLoadedData, user_data);
-      return;
-    }
-
   renderer = champlain_map_source_get_renderer (map_source);
 
   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);
+  g_signal_connect (tile, "render-complete", G_CALLBACK (tile_rendered_cb), user_data);
 
   champlain_renderer_set_data (renderer, contents, length);
   g_free (contents);
@@ -712,9 +681,9 @@ fill_tile (ChamplainMapSource *map_source,
       user_data = g_slice_new (FileLoadedData);
       user_data->tile = tile;
       user_data->map_source = map_source;
-
-      g_object_add_weak_pointer (G_OBJECT (tile), (gpointer *) &user_data->tile);
-      g_object_add_weak_pointer (G_OBJECT (map_source), (gpointer *) &user_data->map_source);
+      
+      g_object_ref (tile);
+      g_object_ref (map_source);
 
       DEBUG ("fill of %s", filename);
 
diff --git a/champlain/champlain-file-tile-source.c b/champlain/champlain-file-tile-source.c
index 23a6aec..b551ff7 100644
--- a/champlain/champlain-file-tile-source.c
+++ b/champlain/champlain-file-tile-source.c
@@ -141,28 +141,17 @@ champlain_file_tile_source_load_map_data (ChamplainFileTileSource *self,
 }
 
 
-typedef struct
-{
-  ChamplainMapSource *map_source;
-} TileRenderedData;
-
-
 static void
 tile_rendered_cb (ChamplainTile *tile,
     ChamplainRenderCallbackData *data,
-    TileRenderedData *user_data)
+    ChamplainMapSource *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);
@@ -177,17 +166,9 @@ tile_rendered_cb (ChamplainTile *tile,
     }
   else if (next_source)
     champlain_map_source_fill_tile (next_source, tile);
-}
-
-
-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);
+  
+  g_object_unref (map_source);
+  g_object_unref (tile);
 }
 
 
@@ -203,19 +184,15 @@ fill_tile (ChamplainMapSource *map_source,
   if (champlain_tile_get_state (tile) != CHAMPLAIN_STATE_LOADED)
     {
       ChamplainRenderer *renderer;
-      TileRenderedData *user_data;
 
       renderer = champlain_map_source_get_renderer (map_source);
 
       g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));
 
-      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_object_ref (map_source);
+      g_object_ref (tile);
 
-      g_signal_connect_data (tile, "render-complete", G_CALLBACK (tile_rendered_cb),
-              user_data, (GClosureNotify) destroy_cb_data, 0);
+      g_signal_connect (tile, "render-complete", G_CALLBACK (tile_rendered_cb), map_source);
 
       champlain_renderer_render (renderer, tile);
     }
diff --git a/champlain/champlain-memory-cache.c b/champlain/champlain-memory-cache.c
index 3843632..1587268 100644
--- a/champlain/champlain-memory-cache.c
+++ b/champlain/champlain-memory-cache.c
@@ -254,26 +254,15 @@ delete_queue_member (QueueMember *member, gpointer user_data)
 }
 
 
-typedef struct
-{
-  ChamplainMapSource *map_source;
-} TileRenderedData;
-
-
 static void
 tile_rendered_cb (ChamplainTile *tile,
     ChamplainRenderCallbackData *data,
-    TileRenderedData *user_data)
+    ChamplainMapSource *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)
@@ -287,17 +276,9 @@ tile_rendered_cb (ChamplainTile *tile,
     }
   else if (next_source)
     champlain_map_source_fill_tile (next_source, tile);
-}
 
-
-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);
+  g_object_unref (map_source);
+  g_object_unref (tile);  
 }
 
 
@@ -323,7 +304,6 @@ fill_tile (ChamplainMapSource *map_source,
       if (link)
         {
           QueueMember *member = link->data;
-          TileRenderedData *user_data;
 
           move_queue_member_to_head (priv->queue, link);
 
@@ -331,13 +311,10 @@ fill_tile (ChamplainMapSource *map_source,
 
           g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));
 
-          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_object_ref (map_source);
+          g_object_ref (tile);
 
-          g_signal_connect_data (tile, "render-complete", G_CALLBACK (tile_rendered_cb),
-                  user_data, (GClosureNotify) destroy_cb_data, 0);
+          g_signal_connect (tile, "render-complete", G_CALLBACK (tile_rendered_cb), map_source);
                   
           champlain_renderer_set_data (renderer, member->data, member->size);
           champlain_renderer_render (renderer, tile);
diff --git a/champlain/champlain-memphis-renderer.c b/champlain/champlain-memphis-renderer.c
index 9fecca6..6859027 100644
--- a/champlain/champlain-memphis-renderer.c
+++ b/champlain/champlain-memphis-renderer.c
@@ -305,9 +305,6 @@ tile_loaded_cb (gpointer worker_data)
   gchar *buffer = NULL;
   gsize buffer_size;
 
-  if (tile)
-    g_object_remove_weak_pointer (G_OBJECT (tile), (gpointer *) &data->tile);
-
   g_slice_free (WorkerThreadData, data);
 
   if (!tile)
@@ -360,6 +357,7 @@ finish:
   if (cst)
     cairo_surface_destroy (cst);
   g_object_unref (renderer);
+  g_object_unref (tile);
   g_free (buffer);
 
   return FALSE;
@@ -424,7 +422,7 @@ render (ChamplainRenderer *renderer,
   data->tile = tile;
   data->renderer = renderer;
 
-  g_object_add_weak_pointer (G_OBJECT (tile), (gpointer *) &data->tile);
+  g_object_ref (tile);
   g_object_ref (renderer);
 
   g_thread_pool_push (priv->thpool, data, &error);
@@ -434,7 +432,7 @@ render (ChamplainRenderer *renderer,
       g_error_free (error);
       g_slice_free (WorkerThreadData, data);
       g_object_unref (renderer);
-      g_object_remove_weak_pointer (G_OBJECT (tile), (gpointer *) &data->tile);
+      g_object_unref (tile);
     }
 }
 
diff --git a/champlain/champlain-network-bbox-tile-source.c b/champlain/champlain-network-bbox-tile-source.c
index 392fe4d..2119da1 100644
--- a/champlain/champlain-network-bbox-tile-source.c
+++ b/champlain/champlain-network-bbox-tile-source.c
@@ -366,26 +366,15 @@ champlain_network_bbox_tile_source_load_map_data (
 }
 
 
-typedef struct
-{
-  ChamplainMapSource *map_source;
-} TileRenderedData;
-
-
 static void
 tile_rendered_cb (ChamplainTile *tile,
     ChamplainRenderCallbackData *data,
-    TileRenderedData *user_data)
+    ChamplainMapSource *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)
@@ -402,17 +391,9 @@ tile_rendered_cb (ChamplainTile *tile,
     }
   else if (next_source)
     champlain_map_source_fill_tile (next_source, tile);
-}
 
-
-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);
+  g_object_unref (map_source);
+  g_object_unref (tile);
 }
 
 
@@ -428,19 +409,15 @@ fill_tile (ChamplainMapSource *map_source,
   if (champlain_tile_get_state (tile) != CHAMPLAIN_STATE_LOADED)
     {
       ChamplainRenderer *renderer;
-      TileRenderedData *user_data;
 
       renderer = champlain_map_source_get_renderer (map_source);
 
       g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));
 
-      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_object_ref (map_source);
+      g_object_ref (tile);
 
-      g_signal_connect_data (tile, "render-complete", G_CALLBACK (tile_rendered_cb),
-              user_data, (GClosureNotify) destroy_cb_data, 0);
+      g_signal_connect (tile, "render-complete", G_CALLBACK (tile_rendered_cb), map_source);
 
       champlain_renderer_render (renderer, tile);
     }
diff --git a/champlain/champlain-network-tile-source.c b/champlain/champlain-network-tile-source.c
index 9eeff25..178dfb2 100644
--- a/champlain/champlain-network-tile-source.c
+++ b/champlain/champlain-network-tile-source.c
@@ -84,7 +84,14 @@ struct _ChamplainNetworkTileSourcePrivate
 typedef struct
 {
   ChamplainMapSource *map_source;
+  SoupMessage *msg;
+} TileCancelledData;
+
+typedef struct
+{
+  ChamplainMapSource *map_source;
   ChamplainTile *tile;
+  TileCancelledData *cancelled_data;
 } TileLoadedData;
 
 typedef struct
@@ -93,14 +100,13 @@ typedef struct
   gchar *etag;
 } TileRenderedData;
 
-typedef struct
-{
-  ChamplainMapSource *map_source;
-  SoupMessage *msg;
-} TileDestroyedCbData;
 
 static void fill_tile (ChamplainMapSource *map_source,
     ChamplainTile *tile);
+static void
+tile_state_notify (ChamplainTile *tile,
+    G_GNUC_UNUSED GParamSpec *pspec,
+    TileCancelledData *data);
 
 static gchar *get_tile_uri (ChamplainNetworkTileSource *source,
     gint x,
@@ -530,16 +536,11 @@ tile_rendered_cb (ChamplainTile *tile,
 {
   ChamplainMapSource *map_source = user_data->map_source;
   ChamplainMapSource *next_source;
-  gchar *etag;
+  gchar *etag = user_data->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);
+  g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, user_data);
+  g_slice_free (TileRenderedData, user_data);
   
-  if (!map_source)
-    return;
-
   next_source = champlain_map_source_get_next_source (map_source);
   
   if (!data->error)
@@ -561,20 +562,8 @@ tile_rendered_cb (ChamplainTile *tile,
     champlain_map_source_fill_tile (next_source, tile);
     
   g_free (etag);
-}
-
-
-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);
+  g_object_unref (map_source);
+  g_object_unref (tile);  
 }
 
 
@@ -593,31 +582,16 @@ tile_loaded_cb (G_GNUC_UNUSED SoupSession *session,
   TileRenderedData *data;
   ChamplainRenderer *renderer;
 
-  if (tile)
-    g_object_remove_weak_pointer (G_OBJECT (tile), (gpointer *) &callback_data->tile);
-
-  if (map_source)
-    g_object_remove_weak_pointer (G_OBJECT (map_source), (gpointer *) &callback_data->map_source);
-
+  g_signal_handlers_disconnect_by_func (tile, tile_state_notify, callback_data->cancelled_data);
   g_slice_free (TileLoadedData, callback_data);
 
   DEBUG ("Got reply %d", msg->status_code);
 
-  if (!tile)
-    {
-      DEBUG ("Tile destroyed while loading");
-      return;
-    }
-  else if (msg->status_code == SOUP_STATUS_CANCELLED)
+  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;
+      goto cleanup;
     }
 
   if (msg->status_code == SOUP_STATUS_NOT_MODIFIED)
@@ -648,10 +622,7 @@ tile_loaded_cb (G_GNUC_UNUSED SoupSession *session,
   data->map_source = map_source;
   data->etag = g_strdup (etag);
 
-  g_object_add_weak_pointer (G_OBJECT (map_source), (gpointer *) &data->map_source);
-
-  g_signal_connect_data (tile, "render-complete", G_CALLBACK (tile_rendered_cb),
-          data, (GClosureNotify) destroy_render_complete_data, 0);
+  g_signal_connect (tile, "render-complete", G_CALLBACK (tile_rendered_cb), data);
 
   champlain_renderer_set_data (renderer, msg->response_body->data, msg->response_body->length);
   champlain_renderer_render (renderer, tile);
@@ -661,17 +632,22 @@ tile_loaded_cb (G_GNUC_UNUSED SoupSession *session,
 load_next:
   if (next_source)
     champlain_map_source_fill_tile (next_source, tile);
-  return;
+
+  goto cleanup;
 
 finish:
   champlain_tile_set_fade_in (tile, TRUE);
   champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE);
   champlain_tile_display_content (tile);
+
+cleanup:
+  g_object_unref (tile);
+  g_object_unref (map_source);
 }
 
 
 static void
-destroy_cb_data (TileDestroyedCbData *data,
+destroy_cancelled_data (TileCancelledData *data,
     G_GNUC_UNUSED GClosure *closure)
 {
   if (data->map_source)
@@ -680,15 +656,16 @@ destroy_cb_data (TileDestroyedCbData *data,
   if (data->msg)
     g_object_remove_weak_pointer (G_OBJECT (data->msg), (gpointer *) &data->msg);
 
-  g_slice_free (TileDestroyedCbData, data);
+  g_slice_free (TileCancelledData, data);
 }
 
 
 static void
-tile_destroyed_cb (G_GNUC_UNUSED ChamplainTile *tile,
-    TileDestroyedCbData *data)
+tile_state_notify (ChamplainTile *tile,
+    G_GNUC_UNUSED GParamSpec *pspec,
+    TileCancelledData *data)
 {
-  if (data->map_source && data->msg)
+  if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_DONE && data->map_source && data->msg)
     {
       DEBUG ("Canceling tile download");
       ChamplainNetworkTileSourcePrivate *priv = CHAMPLAIN_NETWORK_TILE_SOURCE (data->map_source)->priv;
@@ -773,22 +750,23 @@ fill_tile (ChamplainMapSource *map_source,
           g_free (date);
         }
 
-      TileDestroyedCbData *tile_destroyed_cb_data = g_slice_new (TileDestroyedCbData);
-      tile_destroyed_cb_data->map_source = map_source;
-      tile_destroyed_cb_data->msg = msg;
+      TileCancelledData *tile_cancelled_data = g_slice_new (TileCancelledData);
+      tile_cancelled_data->map_source = map_source;
+      tile_cancelled_data->msg = msg;
 
-      g_object_add_weak_pointer (G_OBJECT (msg), (gpointer *) &tile_destroyed_cb_data->msg);
-      g_object_add_weak_pointer (G_OBJECT (map_source), (gpointer *) &tile_destroyed_cb_data->map_source);
+      g_object_add_weak_pointer (G_OBJECT (msg), (gpointer *) &tile_cancelled_data->msg);
+      g_object_add_weak_pointer (G_OBJECT (map_source), (gpointer *) &tile_cancelled_data->map_source);
 
-      g_signal_connect_data (tile, "destroy", G_CALLBACK (tile_destroyed_cb),
-          tile_destroyed_cb_data, (GClosureNotify) destroy_cb_data, 0);
+      g_signal_connect_data (tile, "notify::state", G_CALLBACK (tile_state_notify),
+          tile_cancelled_data, (GClosureNotify) destroy_cancelled_data, 0);
 
       callback_data = g_slice_new (TileLoadedData);
       callback_data->tile = tile;
       callback_data->map_source = map_source;
+      callback_data->cancelled_data = tile_cancelled_data;
 
-      g_object_add_weak_pointer (G_OBJECT (tile), (gpointer *) &callback_data->tile);
-      g_object_add_weak_pointer (G_OBJECT (map_source), (gpointer *) &callback_data->map_source);
+      g_object_ref (map_source);
+      g_object_ref (tile);
 
       soup_session_queue_message (priv->soup_session, msg,
           tile_loaded_cb,
diff --git a/champlain/champlain-null-tile-source.c b/champlain/champlain-null-tile-source.c
index eec204e..174f366 100644
--- a/champlain/champlain-null-tile-source.c
+++ b/champlain/champlain-null-tile-source.c
@@ -75,26 +75,15 @@ champlain_null_tile_source_new_full (ChamplainRenderer *renderer)
 }
 
 
-typedef struct
-{
-  ChamplainMapSource *map_source;
-} TileRenderedData;
-
-
 static void
 tile_rendered_cb (ChamplainTile *tile,
     ChamplainRenderCallbackData *data,
-    TileRenderedData *user_data)
+    ChamplainMapSource *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)
@@ -111,17 +100,9 @@ tile_rendered_cb (ChamplainTile *tile,
     }
   else if (next_source)
     champlain_map_source_fill_tile (next_source, tile);
-}
 
-
-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);
+  g_object_unref (map_source);
+  g_object_unref (tile);  
 }
 
 
@@ -137,19 +118,15 @@ fill_tile (ChamplainMapSource *map_source,
   if (champlain_tile_get_state (tile) != CHAMPLAIN_STATE_LOADED)
     {
       ChamplainRenderer *renderer;
-      TileRenderedData *user_data;
 
       renderer = champlain_map_source_get_renderer (map_source);
 
       g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));
 
-      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_object_ref (map_source);
+      g_object_ref (tile);
 
-      g_signal_connect_data (tile, "render-complete", G_CALLBACK (tile_rendered_cb),
-              user_data, (GClosureNotify) destroy_cb_data, 0);
+      g_signal_connect (tile, "render-complete", G_CALLBACK (tile_rendered_cb), map_source);
 
       champlain_renderer_render (renderer, tile);
     }
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index 698ad69..b449c47 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -251,8 +251,6 @@ static void update_scale (ChamplainView *view);
 static void view_load_visible_tiles (ChamplainView *view);
 static void view_position_tile (ChamplainView *view,
     ChamplainTile *tile);
-static void view_update_state (ChamplainView *view,
-    ChamplainTile *tile);
 static void view_update_anchor (ChamplainView *view,
     gint x,
     gint y);
@@ -260,9 +258,9 @@ static gboolean view_set_zoom_level_at (ChamplainView *view,
     gint zoom_level,
     gint x,
     gint y);
-static void tile_state_notify (GObject *gobject,
-    GParamSpec *pspec,
-    gpointer data);
+static void tile_state_notify (ChamplainTile *tile,
+    G_GNUC_UNUSED GParamSpec *pspec,
+    ChamplainView *view);
 static void view_update_polygons (ChamplainView *view);
 static gboolean finger_scroll_key_press_cb (ClutterActor *actor,
     ClutterKeyEvent *event,
@@ -273,8 +271,6 @@ static void champlain_view_go_to_with_duration (ChamplainView *view,
     guint duration);
 static gboolean perform_update_cb (ChamplainView *view);
 static gboolean fill_tile_cb (FillTileCallbackData *data);
-static void tile_destroyed_cb (GObject *gobject,
-    gpointer data);
 
 #define SCALE_HEIGHT  20
 #define SCALE_PADDING 10
@@ -2536,7 +2532,12 @@ view_load_visible_tiles (ChamplainView *view)
       if (tile_x < x_first || tile_x >= x_end ||
           tile_y < y_first || tile_y >= y_end ||
           zoom_level != priv->zoom_level)
-        clutter_container_remove_actor (CLUTTER_CONTAINER (priv->map_layer), CLUTTER_ACTOR (tile));
+        {
+          // inform map source to terminate loading the tile
+          if (champlain_tile_get_state (tile) != CHAMPLAIN_STATE_DONE)
+            champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE);
+          clutter_container_remove_actor (CLUTTER_CONTAINER (priv->map_layer), CLUTTER_ACTOR (tile));
+        }
       else
         {
           tile_map[(tile_y - y_first) * x_count + (tile_x - x_first)] = TRUE;
@@ -2579,9 +2580,7 @@ view_load_visible_tiles (ChamplainView *view)
               data->tile = tile;
               data->map_source = priv->map_source;
 
-              g_signal_connect (tile, "destroy", G_CALLBACK (tile_destroyed_cb), view);
-
-              g_object_add_weak_pointer (G_OBJECT (tile), (gpointer *) &data->tile);
+              g_object_ref (tile);
               g_object_ref (priv->map_source);
 
               /* set priority high, otherwise tiles will be loaded after panning is done */
@@ -2608,14 +2607,11 @@ fill_tile_cb (FillTileCallbackData *data)
   ChamplainTile *tile = data->tile;
   ChamplainMapSource *map_source = data->map_source;
 
-  if (data->tile)
-    {
-      g_object_remove_weak_pointer (G_OBJECT (data->tile), (gpointer *) &data->tile);
-      champlain_map_source_fill_tile (map_source, tile);
-    }
+  champlain_map_source_fill_tile (map_source, tile);
 
   g_slice_free (FillTileCallbackData, data);
   g_object_unref (map_source);
+  g_object_unref (tile);
 
   return FALSE;
 }
@@ -2658,44 +2654,12 @@ champlain_view_reload_tiles (ChamplainView *view)
 
 
 static void
-tile_destroyed_cb (GObject *gobject,
-    gpointer data)
-{
-  DEBUG_LOG ()
-
-  ChamplainView *view = CHAMPLAIN_VIEW (data);
-  ChamplainTile *tile = CHAMPLAIN_TILE (gobject);
-  ChamplainViewPrivate *priv = view->priv;
-
-  if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_LOADING ||
-      champlain_tile_get_state (tile) == CHAMPLAIN_STATE_LOADED)
-    {
-      priv->tiles_loading--;
-      if (priv->tiles_loading == 0)
-        {
-          priv->state = CHAMPLAIN_STATE_DONE;
-          g_object_notify (G_OBJECT (view), "state");
-        }
-    }
-}
-
-
-static void
-tile_state_notify (GObject *gobject,
+tile_state_notify (ChamplainTile *tile,
     G_GNUC_UNUSED GParamSpec *pspec,
-    gpointer data)
-{
-  DEBUG_LOG ()
-
-  view_update_state (CHAMPLAIN_VIEW (data), CHAMPLAIN_TILE (gobject));
-}
-
-
-static void
-view_update_state (ChamplainView *view, ChamplainTile *tile)
+    ChamplainView *view)
 {
   DEBUG_LOG ()
-
+  
   ChamplainState tile_state = champlain_tile_get_state (tile);
   ChamplainViewPrivate *priv = view->priv;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]