Revision: 7631
http://playerstage.svn.sourceforge.net/playerstage/?rev=7631&view=rev
Author: thjc
Date: 2009-05-09 15:16:57 +0000 (Sat, 09 May 2009)
Log Message:
-----------
fixing some memory leaks
Modified Paths:
--------------
code/stage/trunk/libstage/block.cc
code/stage/trunk/libstage/worldfile.cc
Modified: code/stage/trunk/libstage/block.cc
===================================================================
--- code/stage/trunk/libstage/block.cc 2009-05-08 21:41:48 UTC (rev 7630)
+++ code/stage/trunk/libstage/block.cc 2009-05-09 15:16:57 UTC (rev 7631)
@@ -7,8 +7,8 @@
/** Create a new block. A model's body is a list of these
blocks. The point data is copied, so pts can safely be freed
after calling this.*/
-Block::Block( Model* mod,
- stg_point_t* pts,
+Block::Block( Model* mod,
+ stg_point_t* pts,
size_t pt_count,
stg_meters_t zmin,
stg_meters_t zmax,
@@ -33,31 +33,32 @@
}
/** A from-file constructor */
-Block::Block( Model* mod,
- Worldfile* wf,
- int entity)
+Block::Block( Model* mod,
+ Worldfile* wf,
+ int entity)
: mod( mod ),
mpts(NULL),
- pt_count(0),
- pts(NULL),
+ pt_count(0),
+ pts(NULL),
color(0),
inherit_color(true),
- rendered_cells( g_ptr_array_sized_new(32) ),
+ rendered_cells( g_ptr_array_sized_new(32) ),
candidate_cells( g_ptr_array_sized_new(32) )
{
assert(mod);
assert(wf);
assert(entity);
-
+
Load( wf, entity );
}
Block::~Block()
-{
+{
if( mapped ) UnMap();
-
+
if( pts ) delete[] pts;
-
+ InvalidateModelPointCache();
+
g_ptr_array_free( rendered_cells, TRUE );
g_ptr_array_free( candidate_cells, TRUE );
}
@@ -69,7 +70,7 @@
pts[p].x += x;
pts[p].y += y;
}
-
+
mod->blockgroup.BuildDisplayList( mod );
}
@@ -77,13 +78,13 @@
{
double min = billion;
double max = -billion;
-
+
for( unsigned int p=0; p<pt_count; p++)
{
if( pts[p].y > max ) max = pts[p].y;
if( pts[p].y < min ) min = pts[p].y;
}
-
+
// return the value half way between max and min
return( min + (max - min)/2.0 );
}
@@ -92,13 +93,13 @@
{
double min = billion;
double max = -billion;
-
+
for( unsigned int p=0; p<pt_count; p++)
{
if( pts[p].x > max ) max = pts[p].x;
if( pts[p].x < min ) min = pts[p].x;
}
-
+
// return the value half way between maxx and min
return( min + (max - min)/2.0 );
}
@@ -145,21 +146,21 @@
for( unsigned int i=0; i<rendered_cells->len; i++ )
{
Cell* c = (Cell*)g_ptr_array_index( rendered_cells, i);
-
+
// for every block rendered into that cell
for( std::list<Block*>::iterator it = c->blocks.begin();
it != c->blocks.end();
- ++it )
+ ++it )
{
//Block* testblock = *it;
Model* testmod = (*it)->mod;
-
+
if( !mod->IsRelated( testmod ))
if( ! g_list_find( l, testmod ) )
l = g_list_append( l, testmod );
}
}
-
+
return l;
}
@@ -169,48 +170,48 @@
// find the set of cells we would render into given the current global pose
GenerateCandidateCells();
-
+
if( mod->vis.obstacle_return )
// for every cell we may be rendered into
for( unsigned int i=0; i<candidate_cells->len; i++ )
{
Cell* c = (Cell*)g_ptr_array_index(candidate_cells, i);
-
+
// for every rendered into that cell
for( std::list<Block*>::iterator it = c->blocks.begin();
it != c->blocks.end();
- ++it )
+ ++it )
{
Model* testmod = (*it)->mod;
-
+
//printf( " testing block %p of model %s\n",
testblock, testmod->Token() );
-
+
// if the tested model is an obstacle and it's
not attached to this model
- if( (testmod != this->mod) &&
- testmod->vis.obstacle_return &&
+ if( (testmod != this->mod) &&
+ testmod->vis.obstacle_return &&
!mod->IsRelated( testmod ))
{
//puts( "HIT");
return testmod; // bail immediately
with the bad news
- }
+ }
}
}
-
+
//printf( "model %s block %p collision done. no hits.\n", mod->Token(), this
);
return NULL; // no hit
}
void Block::RemoveFromCellArray( GPtrArray* ptrarray )
-{
- for( unsigned int i=0; i<ptrarray->len; i++ )
- ((Cell*)g_ptr_array_index(ptrarray, i))->RemoveBlock( this );
+{
+ for( unsigned int i=0; i<ptrarray->len; i++ )
+ ((Cell*)g_ptr_array_index(ptrarray, i))->RemoveBlock( this );
}
void Block::AddToCellArray( GPtrArray* ptrarray )
-{
- for( unsigned int i=0; i<ptrarray->len; i++ )
- ((Cell*)g_ptr_array_index(ptrarray, i))->AddBlock( this );
+{
+ for( unsigned int i=0; i<ptrarray->len; i++ )
+ ((Cell*)g_ptr_array_index(ptrarray, i))->AddBlock( this );
}
@@ -239,7 +240,7 @@
void Block::UnMap()
{
RemoveFromCellArray( rendered_cells );
-
+
g_ptr_array_set_size( rendered_cells, 0 );
mapped = false;
}
@@ -248,7 +249,7 @@
{
RemoveFromCellArray( rendered_cells );
AddToCellArray( candidate_cells );
-
+
// switch current and candidate cell pointers
GPtrArray* tmp = rendered_cells;
rendered_cells = candidate_cells;
@@ -261,7 +262,7 @@
{
Size bgsize = mod->blockgroup.GetSize();
stg_point3_t bgoffset = mod->blockgroup.GetOffset();
-
+
return stg_point_t( (bpt.x - bgoffset.x) * (mod->geom.size.x/bgsize.x),
(bpt.y - bgoffset.y) *
(mod->geom.size.y/bgsize.y));
}
@@ -272,11 +273,11 @@
{
// no valid cache of model coord points, so generate them
mpts = new stg_point_t[pt_count];
-
+
for( unsigned int i=0; i<pt_count; i++ )
mpts[i] = BlockPointToModelMeters( pts[i] );
}
-
+
return mpts;
}
@@ -284,7 +285,7 @@
{
// this doesn't happen often, so this simple strategy isn't too wasteful
if( mpts )
- {
+ {
delete[] mpts;
mpts = NULL;
}
@@ -293,7 +294,7 @@
void Block::GenerateCandidateCells()
{
stg_point_t* mpts = GetPointsInModelCoords();
-
+
// convert the mpts in model coords into global coords
stg_point_t* gpts = new stg_point_t[pt_count];
for( unsigned int i=0; i<pt_count; i++ )
@@ -312,11 +313,11 @@
gpose.z += mod->geom.pose.z;
double scalez = mod->geom.size.z / mod->blockgroup.GetSize().z;
stg_meters_t z = gpose.z - mod->blockgroup.GetOffset().z;
-
+
// store the block's absolute z bounds at this rendering
global_z.min = (scalez * local_z.min) + z;
- global_z.max = (scalez * local_z.max) + z;
-
+ global_z.max = (scalez * local_z.max) + z;
+
mapped = true;
}
@@ -327,9 +328,9 @@
b = tmp;
}
-void Block::Rasterize( uint8_t* data,
- unsigned int width,
- unsigned int height,
+void Block::Rasterize( uint8_t* data,
+ unsigned int width,
+ unsigned int height,
stg_meters_t
cellwidth,
stg_meters_t
cellheight )
{
@@ -341,38 +342,38 @@
// convert points from local to model coords
stg_point_t mpt1 = BlockPointToModelMeters( pts[i] );
stg_point_t mpt2 = BlockPointToModelMeters( pts[(i+1)%pt_count]
);
-
+
// record for debug visualization
mod->rastervis.AddPoint( mpt1.x, mpt1.y );
-
+
// shift to the bottom left of the model
mpt1.x += mod->geom.size.x/2.0;
mpt1.y += mod->geom.size.y/2.0;
mpt2.x += mod->geom.size.x/2.0;
mpt2.y += mod->geom.size.y/2.0;
-
+
// convert from meters to cells
stg_point_int_t a( floor( mpt1.x / cellwidth ),
floor( mpt1.y
/ cellheight ));
stg_point_int_t b( floor( mpt2.x / cellwidth ),
floor( mpt2.y
/ cellheight ) );
-
+
bool steep = abs( b.y-a.y ) > abs( b.x-a.x );
if( steep )
{
swap( a.x, a.y );
swap( b.x, b.y );
}
-
+
if( a.x > b.x )
{
swap( a.x, b.x );
swap( a.y, b.y );
}
-
+
double dydx = (double) (b.y - a.y) / (double) (b.x - a.x);
double y = a.y;
- for(int x=a.x; x<=b.x; x++)
+ for(int x=a.x; x<=b.x; x++)
{
if( steep )
{
@@ -388,9 +389,9 @@
if( ! (floor(y) >= 0) ) continue;
if( ! (floor(y) < (int)height) ) continue;
}
-
+
if( steep )
- data[ (int)floor(y) + (x * width)] = 1;
+ data[ (int)floor(y) + (x * width)] = 1;
else
data[ x + ((int)floor(y) * width)] = 1;
y += dydx;
@@ -406,11 +407,11 @@
for( unsigned int i=0; i<pt_count; i++ )
glVertex3f( pts[i].x, pts[i].y, local_z.max );
glEnd();
-}
+}
void Block::DrawSides()
{
- // construct a strip that wraps around the polygon
+ // construct a strip that wraps around the polygon
glBegin(GL_QUAD_STRIP);
for( unsigned int p=0; p<pt_count; p++)
{
@@ -433,28 +434,28 @@
void Block::Draw( Model* mod )
{
- // draw filled color polygons
- stg_color_t col = inherit_color ? mod->color : color;
-
+ // draw filled color polygons
+ stg_color_t col = inherit_color ? mod->color : color;
+
mod->PushColor( col );
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.0, 1.0);
DrawSides();
DrawTop();
glDisable(GL_POLYGON_OFFSET_FILL);
-
+
// // draw the block outline in a darker version of the same color
double r,g,b,a;
stg_color_unpack( col, &r, &g, &b, &a );
mod->PushColor( stg_color_pack( r/2.0, g/2.0, b/2.0, a ));
-
+
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glDepthMask(GL_FALSE);
DrawTop();
DrawSides();
glDepthMask(GL_TRUE);
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
-
+
mod->PopColor();
mod->PopColor();
}
@@ -472,27 +473,27 @@
void Block::Load( Worldfile* wf, int entity )
{
//printf( "Block::Load entity %d\n", entity );
-
+
if( pts )
delete[] pts;
-
+
pt_count = wf->ReadInt( entity, "points", 0);
pts = new stg_point_t[ pt_count ];
-
+
//printf( "reading %d points\n",
// pt_count );
-
- char key[128];
+
+ char key[128];
for( unsigned int p=0; p<pt_count; p++ ) {
snprintf(key, sizeof(key), "point[%d]", p );
-
+
pts[p].x = wf->ReadTupleLength(entity, key, 0, 0);
pts[p].y = wf->ReadTupleLength(entity, key, 1, 0);
}
-
+
local_z.min = wf->ReadTupleLength( entity, "z", 0, 0.0 );
local_z.max = wf->ReadTupleLength( entity, "z", 1, 1.0 );
-
+
const char* colorstr = wf->ReadString( entity, "color", NULL );
if( colorstr )
{
@@ -503,5 +504,5 @@
inherit_color = true;
}
-
-
+
+
Modified: code/stage/trunk/libstage/worldfile.cc
===================================================================
--- code/stage/trunk/libstage/worldfile.cc 2009-05-08 21:41:48 UTC (rev
7630)
+++ code/stage/trunk/libstage/worldfile.cc 2009-05-09 15:16:57 UTC (rev
7631)
@@ -68,11 +68,18 @@
// return g_str_hash( prop->key );
// }
+void destroy_property(gpointer value)
+{
+ CProperty * prop = reinterpret_cast<CProperty *> (value);
+ free(prop->key);
+ free(prop->values);
+ g_free(value);
+}
///////////////////////////////////////////////////////////////////////////
// Default constructor
-Worldfile::Worldfile()
+Worldfile::Worldfile()
{
this->filename = NULL;
@@ -96,7 +103,7 @@
this->unit_length = 1.0;
this->unit_angle = M_PI / 180;
- this->nametable = g_hash_table_new( g_str_hash, g_str_equal );
+ this->nametable = g_hash_table_new_full( g_str_hash, g_str_equal, NULL,
destroy_property );
}
@@ -157,13 +164,13 @@
{
// Shouldnt call load more than once,
// so this should be null.
-
+
if(this->filename == NULL)
{
this->filename = strdup(filename);
}
-
-
+
+
// Open the file
//FILE *file = fopen(this->filename, "r");
FILE *file = FileOpen(this->filename, "r");
@@ -173,23 +180,23 @@
this->filename, strerror(errno));
return false;
}
-
+
ClearTokens();
-
+
// Read tokens from the file
if (!LoadTokens(file, 0))
{
//DumpTokens();
return false;
}
-
+
// Parse the tokens to identify entities
if (!ParseTokens())
{
//DumpTokens();
return false;
}
-
+
// Dump contents and exit if this file is meant for debugging only.
if (ReadInt(0, "test", 0) != 0)
{
@@ -200,7 +207,7 @@
DumpProperties();
return false;
}
-
+
// Work out what the length units are
const char *unit = ReadString(0, "unit_length", "m");
if (strcmp(unit, "m") == 0)
@@ -209,14 +216,14 @@
this->unit_length = 0.01;
else if (strcmp(unit, "mm") == 0)
this->unit_length = 0.001;
-
+
// Work out what the angle units are
unit = ReadString(0, "unit_angle", "degrees");
if (strcmp(unit, "degrees") == 0)
this->unit_angle = M_PI / 180;
else if (strcmp(unit, "radians") == 0)
this->unit_angle = 1;
-
+
return true;
}
@@ -349,7 +356,7 @@
else if ( 0x0d == ch )
{
ch = fgetc(file);
- if ( 0x0a != ch )
+ if ( 0x0a != ch )
ungetc(ch, file);
line++;
AddToken(TokenEOL, "\n", include);
@@ -357,7 +364,7 @@
else if ( 0x0a == ch )
{
ch = fgetc(file);
- if ( 0x0d != ch )
+ if ( 0x0d != ch )
ungetc(ch, file);
line++;
AddToken(TokenEOL, "\n", include);
@@ -1335,7 +1342,7 @@
if( this->nametable )
g_hash_table_destroy( this->nametable );
- this->nametable = g_hash_table_new( g_str_hash, g_str_equal );
+ this->nametable = g_hash_table_new_full( g_str_hash, g_str_equal, NULL,
destroy_property );
}
@@ -1388,7 +1395,7 @@
///////////////////////////////////////////////////////////////////////////
-// Get an property
+// Get an property
CProperty* Worldfile::GetProperty(int entity, const char *name)
{
char key[128];
@@ -1431,7 +1438,7 @@
///////////////////////////////////////////////////////////////////////////
-// Get the value of an property
+// Get the value of an property
const char *Worldfile::GetPropertyValue(CProperty* property, int index)
{
assert(property);
@@ -1511,7 +1518,7 @@
WriteString(entity, name, "0" ); // compact zeros make the file
// more readable
else
- {
+ {
char default_str[64];
snprintf(default_str, sizeof(default_str), "%.3f", value);
WriteString(entity, name, default_str);
@@ -1545,12 +1552,12 @@
void Worldfile::WriteLength(int entity, const char *name, double value)
{
value /= this->unit_length;
-
+
if( fabs(value) < 0.001 ) // nearly 0
WriteString(entity, name, "0" ); // compact zeros make the file
// more readable
else
- {
+ {
char default_str[64];
snprintf(default_str, sizeof(default_str), "%.3f", value );
WriteString(entity, name, default_str);
@@ -1709,9 +1716,9 @@
int index, double value)
{
if( fabs(value) < 0.001 ) // nearly 0
- WriteTupleString(entity, name, index, "0" );
+ WriteTupleString(entity, name, index, "0" );
else
- {
+ {
char default_str[64];
snprintf(default_str, sizeof(default_str), "%.3f", value);
WriteTupleString(entity, name, index, default_str);
@@ -1737,11 +1744,11 @@
int index, double value)
{
value /= this->unit_length;
-
+
if( fabs(value) < 0.001 ) // nearly 0
- WriteTupleString(entity, name, index, "0" );
+ WriteTupleString(entity, name, index, "0" );
else
- {
+ {
char default_str[64];
snprintf(default_str, sizeof(default_str), "%.3f", value );
WriteTupleString(entity, name, index, default_str);
@@ -1766,11 +1773,11 @@
int index, double value)
{
value /= this->unit_angle;
-
+
if( fabs(value) < 0.001 ) // nearly 0
- WriteTupleString(entity, name, index, "0" );
+ WriteTupleString(entity, name, index, "0" );
else
- {
+ {
char default_str[64];
snprintf(default_str, sizeof(default_str), "%.3f", value );
WriteTupleString(entity, name, index, default_str);
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image
processing features enabled. http://p.sf.net/sfu/kodak-com
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit