]> err.no Git - libchamplain/commitdiff
Keep only visible tiles and level in memory
authorPierre-Luc Beaudoin <pierlux@carbon.(none)>
Thu, 4 Sep 2008 17:44:37 +0000 (13:44 -0400)
committerPierre-Luc Beaudoin <pierlux@carbon.(none)>
Thu, 4 Sep 2008 17:44:37 +0000 (13:44 -0400)
champlain/map.c
champlain/map.h
champlain/tile.c
champlain/zoomlevel.c

index 60dfbd6d2b9ba102fb32f82fb1d909badcbf0f89..3538cc8e5644379fa7e617139312f6c9dbc26a46 100644 (file)
@@ -47,7 +47,7 @@ map_new (ChamplainMapSource source)
         break;
     }
   
-  map->levels = g_ptr_array_sized_new (map->zoom_levels);
+  map->previous_level = NULL;
   map->current_level = NULL;
 
   return map;
@@ -56,11 +56,14 @@ map_new (ChamplainMapSource source)
 void 
 map_load_level(Map* map, gint zoom_level)
 {
+  if (map->previous_level)
+    zoom_level_free(map->previous_level);
+  map->previous_level = map->current_level;
+
   guint row_count = map->get_row_count(map, zoom_level);
   guint column_count = map->get_column_count(map, zoom_level);
 
   map->current_level = zoom_level_new(zoom_level, row_count, column_count, map->tile_size);
-  g_ptr_array_add(map->levels, map->current_level);
 }
 
 void
@@ -74,16 +77,32 @@ map_load_visible_tiles (Map* map, GdkRectangle viewport, gboolean offline)
   
   x_count += x_first;
   y_count += y_first;
-  g_print("Tiles: %d, %d to %d, %d\n", x_first, y_first, x_count, y_count);
+
+  if(x_count > map->current_level->row_count)
+    x_count = map->current_level->row_count;
+  if(y_count > map->current_level->column_count)
+    y_count = map->current_level->column_count;
+
+  //g_print("Tiles: %d, %d to %d, %d\n", x_first, y_first, x_count, y_count);
   
   int i, j, k;
+
+  // Get rid of old tiles first
+  for (k = 0; k < map->current_level->tiles->len; k++)
+    {
+      Tile* tile = g_ptr_array_index(map->current_level->tiles, k);
+      if (tile->x < x_first || tile->x > x_count || tile->y < y_first || tile->y > y_count)
+        {
+          g_ptr_array_remove (map->current_level->tiles, tile);
+          tile_free(tile);
+        }
+    }
+  
+  //Load new tiles if needed
   for (i = x_first; i < x_count; i++)
     {
       for (j = y_first; j < y_count; j++)
         {
-          if(i >= map->current_level->row_count || j >= map->current_level->column_count)
-            continue;
-            
           gboolean exist = FALSE;
           for (k = 0; k < map->current_level->tiles->len && !exist; k++)
             {
@@ -107,22 +126,7 @@ map_zoom_in (Map* map)
   gint new_level = map->current_level->level + 1;
   if(new_level <= map->zoom_levels)
     {
-      gboolean exist = FALSE;
-      int i;
-      for (i = 0; i < map->levels->len && !exist; i++)
-        {
-          ZoomLevel* level = g_ptr_array_index(map->levels, i);
-          if (level && level->level == new_level)
-            {
-              exist = TRUE;
-              map->current_level = level;
-            }
-        }
-
-      if(!exist)
-        {
-          map_load_level(map, map->current_level->level + 1);
-        }
+      map_load_level(map, new_level);
       return TRUE;
     }
   return FALSE;
@@ -134,22 +138,7 @@ map_zoom_out (Map* map)
   gint new_level = map->current_level->level - 1;
   if(new_level >= 0)
     {
-      gboolean exist = FALSE;
-      int i;
-      for (i = 0; i < map->levels->len && !exist; i++)
-        {
-          ZoomLevel* level = g_ptr_array_index(map->levels, i);
-          if (level && level->level == new_level)
-            {
-              exist = TRUE;
-              map->current_level = level;
-            }
-        }
-
-      if(!exist)
-        {
-          map_load_level(map, map->current_level->level - 1);
-        }
+      map_load_level(map, new_level);
       return TRUE;
     }
   return FALSE;
@@ -158,12 +147,7 @@ map_zoom_out (Map* map)
 void 
 map_free (Map* map)
 {
-  int i;
-  for (i = 0; i < map->levels->len; i++)
-    {
-      ZoomLevel* level = g_ptr_array_index(map->levels, i);
-      zoom_level_free(level);
-    }
+  zoom_level_free(map->current_level);
 }
 
 gboolean 
@@ -172,22 +156,7 @@ map_zoom_to (Map* map, guint zoomLevel)
   if(zoomLevel >= 0 && 
      zoomLevel<= map->zoom_levels)
     {
-      gboolean exist = FALSE;
-      int i;
-      for (i = 0; i < map->levels->len && !exist; i++)
-        {
-          ZoomLevel* level = g_ptr_array_index(map->levels, i);
-          if (level && level->level == zoomLevel)
-            {
-              exist = TRUE;
-              map->current_level = level;
-            }
-        }
-
-      if(!exist)
-        {
-          map_load_level(map, zoomLevel);
-        }
+      map_load_level(map, zoomLevel);
       return TRUE;
     }
   return FALSE;
index 03f3eee336fc9966db0a5dc0934f0757313a3105..911c1970dcdfc42177f4f57cc36e2998aef6be28 100644 (file)
@@ -37,7 +37,7 @@ struct _Map
   int tile_size;
 
   ZoomLevel* current_level;
-  GPtrArray  *levels;
+  ZoomLevel* previous_level;
   
   guint (* get_row_count) (Map* map, guint zoom_level);
   guint (* get_column_count) (Map* map, guint zoom_level);
index 717a644a0be90ae7392a9530ec314d662f10dc9d..01f92969c0ad2f3abb99e217adc4d6c1be0721bb 100644 (file)
@@ -42,7 +42,6 @@ tile_set(Map* map, Tile* tile)
     (tile->y * tile->size) - map->current_level->anchor.y);
   clutter_actor_set_size (tile->actor, tile->size, tile->size);
   clutter_actor_show (tile->actor);
-  g_print("Tile %d, %d\n", (tile->x * tile->size) - map->current_level->anchor.x, (tile->y * tile->size) - map->current_level->anchor.y);
 }
 
 static void 
@@ -206,4 +205,5 @@ tile_free(Tile* tile)
 {
   if(tile->actor)
     clutter_actor_destroy(tile->actor);
+  g_free(tile);
 }
index 8d4c86c082d7256d2ea44138b6a48af618566d80..f8d4a217a56dee442f410edb9f7c2a2e3224c5d1 100644 (file)
@@ -31,11 +31,9 @@ zoom_level_new(gint zoom_level, gint row, gint column, gint tile_size)
   level->row_count = row;
   level->column_count = column;
   level->tile_size = tile_size;
-  gint count = row * column;
-  if (row * column > 256)
-    count = 256;
-    
-  level->tiles = g_ptr_array_sized_new (count);
+
+  //FIXME: this hard coded value means that there can't be more than 16x16 tiles displayed at once
+  level->tiles = g_ptr_array_sized_new (256);
   level->group = clutter_group_new ();
   
   g_object_ref(level->group); // so that the group isn't destroyed when removed from the viewport