T
Taddio
Guest
I have this world generator that takes a picture and extracts data from colors and sets values in a grid according to the color. That works great, I can then set tiles according to the grid data.
The map is divided in a GRID, in which each cell stores a MAP for specific cell information.
It all works good, but I found I have a memory leak, and I can't find it. My CleanUp and destroy event are failproof (it seems) and running.
I provided the code below.
Can it be that somehow, destroying the top level grid does not free the containing maps automatically? According to the manual, it should, of I remember correctly.
This is the Create event.
And this is the Destroy and CleanUp event (they do run, I tried putting a breakpoint and they ran good)
It does leak no matter if I copy the grid to obj_data and destroy the generator or if I don't destroy it and simply reset a room where he's the only object, so obj_data is to rule out of the suspects. There's only his one generator object in the room.
The map is divided in a GRID, in which each cell stores a MAP for specific cell information.
It all works good, but I found I have a memory leak, and I can't find it. My CleanUp and destroy event are failproof (it seems) and running.
I provided the code below.
Can it be that somehow, destroying the top level grid does not free the containing maps automatically? According to the manual, it should, of I remember correctly.
This is the Create event.
Code:
/// @description Generate world
randomize();
#region Surface and save it to a sprite
application_surface_enable(false); //We don't really need it
surf_terrain = 0; //Will be the terrain surface
spr_surf = 0; //Will be a sprite of the surface, to save it
//Create terrain surface
if(!surface_exists(surf_terrain)) {
surf_terrain = surface_create(room_width, room_height); //This is the terrain surface
} else { surface_free(surf_terrain); }
spr_surf = 0; //Will be a sprite of the surface, to save it
//Get scaling variables
var _spr_w, _spr_h, _x_scale, _y_scale;
_spr_w = sprite_get_width(spr_pixel_map); //Get width of terrain sprite
_spr_h = sprite_get_height(spr_pixel_map); //Get height of terrain sprite
_x_scale = (room_width/_spr_w); //get aspet ration in X
_y_scale = (room_height/_spr_h); //Get aspect ratio in Y
//Chooses a random sprite
var _spr_map, _map_num;
_map_num = sprite_get_number(spr_pixel_map)-1;
_spr_map = irandom(_map_num);
//Draw the sprites onto surface
surface_set_target(surf_terrain);
draw_sprite_ext(spr_pixel_map, _spr_map, 0, 0, _x_scale, _y_scale, 0, c_white, 1);
surface_reset_target();
//Copy the surface to a sprite
if(!sprite_exists(spr_surf)) {
spr_surf = sprite_create_from_surface(surf_terrain, 0, 0, room_width, room_height, 0, 0, 0, 0);
}
#endregion
#region Creates world based on color of bg
var max_chunk_w = room_width/TILE_SIZE; //Get number of horizontalgrid cell in room
var max_chunk_h = room_height/TILE_SIZE; //Get number of vertical grid cell in room
var _buff = buffer_getpixel_begin(surf_terrain); //Creates buffer and get surface data
grid_terrain = ds_grid_create(max_chunk_w, max_chunk_h); //This ds_grid holds all terrain values
//Loop variables
var _i, _j, _col, _red, _blue, _green, _xx, _yy, _offset;
var _map, _type, _mine, _pass;
_offset = (TILE_SIZE/2);
//Loops through grid to find color of pixels at middle center of grid
for(_i=0; _i<=max_chunk_w-1; _i++) { //Loops through all ds_grid in X
for(_j=0; _j <=max_chunk_h-1; _j++) { //Loops through all ds_grid in Y
_xx = _i<<5; //Multiply _i by 16 (TILE SIZE)
_yy = _j<<5; //Multiply _j by 16 (TILE SIZE)
//Create maps that will hold all grid cell data
_map = ds_map_create();
//Get pixel color of the middle-center of the grid cell
_col = buffer_getpixel(_buff, _xx+_offset, _yy+_offset, room_width, room_height);
//Get the color value (colors swapped because RGB vs. BGR)
_blue = (color_get_red(_col));
_red = (color_get_blue(_col));
_green = (color_get_green(_col));
//Make cell value according to color
if(_blue == 255){ //Light blue
_type = TILE_WATER;
_mine = 0;
_pass = 0;
} else
if(_blue == 128){ //Dark blue
_type = TILE_WALL;
_mine = 0;
_pass = 0;
} else
if(_red == 255){ //Light red
_type = TILE_MG42;
_mine = 0;
_pass = 0;
} else
if(_red == 128){ //Dark red
_type = TILE_SAND;
_mine = 1;
_pass = 1;
} else
if(_green == 255){ //Light green
_type = TILE_GRASS;
_mine = 1;
_pass = 1;
} else
if(_green == 128){ //Dark green
_type = TILE_CONCRETE;
_mine = 0;
_pass = 1;
}
ds_map_add(_map, "TYPE", _type);
ds_map_add(_map, "MINE", _mine);
ds_map_add(_map, "PASS", _pass);
//Set grid value in relation to color
ds_grid_set(grid_terrain, _i, _j, _map);
}
}
//Copy grid to data object
with(obj_data){
grid_terrain = ds_grid_create(max_chunk_w, max_chunk_h); //This ds_grid holds all terrain values
ds_grid_copy(grid_terrain, other.grid_terrain);
}
//Delete buffer because we don't need it anymore
buffer_delete(_buff);
#endregion
//Set tiles according to grid cell value
var max_chunk_w = room_width/TILE_SIZE; //Get number of horizontal grid cell in room
var max_chunk_h = room_height/TILE_SIZE; //Get number of vertical grid cell in room
var _ind;
var lay_id = layer_get_id("Tiles_terrain");
var map_id = layer_tilemap_get_id(lay_id);
for(var _w=0; _w <= (max_chunk_w-1); _w++) {
for(var _h=0; _h <= (max_chunk_h-1); _h++) {
var _cell = ds_grid_get(grid_terrain, _w, _h);
var _type = ds_map_find_value(_cell, "TYPE")
switch(_type){
case TILE_WALL:
_ind = 5;
break
case TILE_CONCRETE:
_ind = 3;
break;
case TILE_GRASS:
_ind = 1;
break;
case TILE_WATER:
_ind = 4;
break;
case TILE_SAND:
_ind = 2;
break;
case TILE_MG42:
_ind = 6;
break;
}
//DRAW TILES
var _xx = _w<<5; //Get x position of tile
var _yy = _h<<5; //Get y position of tile
tilemap_set(map_id, _ind, _w, _h);
}
}
//Destroy the world generator
instance_destroy();
And this is the Destroy and CleanUp event (they do run, I tried putting a breakpoint and they ran good)
Code:
/// @description DS, sprite and surface
if(ds_exists(grid_terrain, ds_type_grid)){
ds_grid_destroy(grid_terrain);
}
if(surface_exists(surf_terrain)){
surface_free(surf_terrain);
}
if(sprite_exists(spr_surf)){
sprite_delete(spr_surf);
}
It does leak no matter if I copy the grid to obj_data and destroy the generator or if I don't destroy it and simply reset a room where he's the only object, so obj_data is to rule out of the suspects. There's only his one generator object in the room.