Update of /cvsroot/playerstage/code/stage/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13269/src

Added Files:
      Tag: opengl
        model_callbacks.c 
Log Message:
added missing file

--- NEW FILE: model_callbacks.c ---
#include "stage_internal.h"

void stg_model_add_callback( stg_model_t* mod, 
                             void* address, 
                             stg_model_callback_t cb, 
                             void* user )
{
  int* key = malloc(sizeof(int));
  *key = address - (void*)mod;

  GList* cb_list = g_hash_table_lookup( mod->callbacks, key );

  //printf( "installing callback in model %s with key %d\n",
  //  mod->token, *key );
  
  // add the callback & argument to the list
  cb_list = g_list_prepend( cb_list, cb_create( cb, user ) );
  
  // and replace the list in the hash table
  g_hash_table_insert( mod->callbacks, key, cb_list );

  // if the callback was an update function, add this model to the
  // world's list of models that need updating (if it's not there
  // already)
  if( address == (void*)&mod->update )
    stg_world_start_updating_model( mod->world, mod );
}


int stg_model_remove_callback( stg_model_t* mod,
                               void* member,
                               stg_model_callback_t callback )
{
  int key = member - (void*)mod;

  GList* cb_list = g_hash_table_lookup( mod->callbacks, &key );
 
  // find our callback in the list of stg_cbarg_t
  GList* el = NULL;
  
  // scan the list for the first matching callback
  for( el = g_list_first( cb_list );
       el;
       el = el->next )
    {
      if( ((stg_cb_t*)el->data)->callback == callback )
        break;
    }

  if( el ) // if we found the matching callback, remove it
    {
      //puts( "removed callback" );

      cb_list = g_list_remove( cb_list, el->data);
      
      // store the new, shorter, list of callbacks
      g_hash_table_insert( mod->callbacks, &key, cb_list );

      // we're done with that
      //free( el->data );
      // TODO - fix leak of cb_t

      // if we just removed a model's last update callback,
      // remove this model from the world's update list
      if( (member == (void*)&mod->update) && (cb_list == NULL) )
        stg_world_stop_updating_model( mod->world, mod );
    }
  else
    {
      //puts( "callback was not installed" );
    }
 
  return 0; //ok
}


void model_call_callbacks( stg_model_t* mod, void* address )
{
  assert( mod );
  assert( address );
  assert( address > (void*)mod );
  assert( address < (void*)( mod + sizeof(stg_model_t)));
  
  int key = address - (void*)mod;
  
  //printf( "Model %s has %d callbacks. Checking key %d\n", 
  //  mod->token, g_hash_table_size( mod->callbacks ), key );
  
  GList* cbs = g_hash_table_lookup( mod->callbacks, &key ); 
  
  //printf( "key %d has %d callbacks registered\n",
  //  key, g_list_length( cbs ) );
  
  // maintain a list of callbacks that should be cancelled
  GList* doomed = NULL;

  // for each callback in the list
  while( cbs )
    {  
      stg_cb_t* cba = (stg_cb_t*)cbs->data;
      
      //puts( "calling..." );
      
      if( (cba->callback)( mod, cba->arg ) )
        {
          //printf( "callback returned TRUE - schedule removal from list\n" );
          doomed = g_list_prepend( doomed, cba->callback );
        }
      else
        {
          //printf( "callback returned FALSE - keep in list\n" );
        }
      
      cbs = cbs->next;
    }      

  if( doomed )  // delete all the callbacks that returned TRUE    
    {
      //printf( "removing %d doomed callbacks\n", g_list_length( doomed ) );
      
      for( ; doomed ; doomed = doomed->next )
        stg_model_remove_callback( mod, address, 
(stg_model_callback_t)doomed->data );
      
      g_list_free( doomed );      
    }

}


/* wrappers for the generic callback add & remove functions that hide
   some implementation detail */

void stg_model_add_update_callback( stg_model_t* mod, 
                                    stg_model_callback_t cb, 
                                    void* user )
{
  stg_model_add_callback( mod, &mod->update, cb, user );
}

void stg_model_remove_update_callback( stg_model_t* mod, 
                                       stg_model_callback_t cb )
{
  stg_model_remove_callback( mod, &mod->update, cb );
}

void stg_model_add_load_callback( stg_model_t* mod, 
                                    stg_model_callback_t cb, 
                                    void* user )
{
  stg_model_add_callback( mod, &mod->load, cb, user );
}

void stg_model_remove_load_callback( stg_model_t* mod, 
                                       stg_model_callback_t cb )
{
  stg_model_remove_callback( mod, &mod->load, cb );
}

void stg_model_add_save_callback( stg_model_t* mod, 
                                    stg_model_callback_t cb, 
                                    void* user )
{
  stg_model_add_callback( mod, &mod->save, cb, user );
}

void stg_model_remove_save_callback( stg_model_t* mod, 
                                       stg_model_callback_t cb )
{
  stg_model_remove_callback( mod, &mod->save, cb );
}

void stg_model_add_startup_callback( stg_model_t* mod, 
                                    stg_model_callback_t cb, 
                                    void* user )
{
  stg_model_add_callback( mod, &mod->startup, cb, user );
}

void stg_model_remove_startup_callback( stg_model_t* mod, 
                                       stg_model_callback_t cb )
{
  stg_model_remove_callback( mod, &mod->startup, cb );
}

void stg_model_add_shutdown_callback( stg_model_t* mod, 
                                    stg_model_callback_t cb, 
                                    void* user )
{
  stg_model_add_callback( mod, &mod->shutdown, cb, user );
}

void stg_model_remove_shutdown_callback( stg_model_t* mod, 
                                       stg_model_callback_t cb )
{
  stg_model_remove_callback( mod, &mod->shutdown, cb );
}



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to