Permalink
Browse files

* Hooks should save their arguments properl and also remove them when…

… hooks get removed.
  • Loading branch information...
1 parent 87ae4b3 commit e84cf84f1bb0ece7f54e543f190ef307be6e02f1 @bobbens committed May 1, 2011
Showing with 73 additions and 18 deletions.
  1. +1 −3 src/event.c
  2. +1 −0 src/event.h
  3. +50 −15 src/hook.c
  4. +18 −0 src/nlua_hook.c
  5. +1 −0 src/nlua_hook.h
  6. +2 −0 src/player.c
View
4 src/event.c
@@ -88,7 +88,6 @@ static int event_mactive = 0; /**< Allocated space for active events. */
* Prototypes.
*/
static unsigned int event_genID (void);
-static Event_t *event_get( unsigned int eventid );
static int event_parse( EventData_t *temp, const xmlNodePtr parent );
static void event_freeData( EventData_t *event );
static int event_create( int dataid, unsigned int *id );
@@ -100,7 +99,7 @@ static int events_parseActive( xmlNodePtr parent );
/**
* @brief Gets an event.
*/
-static Event_t *event_get( unsigned int eventid )
+Event_t *event_get( unsigned int eventid )
{
int i;
Event_t *ev;
@@ -141,7 +140,6 @@ int event_start( const char *name, unsigned int *id )
}
-
/**
* @brief Starts running a function, allows programmer to set up arguments.
*/
View
1 src/event.h
@@ -57,6 +57,7 @@ void events_trigger( EventTrigger_t trigger );
/*
* Handling.
*/
+Event_t *event_get( unsigned int eventid );
void event_remove( unsigned int eventid );
int event_save( unsigned int eventid );
const char *event_getData( unsigned int eventid );
View
65 src/hook.c
@@ -127,6 +127,7 @@ static int hook_loadingstack = 0; /**< Check if the hooks are being loaded. */
static int hooks_executeParam( const char* stack, HookParam *param );
static void hooks_updateDateExecute( ntime_t change );
/* intern */
+static void hook_rmRaw( Hook *h );
static void hooks_purgeList (void);
static Hook* hook_get( unsigned int id );
static unsigned int hook_genID (void);
@@ -142,6 +143,8 @@ static int hook_parse( xmlNodePtr base );
/* externed */
int hook_save( xmlTextWriterPtr writer );
int hook_load( xmlNodePtr parent );
+/* Misc. */
+static Mission *hook_getMission( Hook *hook );
/**
@@ -292,7 +295,6 @@ static int hook_parseParam( lua_State *L, HookParam *param )
*/
static int hook_runMisn( Hook *hook, HookParam *param, int claims )
{
- int i;
unsigned int id;
Mission* misn;
lua_State *L;
@@ -309,23 +311,20 @@ static int hook_runMisn( Hook *hook, HookParam *param, int claims )
}
/* Locate the mission */
- for (i=0; i<MISSION_MAX; i++)
- if (player_missions[i].id == hook->u.misn.parent)
- break;
- if (i>=MISSION_MAX) {
+ misn = hook_getMission( hook );
+ if (misn == NULL) {
WARN("Trying to run hook with parent not in player mission stack: deleting");
hook->delete = 1; /* so we delete it */
return -1;
}
- misn = &player_missions[i];
/* Make sure it's claimed. */
if ((claims > 0) && (claim_testSys(misn->claims, cur_system->id) != claims))
return 1;
/* Delete if only supposed to run once. */
if (hook->once)
- hook->delete = 1;
+ hook_rmRaw( hook );
/* Set up hook parameters. */
L = misn_runStart( misn, hook->u.misn.func );
@@ -355,7 +354,6 @@ static int hook_runMisn( Hook *hook, HookParam *param, int claims )
static int hook_runEvent( Hook *hook, HookParam *param, int claims )
{
int ret;
- unsigned int id;
lua_State *L;
int n;
@@ -365,10 +363,7 @@ static int hook_runEvent( Hook *hook, HookParam *param, int claims )
/* Delete if only supposed to run once. */
if (hook->once)
- hook->delete = 1;
-
- /* Simplicity. */
- id = hook->id;
+ hook_rmRaw( hook );
/* Set up hook parameters. */
L = event_runStart( hook->u.event.parent, hook->u.event.func );
@@ -381,14 +376,14 @@ static int hook_runEvent( Hook *hook, HookParam *param, int claims )
n = hook_parseParam( L, param );
/* Add hook parameters. */
- hookL_getarg( L, id );
+ hookL_getarg( L, hook->id );
n++;
/* Run the hook. */
ret = event_runFunc( hook->u.event.parent, hook->u.event.func, n );
hook->ran_once = 1;
if (ret < 0) {
- hook_rm( id );
+ hook_rmRaw( hook );
WARN("Hook [%s] '%d' -> '%s' failed", hook->stack,
hook->id, hook->u.event.func);
return -1;
@@ -792,7 +787,7 @@ void hooks_update( double dt )
/* Run the timer hook. */
hook_run( h, NULL, j );
- h->delete = 1; /* Mark for deletion. */
+ hook_rmRaw( h );
}
}
hook_runningstack--; /* not running hooks anymore */
@@ -827,6 +822,19 @@ unsigned hook_addFunc( int (*func)(void*), void* data, const char *stack )
/**
+ * @brief Gets the mission of a hook.
+ */
+static Mission *hook_getMission( Hook *hook )
+{
+ int i;
+ for (i=0; i<MISSION_MAX; i++)
+ if (player_missions[i].id == hook->u.misn.parent)
+ return &player_missions[i];
+ return NULL;
+}
+
+
+/**
* @brief Removes a hook.
*
* @param id Identifier of the hook to remove.
@@ -838,7 +846,34 @@ void hook_rm( unsigned int id )
h = hook_get( id );
if (h==NULL)
return;
+ hook_rmRaw( h );
+}
+
+
+/**
+ * @brief Removes a hook.
+ */
+static void hook_rmRaw( Hook *h )
+{
+ Mission *misn;
+ Event_t *evt;
h->delete = 1;
+ switch (h->type) {
+ case HOOK_TYPE_MISN:
+ misn = hook_getMission( h );
+ if (misn != NULL)
+ hookL_unsetarg( misn->L, h->id );
+ break;
+
+ case HOOK_TYPE_EVENT:
+ evt = event_get( h->u.event.parent );
+ if (evt != NULL)
+ hookL_unsetarg( evt->L, h->id );
+ break;
+
+ default:
+ break;
+ }
}
View
18 src/nlua_hook.c
@@ -164,6 +164,8 @@ static int hookL_setarg( lua_State *L, unsigned int hook, int ind )
lua_newtable( L ); /* v, t */
lua_pushvalue( L, -1 ); /* v, t, t */
lua_setglobal( L, "__hook_arg" ); /* v, t */
+ lua_pushboolean( L, 1 ); /* v, t, s */
+ lua_setfield( L, -2, "__save" ); /* v, t */
}
lua_pushnumber( L, hook ); /* v, t, k */
lua_pushvalue( L, -3 ); /* v, t, k, v */
@@ -174,6 +176,22 @@ static int hookL_setarg( lua_State *L, unsigned int hook, int ind )
/**
+ * @brief Unsets a lua argument.
+ */
+void hookL_unsetarg( lua_State *L, unsigned int hook )
+{
+ lua_getglobal( L, "__hook_arg" ); /* t */
+ if (lua_isnil(L,-1)) { /* */
+ lua_pop(L,1);
+ }
+ lua_pushnumber( L, hook ); /* t, h */
+ lua_pushnil( L ); /* t, h, n */
+ lua_settable( L, -3 ); /* t */
+ lua_pop( L, 1 );
+}
+
+
+/**
* @brief Gets a Lua argument for a hook.
*
* @param L Lua state to put argument in.
View
1 src/nlua_hook.h
@@ -15,6 +15,7 @@ int nlua_loadHook( lua_State *L );
/* Misc. */
int hookL_getarg( lua_State *L, unsigned int hook );
+void hookL_unsetarg( lua_State *L, unsigned int hook );
#endif /* NLUA_HOOK */
View
2 src/player.c
@@ -3655,3 +3655,5 @@ static int player_parseShip( xmlNodePtr parent, int is_player, char *planet )
return 0;
}
+
+

0 comments on commit e84cf84

Please sign in to comment.