static void
tile_rendered_cb (ChamplainTile *tile,
    gpointer data,
    guint size,
    gboolean error,
    ChamplainMapSource *map_source)
{
  ChamplainMapSource *next_source;

  g_signal_handlers_disconnect_by_func (tile, tile_rendered_cb, map_source);

  next_source = champlain_map_source_get_next_source (map_source);

  if (!error)
    {
      if (CHAMPLAIN_IS_TILE_CACHE (next_source))
        champlain_tile_cache_on_tile_filled (CHAMPLAIN_TILE_CACHE (next_source), tile);

      champlain_tile_set_fade_in (tile, FALSE);
      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);

  g_object_unref (map_source);
  g_object_unref (tile);
}
/**
 * champlain_map_source_chain_pop:
 * @source_chain: a #ChamplainMapSourceChain
 *
 * Pops a map source from the top of the stack from the chain.
 *
 * Since: 0.6
 */
void
champlain_map_source_chain_pop (ChamplainMapSourceChain *source_chain)
{
  ChamplainMapSourceChainPrivate *priv = source_chain->priv;
  ChamplainMapSource *old_stack_top = priv->stack_top;
  ChamplainMapSource *next_source = champlain_map_source_get_next_source (priv->stack_top);

  g_return_if_fail (priv->stack_top);

  if (CHAMPLAIN_IS_TILE_CACHE (priv->stack_top))
    {
      ChamplainTileCache *tile_cache = NULL;

      if (CHAMPLAIN_IS_TILE_CACHE (next_source))
        tile_cache = CHAMPLAIN_TILE_CACHE (next_source);

      /* _push() guarantees that the last source is tile_source so we can be
         sure that the next map source is still within the chain */
      assign_cache_of_next_source_sequence (source_chain, priv->stack_top, tile_cache);
    }

  if (next_source == champlain_map_source_get_next_source (CHAMPLAIN_MAP_SOURCE (source_chain)))
    {
      priv->stack_top = NULL;
      priv->stack_bottom = NULL;
    }
  else
    priv->stack_top = next_source;

  g_object_unref (old_stack_top);
}
static void
refresh_tile_time (ChamplainTileCache *tile_cache,
    ChamplainTile *tile)
{
  g_return_if_fail (CHAMPLAIN_IS_MEMORY_CACHE (tile_cache));

  ChamplainMapSource *map_source = CHAMPLAIN_MAP_SOURCE (tile_cache);
  ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);

  if (CHAMPLAIN_IS_TILE_CACHE (next_source))
    champlain_tile_cache_refresh_tile_time (CHAMPLAIN_TILE_CACHE (next_source), tile);
}
static void
store_tile (ChamplainTileCache *tile_cache,
    ChamplainTile *tile,
    const gchar *contents,
    gsize size)
{
  g_return_if_fail (CHAMPLAIN_IS_MEMORY_CACHE (tile_cache));

  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);
  if (link)
    {
      move_queue_member_to_head (priv->queue, link);
      g_free (key);
    }
  else
    {
      QueueMember *member;

      if (priv->queue->length >= priv->size_limit)
        {
          member = g_queue_pop_tail (priv->queue);
          g_hash_table_remove (priv->hash_table, member->key);
          delete_queue_member (member, NULL);
        }

      member = g_slice_new (QueueMember);
      member->key = key;
      member->data = g_memdup (contents, size);
      member->size = size;

      g_queue_push_head (priv->queue, member);
      g_hash_table_insert (priv->hash_table, g_strdup (key), g_queue_peek_head_link (priv->queue));
    }

  if (CHAMPLAIN_IS_TILE_CACHE (next_source))
    champlain_tile_cache_store_tile (CHAMPLAIN_TILE_CACHE (next_source), tile, contents, size);
}
예제 #5
0
/**
 * champlain_map_source_chain_push:
 * @source_chain: a #ChamplainMapSourceChain
 * @map_source: the #ChamplainMapSource to be pushed into the chain
 *
 * Pushes a map source into the chain.
 *
 * Since: 0.6
 */
void
champlain_map_source_chain_push (ChamplainMapSourceChain *source_chain,
    ChamplainMapSource *map_source)
{
  ChamplainMapSourceChainPrivate *priv = source_chain->priv;
  gboolean is_cache = FALSE;

  if (CHAMPLAIN_IS_TILE_CACHE(map_source))
    is_cache = TRUE;
  else
    g_return_if_fail (CHAMPLAIN_IS_TILE_SOURCE(map_source));

  g_object_ref_sink (map_source);

  if (!priv->stack_top)
    {
      ChamplainMapSource *chain_next_source = champlain_map_source_get_next_source (CHAMPLAIN_MAP_SOURCE(source_chain));

      /* tile source has to be last */
      g_return_if_fail (!is_cache);

      priv->stack_top = map_source;
      priv->stack_bottom = map_source;
      if (chain_next_source)
        champlain_map_source_set_next_source (priv->stack_bottom, chain_next_source);
    }
  else
    {
      if (g_signal_handler_is_connected (priv->stack_top, priv->sig_handler_id))
        g_signal_handler_disconnect (priv->stack_top, priv->sig_handler_id);

      champlain_map_source_set_next_source (map_source, priv->stack_top);
      priv->stack_top = map_source;

      if (is_cache)
        {
          ChamplainTileCache *tile_cache = CHAMPLAIN_TILE_CACHE(map_source);
          assign_cache_of_next_source_sequence (source_chain, priv->stack_top, tile_cache);
        }
    }

  priv->sig_handler_id = g_signal_connect (priv->stack_top, "reload-tiles",
                         G_CALLBACK (reload_tiles_cb), source_chain);
}
예제 #6
0
/**
 * champlain_map_source_chain_pop:
 * @source_chain: a #ChamplainMapSourceChain
 *
 * Pops the map source from the top of the stack from the chain.
 *
 * Since: 0.6
 */
void
champlain_map_source_chain_pop (ChamplainMapSourceChain *source_chain)
{
  ChamplainMapSourceChainPrivate *priv = source_chain->priv;
  ChamplainMapSource *old_stack_top = priv->stack_top;
  ChamplainMapSource *next_source = champlain_map_source_get_next_source (priv->stack_top);

  g_return_if_fail (priv->stack_top);

  if (g_signal_handler_is_connected (priv->stack_top, priv->sig_handler_id))
    g_signal_handler_disconnect (priv->stack_top, priv->sig_handler_id);

  if (CHAMPLAIN_IS_TILE_CACHE(priv->stack_top))
    {
      ChamplainTileCache *tile_cache = NULL;

      if (CHAMPLAIN_IS_TILE_CACHE(next_source))
        tile_cache = CHAMPLAIN_TILE_CACHE(next_source);

      /* _push() guarantees that the last source is tile_source so we can be
         sure that the next map source is still within the chain */
      assign_cache_of_next_source_sequence (source_chain, priv->stack_top, tile_cache);
    }

  if (next_source == champlain_map_source_get_next_source (CHAMPLAIN_MAP_SOURCE(source_chain)))
  {
    priv->stack_top = NULL;
    priv->stack_bottom = NULL;
  }
  else
    priv->stack_top = next_source;

  if (priv->stack_top)
    {
      priv->sig_handler_id = g_signal_connect (priv->stack_top, "reload-tiles",
                             G_CALLBACK (reload_tiles_cb), source_chain);
    }

  g_object_unref (old_stack_top);
}
/**
 * champlain_map_source_chain_push:
 * @source_chain: a #ChamplainMapSourceChain
 * @map_source: the #ChamplainMapSource to be pushed into the chain
 *
 * Pushes a map source into the chain.
 *
 * Since: 0.6
 */
void
champlain_map_source_chain_push (ChamplainMapSourceChain *source_chain,
    ChamplainMapSource *map_source)
{
  ChamplainMapSourceChainPrivate *priv = source_chain->priv;
  gboolean is_cache = FALSE;

  if (CHAMPLAIN_IS_TILE_CACHE (map_source))
    is_cache = TRUE;
  else
    g_return_if_fail (CHAMPLAIN_IS_TILE_SOURCE (map_source));

  g_object_ref_sink (map_source);

  if (!priv->stack_top)
    {
      ChamplainMapSource *chain_next_source = champlain_map_source_get_next_source (CHAMPLAIN_MAP_SOURCE (source_chain));

      /* tile source has to be last */
      g_return_if_fail (!is_cache);

      priv->stack_top = map_source;
      priv->stack_bottom = map_source;
      if (chain_next_source)
        champlain_map_source_set_next_source (priv->stack_bottom, chain_next_source);
    }
  else
    {
      champlain_map_source_set_next_source (map_source, priv->stack_top);
      priv->stack_top = map_source;

      if (is_cache)
        {
          ChamplainTileCache *tile_cache = CHAMPLAIN_TILE_CACHE (map_source);
          assign_cache_of_next_source_sequence (source_chain, priv->stack_top, tile_cache);
        }
    }
}
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);
}