static void
fill_tile (ChamplainMapSource *map_source,
    ChamplainTile *tile)
{
  g_return_if_fail (CHAMPLAIN_IS_MEMORY_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_DONE)
    return;

  if (champlain_tile_get_state (tile) != CHAMPLAIN_STATE_LOADED)
    {
      ChamplainMemoryCache *memory_cache = CHAMPLAIN_MEMORY_CACHE (map_source);
      ChamplainMemoryCachePrivate *priv = memory_cache->priv;
      ChamplainRenderer *renderer;
      GList *link;
      gchar *key;

      key = generate_queue_key (memory_cache, tile);
      link = g_hash_table_lookup (priv->hash_table, key);
      g_free (key);
      if (link)
        {
          QueueMember *member = link->data;

          move_queue_member_to_head (priv->queue, link);

          renderer = champlain_map_source_get_renderer (map_source);

          g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));

          g_object_ref (map_source);
          g_object_ref (tile);

          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);

          return;
        }
    }

  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);
    }
}
static gchar *
generate_queue_key (ChamplainMemoryCache *memory_cache,
    ChamplainTile *tile)
{
  g_return_val_if_fail (CHAMPLAIN_IS_MEMORY_CACHE (memory_cache), NULL);
  g_return_val_if_fail (CHAMPLAIN_IS_TILE (tile), NULL);

  ChamplainMapSource *map_source = CHAMPLAIN_MAP_SOURCE (memory_cache);
  gchar *key;

  key = g_strdup_printf ("%d/%d/%d/%s",
        champlain_tile_get_zoom_level (tile),
        champlain_tile_get_x (tile),
        champlain_tile_get_y (tile),
        champlain_map_source_get_id (map_source));
  return key;
}
static void
on_tile_filled (ChamplainTileCache *tile_cache,
    ChamplainTile *tile)
{
  g_return_if_fail (CHAMPLAIN_IS_MEMORY_CACHE (tile_cache));
  g_return_if_fail (CHAMPLAIN_IS_TILE (tile));

  ChamplainMapSource *map_source = CHAMPLAIN_MAP_SOURCE (tile_cache);
  ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
  ChamplainMemoryCache *memory_cache = CHAMPLAIN_MEMORY_CACHE (tile_cache);
  ChamplainMemoryCachePrivate *priv = memory_cache->priv;
  GList *link;
  gchar *key;

  key = generate_queue_key (memory_cache, tile);
  link = g_hash_table_lookup (priv->hash_table, key);
  g_free (key);
  if (link)
    move_queue_member_to_head (priv->queue, link);

  if (CHAMPLAIN_IS_TILE_CACHE (next_source))
    champlain_tile_cache_on_tile_filled (CHAMPLAIN_TILE_CACHE (next_source), tile);
}
static void
fill_tile (ChamplainMapSource *map_source,
    ChamplainTile *tile)
{
  g_return_if_fail (CHAMPLAIN_IS_FILE_TILE_SOURCE (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_DONE)
    return;

  if (champlain_tile_get_state (tile) != CHAMPLAIN_STATE_LOADED)
    {
      ChamplainRenderer *renderer;

      renderer = champlain_map_source_get_renderer (map_source);

      g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer));

      g_object_ref (map_source);
      g_object_ref (tile);

      g_signal_connect (tile, "render-complete", G_CALLBACK (tile_rendered_cb), map_source);

      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);
    }
}