Revision: 7606
http://playerstage.svn.sourceforge.net/playerstage/?rev=7606&view=rev
Author: rtv
Date: 2009-04-30 00:46:52 +0000 (Thu, 30 Apr 2009)
Log Message:
-----------
added callbacks to world that runat the end of an update cycle, after all model
callbacks have been called but before the clock is ticked
Modified Paths:
--------------
code/stage/trunk/libstage/model_callbacks.cc
code/stage/trunk/libstage/region.cc
code/stage/trunk/libstage/region.hh
code/stage/trunk/libstage/stage.hh
code/stage/trunk/libstage/world.cc
Modified: code/stage/trunk/libstage/model_callbacks.cc
===================================================================
--- code/stage/trunk/libstage/model_callbacks.cc 2009-04-23 01:44:18 UTC
(rev 7605)
+++ code/stage/trunk/libstage/model_callbacks.cc 2009-04-30 00:46:52 UTC
(rev 7606)
@@ -54,9 +54,8 @@
// store the new, shorter, list of callbacks
g_hash_table_insert( callbacks, member, cb_list );
- // we're done with that
- //free( el->data );
- // TODO - fix leak of stg_cb_t
+ // we're done with the stored data
+ delete (stg_cb_t*)(el->data);
}
else
{
Modified: code/stage/trunk/libstage/region.cc
===================================================================
--- code/stage/trunk/libstage/region.cc 2009-04-23 01:44:18 UTC (rev 7605)
+++ code/stage/trunk/libstage/region.cc 2009-04-30 00:46:52 UTC (rev 7606)
@@ -233,9 +233,7 @@
}
}
}
-
-
- glPopMatrix();
+ glPopMatrix();
}
@@ -247,3 +245,4 @@
glRecti( 0,0, 1<<SRBITS, 1<<SRBITS );
glPopMatrix();
}
+
Modified: code/stage/trunk/libstage/region.hh
===================================================================
--- code/stage/trunk/libstage/region.hh 2009-04-23 01:44:18 UTC (rev 7605)
+++ code/stage/trunk/libstage/region.hh 2009-04-30 00:46:52 UTC (rev 7606)
@@ -74,14 +74,37 @@
cells[i].region = this;
}
return( &cells[x + (y*Region::WIDTH)] );
+ }
- };
+ Cell* GetCellCreate( const stg_point_int_t& c )
+ {
+ if( ! cells )
+ {
+ cells = new Cell[REGIONSIZE];
+ for( unsigned int i=0; i<Region::SIZE; i++ )
+ cells[i].region = this;
+ }
+ return( &cells[c.x + (c.y*Region::WIDTH)] );
+ }
- Cell* GetCellNoCreate( int32_t x, int32_t y )
+ Cell* GetCellNoCreate( int32_t x, int32_t y ) const
{
return( &cells[x + (y*Region::WIDTH)] );
- };
+ }
+
+ Cell* GetCellNoCreate( const stg_point_int_t& c ) const
+ {
+ return( &cells[c.x + (c.y*Region::WIDTH)] );
+ }
+// Cell* GetCellNoCreateBoundsCheck( const stg_point_int_t& c ) const
+// {
+// if( c.x < 0 || c.x > WIDTH || c.y < 0 || c.y > WIDTH )
+// return NULL;
+// else
+// return( &cells[c.x + (c.y*Region::WIDTH)] );
+// }
+
void DecrementOccupancy();
void IncrementOccupancy();
};
Modified: code/stage/trunk/libstage/stage.hh
===================================================================
--- code/stage/trunk/libstage/stage.hh 2009-04-23 01:44:18 UTC (rev 7605)
+++ code/stage/trunk/libstage/stage.hh 2009-04-30 00:46:52 UTC (rev 7606)
@@ -41,6 +41,8 @@
#include <sys/time.h>
#include <iostream>
#include <vector>
+#include <list>
+//#include <pair>
// we use GLib's data structures extensively. Perhaps we'll move to
// C++ STL types to lose this dependency one day.
@@ -647,6 +649,7 @@
typedef int(*stg_model_callback_t)(Model* mod, void* user );
+ typedef int(*stg_world_callback_t)(World* world, void* user );
typedef int(*stg_cell_callback_t)(Cell* cell, void* user );
// return val, or minval if val < minval, or maxval if val > maxval
@@ -673,14 +676,18 @@
class stg_cb_t
{
public:
- stg_model_callback_t callback;
+ stg_model_callback_t callback;
void* arg;
stg_cb_t( stg_model_callback_t cb, void* arg )
: callback(cb), arg(arg) {}
+
+ stg_cb_t( stg_world_callback_t cb, void* arg )
+ : callback(NULL), arg(arg) {}
stg_cb_t() : callback(NULL), arg(NULL) {}
};
+
/** Defines a rectangle of [size] located at [pose] */
typedef struct
@@ -886,7 +893,8 @@
GCond* worker_threads_done; ///< signalled when there are no more updates
for the worker threads to do
protected:
-
+
+ std::list<std::pair<stg_world_callback_t,void*> > cb_list; ///< List
of callback functions and arguments
stg_bounds3d_t extent; ///< Describes the 3D volume of the world
bool graphics;///< true iff we have a GUI
stg_usec_t interval_sim; ///< temporal resolution: microseconds that
elapse between simulated time steps
@@ -904,11 +912,21 @@
long unsigned int updates; ///< the number of simulated time steps
executed so far
Worldfile* wf; ///< If set, points to the worldfile used to create this
world
+ void CallUpdateCallbacks(); ///< Call all calbacks in cb_list,
removing any that return true;
+
public:
static const int DEFAULT_PPM = 50; // default resolution in pixels per
meter
static const stg_msec_t DEFAULT_INTERVAL_SIM = 100; ///< duration of sim
timestep
+ /** Attach a callback function, to be called with the argument at
+ the end of a complete update step */
+ void AddUpdateCallback( stg_world_callback_t cb, void* user );
+
+ /** Remove a callback function. Any argument data passed to
+ AddUpdateCallback is not automatically freed. */
+ int RemoveUpdateCallback( stg_world_callback_t cb, void* user );
+
/** Log the state of a Model */
void Log( Model* mod );
@@ -1630,6 +1648,7 @@
int shutdown;
int startup;
int update;
+ int update_done;
};
/** Records model state and functionality in the GUI, if used */
Modified: code/stage/trunk/libstage/world.cc
===================================================================
--- code/stage/trunk/libstage/world.cc 2009-04-23 01:44:18 UTC (rev 7605)
+++ code/stage/trunk/libstage/world.cc 2009-04-30 00:46:52 UTC (rev 7606)
@@ -95,6 +95,7 @@
worker_threads_done( g_cond_new() ),
// protected
+ cb_list(NULL),
extent(),
graphics( false ),
interval_sim( (stg_usec_t)thousand * interval_sim ),
@@ -455,6 +456,54 @@
return str;
}
+void World::AddUpdateCallback( stg_world_callback_t cb,
+
void* user )
+{
+ // add the callback & argument to the list
+ std::pair<stg_world_callback_t,void*> p(cb, user);
+ cb_list.push_back( p );
+}
+
+int World::RemoveUpdateCallback( stg_world_callback_t cb,
+
void* user )
+{
+ std::pair<stg_world_callback_t,void*> p( cb, user );
+
+ std::list<std::pair<stg_world_callback_t,void*> >::iterator it;
+ for( it = cb_list.begin();
+ it != cb_list.end();
+ it++ )
+ {
+ if( (*it) == p )
+ {
+ cb_list.erase( it );
+ break;
+ }
+ }
+
+ // return the number of callbacks now in the list. Useful for
+ // detecting when the list is empty.
+ return cb_list.size();
+}
+
+void World::CallUpdateCallbacks()
+{
+
+ // for each callback in the list
+ for( std::list<std::pair<stg_world_callback_t,void*> >::iterator it =
cb_list.begin();
+ it != cb_list.end();
+ it++ )
+ {
+ //printf( "cbs %p data %p cvs->next %p\n", cbs, cbs->data,
cbs->next );
+
+ if( ((*it).first )( this, (*it).second ) )
+ {
+ //printf( "callback returned TRUE - schedule removal
from list\n" );
+ it = cb_list.erase( it );
+ }
+ }
+}
+
bool World::Update()
{
PRINT_DEBUG( "World::Update()" );
@@ -515,8 +564,11 @@
fflush( stdout );
}
+ this->updates++;
+
+ CallUpdateCallbacks();
+
this->sim_time += this->interval_sim;
- this->updates++;
return false;
@@ -1052,4 +1104,3 @@
//LogEntry::Print();
}
-
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Register Now & Save for Velocity, the Web Performance & Operations
Conference from O'Reilly Media. Velocity features a full day of
expert-led, hands-on workshops and two days of sessions from industry
leaders in dedicated Performance & Operations tracks. Use code vel09scf
and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit