Commit 191394a29db4da0ee4bb3c1121d4bd28d711ff16

Make it possible to manually chain chains.

Chains should behave as other map sources so it should be possible
to create chains of chains. For now, chains of chains have to be
created manually - i.e. the outer chain cannot be ChamplainMapSourceChain
but has to be created by _set_next_source(). The reason is that
a chain has to know about each of its elements whether it is a map
source or a cache (if this feature is desirable, we can add a virtual
method of map sources that determines whether it behaves as a map source
or cache so even if the map source is a chain, it could have this
information attached).

Signed-off-by: Jiří Techet <techet@gmail.com>
champlain/champlain-map-source-chain.c
(59 / 20)
  
4343struct _ChamplainMapSourceChainPrivate
4444{
4545 ChamplainMapSource *stack_top;
46 ChamplainMapSource *stack_bottom;
4647 gulong sig_handler_id;
4748};
4849
5656static guint get_tile_size (ChamplainMapSource *map_source);
5757
5858static void fill_tile (ChamplainMapSource *map_source, ChamplainTile *tile);
59static void on_set_next_source (ChamplainMapSource *map_source,
60 ChamplainMapSource *old_next_source,
61 ChamplainMapSource *new_next_source);
5962
6063static void
6164champlain_map_source_chain_dispose (GObject *object)
9999 map_source_class->get_tile_size = get_tile_size;
100100
101101 map_source_class->fill_tile = fill_tile;
102 map_source_class->on_set_next_source = on_set_next_source;
102103}
103104
104105static void
107107{
108108 ChamplainMapSourceChainPrivate *priv = GET_PRIVATE(source_chain);
109109 priv->stack_top = NULL;
110 priv->sig_handler_id = 0;
110 priv->stack_bottom = NULL;
111111}
112112
113113/**
119119 *
120120 * Since: 0.6
121121 */
122ChamplainMapSourceChain* champlain_map_source_chain_new (void)
122ChamplainMapSourceChain*
123champlain_map_source_chain_new (void)
123124{
124125 return g_object_new (CHAMPLAIN_TYPE_MAP_SOURCE_CHAIN, NULL);
125126}
209209 return champlain_map_source_get_tile_size (priv->stack_top);
210210}
211211
212static void fill_tile (ChamplainMapSource *map_source,
213 ChamplainTile *tile)
212static void
213fill_tile (ChamplainMapSource *map_source,
214 ChamplainTile *tile)
214215{
215216 ChamplainMapSourceChain *source_chain = CHAMPLAIN_MAP_SOURCE_CHAIN (map_source);
216217 g_return_if_fail (source_chain);
222222 champlain_map_source_fill_tile (priv->stack_top, tile);
223223}
224224
225static void assign_cache_of_next_source_sequence (ChamplainMapSource *start_map_source, ChamplainTileCache *tile_cache)
225static void
226on_set_next_source (ChamplainMapSource *map_source,
227 ChamplainMapSource *old_next_source,
228 ChamplainMapSource *new_next_source)
226229{
230 ChamplainMapSourceChain *source_chain = CHAMPLAIN_MAP_SOURCE_CHAIN (map_source);
231 ChamplainMapSourceChainPrivate *priv = GET_PRIVATE(source_chain);
232
233 g_return_if_fail (source_chain);
234
235 if (priv->stack_bottom)
236 champlain_map_source_set_next_source (priv->stack_bottom, new_next_source);
237}
238
239static void
240assign_cache_of_next_source_sequence (ChamplainMapSourceChain *source_chain,
241 ChamplainMapSource *start_map_source,
242 ChamplainTileCache *tile_cache)
243{
227244 ChamplainMapSource *map_source = start_map_source;
228 ChamplainTileSource *tile_source;
245 ChamplainMapSource *chain_next_source = champlain_map_source_get_next_source (CHAMPLAIN_MAP_SOURCE(source_chain));
229246
230247 do
231248 {
250250 }
251251 while (CHAMPLAIN_IS_TILE_CACHE(map_source));
252252
253 tile_source = CHAMPLAIN_TILE_SOURCE(map_source);
254 while (tile_source)
253 while (CHAMPLAIN_IS_TILE_SOURCE(map_source) && map_source != chain_next_source)
255254 {
256 champlain_tile_source_set_cache (tile_source, tile_cache);
255 champlain_tile_source_set_cache (CHAMPLAIN_TILE_SOURCE(map_source), tile_cache);
257256 map_source = champlain_map_source_get_next_source (map_source);
258 tile_source = CHAMPLAIN_TILE_SOURCE(map_source);
259257 }
260258}
261259
262static
263void reload_tiles_cb (ChamplainMapSource *map_source, ChamplainMapSourceChain *source_chain)
260static void
261reload_tiles_cb (ChamplainMapSource *map_source, ChamplainMapSourceChain *source_chain)
264262{
265263 /* propagate the signal from the chain that is inside champlain_map_source_chain */
266264 g_signal_emit_by_name (source_chain, "reload-tiles", NULL);
273273 *
274274 * Since: 0.6
275275 */
276void champlain_map_source_chain_push (ChamplainMapSourceChain *source_chain, ChamplainMapSource *map_source)
276void
277champlain_map_source_chain_push (ChamplainMapSourceChain *source_chain, ChamplainMapSource *map_source)
277278{
278279 ChamplainMapSourceChainPrivate *priv = GET_PRIVATE(source_chain);
279280 gboolean is_cache = FALSE;
288288
289289 if (!priv->stack_top)
290290 {
291 ChamplainMapSource *chain_next_source = champlain_map_source_get_next_source (CHAMPLAIN_MAP_SOURCE(source_chain));
292
291293 /* tile source has to be last */
292294 g_return_if_fail (!is_cache);
295
293296 priv->stack_top = map_source;
297 priv->stack_bottom = map_source;
298 if (chain_next_source)
299 champlain_map_source_set_next_source (priv->stack_bottom, chain_next_source);
294300 }
295301 else
296302 {
309309 if (is_cache)
310310 {
311311 ChamplainTileCache *tile_cache = CHAMPLAIN_TILE_CACHE(map_source);
312 assign_cache_of_next_source_sequence (priv->stack_top, tile_cache);
312 assign_cache_of_next_source_sequence (source_chain, priv->stack_top, tile_cache);
313313 }
314314 }
315315
325325 *
326326 * Since: 0.6
327327 */
328void champlain_map_source_chain_pop (ChamplainMapSourceChain *source_chain)
328void
329champlain_map_source_chain_pop (ChamplainMapSourceChain *source_chain)
329330{
330331 ChamplainMapSourceChainPrivate *priv = GET_PRIVATE(source_chain);
331332 ChamplainMapSource *old_stack_top = priv->stack_top;
333 ChamplainMapSource *next_source = champlain_map_source_get_next_source (priv->stack_top);
332334
333335 g_return_if_fail (priv->stack_top);
334336
339339
340340 if (CHAMPLAIN_IS_TILE_CACHE(priv->stack_top))
341341 {
342 ChamplainMapSource *map_source = champlain_map_source_get_next_source (priv->stack_top);
343342 ChamplainTileCache *tile_cache = NULL;
344343
345 if (CHAMPLAIN_IS_TILE_CACHE(map_source))
346 tile_cache = CHAMPLAIN_TILE_CACHE(map_source);
344 if (CHAMPLAIN_IS_TILE_CACHE(next_source))
345 tile_cache = CHAMPLAIN_TILE_CACHE(next_source);
347346
348 assign_cache_of_next_source_sequence (priv->stack_top, tile_cache);
347 /* _push() guarantees that the last source is tile_source so we can be
348 sure that the next map source is still within the chain */
349 assign_cache_of_next_source_sequence (source_chain, priv->stack_top, tile_cache);
349350 }
350351
351 priv->stack_top = champlain_map_source_get_next_source (priv->stack_top);
352 if (next_source == champlain_map_source_get_next_source (CHAMPLAIN_MAP_SOURCE(source_chain)))
353 {
354 priv->stack_top = NULL;
355 priv->stack_bottom = NULL;
356 }
357 else
358 priv->stack_top = next_source;
359
352360 if (priv->stack_top)
353361 {
354362 priv->sig_handler_id = g_signal_connect (priv->stack_top, "reload-tiles",
champlain/champlain-map-source.c
(26 / 9)
  
8383};
8484
8585static void reload_tiles_cb (ChamplainMapSource *orig, ChamplainMapSource *self);
86static void on_set_next_source (ChamplainMapSource *map_source,
87 ChamplainMapSource *old_next_source,
88 ChamplainMapSource *new_next_source);
8689
8790static void
8891champlain_map_source_get_property (GObject *object,
176176 klass->get_projection = NULL;
177177
178178 klass->fill_tile = NULL;
179 klass->on_set_next_source = on_set_next_source;
179180
180181 /**
181182 * ChamplainMapSource:next-source:
242242 g_signal_emit_by_name (self, "reload-tiles", NULL);
243243}
244244
245static void
246on_set_next_source (ChamplainMapSource *map_source,
247 ChamplainMapSource *old_next_source,
248 ChamplainMapSource *new_next_source)
249{
250 ChamplainMapSourcePrivate *priv = GET_PRIVATE(map_source);
251 if (old_next_source)
252 {
253 if (g_signal_handler_is_connected (old_next_source, priv->sig_handler_id))
254 g_signal_handler_disconnect (old_next_source, priv->sig_handler_id);
255 }
256
257 if (new_next_source)
258 {
259 priv->sig_handler_id = g_signal_connect (new_next_source, "reload-tiles",
260 G_CALLBACK (reload_tiles_cb), map_source);
261 }
262}
263
245264/**
246265 * champlain_map_source_set_next_source:
247266 * @map_source: a #ChamplainMapSource
278278
279279 ChamplainMapSourcePrivate *priv = GET_PRIVATE(map_source);
280280
281 CHAMPLAIN_MAP_SOURCE_GET_CLASS (map_source)->on_set_next_source (map_source, priv->next_source, next_source);
282
281283 if (priv->next_source != NULL)
282 {
283 if (g_signal_handler_is_connected (priv->next_source, priv->sig_handler_id))
284 g_signal_handler_disconnect (priv->next_source, priv->sig_handler_id);
284 g_object_unref (priv->next_source);
285285
286 g_object_unref (priv->next_source);
287 }
288
289286 if (next_source)
290287 {
291288 g_return_if_fail (CHAMPLAIN_IS_MAP_SOURCE (next_source));
292289
293290 g_object_ref_sink (next_source);
294
295 priv->sig_handler_id = g_signal_connect (next_source, "reload-tiles",
296 G_CALLBACK (reload_tiles_cb), map_source);
297291 }
298292
299293 priv->next_source = next_source;
champlain/champlain-map-source.h
(4 / 0)
  
6363
6464 void (*fill_tile) (ChamplainMapSource *map_source,
6565 ChamplainTile *tile);
66
67 void (*on_set_next_source) (ChamplainMapSource *map_source,
68 ChamplainMapSource *next_source,
69 ChamplainMapSource *new_next_source);
6670};
6771
6872GType champlain_map_source_get_type (void);

Comments

Add a new comment:

Login or create an account to post a comment

Add your comment