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

Reply via email to