Added a GIB event system for registering GIB callback functions to be

started when a named event occurs.  Added a few test events to the qw
client and server.  Cleaned up the range GIB builtin a bit.
This commit is contained in:
Brian Koropoff 2003-01-03 04:30:38 +00:00
parent 79a638198d
commit c522970a88
8 changed files with 104 additions and 74 deletions

View file

@ -29,15 +29,30 @@
$Id$
*/
#ifndef __gib_thread_h
#define __gib_thread_h
#include "QF/gib_function.h"
typedef struct gib_thread_s {
unsigned long int id;
struct cbuf_s *cbuf;
struct gib_thread_s *next,*prev;
} gib_thread_t;
typedef struct gib_event_s {
const char *name;
struct gib_function_s *func;
} gib_event_t;
void GIB_Thread_Add (gib_thread_t *thread);
void GIB_Thread_Remove (gib_thread_t *thread);
gib_thread_t *GIB_Thread_Find (unsigned long int id);
gib_thread_t *GIB_Thread_New (void);
void GIB_Thread_Execute (void);
void GIB_Thread_Callback (const char *func, unsigned int argc, ...);
gib_event_t *GIB_Event_New (const char *name);
int GIB_Event_Register (const char *name, gib_function_t *func);
void GIB_Event_Callback (gib_event_t *event, unsigned int argc, ...);
void GIB_Event_Init (void);
#endif

View file

@ -610,6 +610,18 @@ GIB_Thread_Kill_f (void)
}
}
void
GIB_Event_Register_f (void)
{
gib_function_t *func;
if (GIB_Argc() != 3)
GIB_USAGE ("event function");
else if (!(func = GIB_Function_Find (GIB_Argv(2))) && GIB_Argv(2)[0])
Cbuf_Error ("function", "Function %s not found.", GIB_Argv(2));
else if (GIB_Event_Register (GIB_Argv(1), func))
Cbuf_Error ("event", "Event %s not found.", GIB_Argv(1));
}
/* File access */
int (*GIB_File_Transform_Path) (dstring_t *path) = NULL;
@ -819,24 +831,19 @@ GIB_Range_f (void)
GIB_USAGE ("lower upper [step]");
return;
}
if (!(dstr = GIB_Return (0)))
return; // Why bother?
limit = atof(GIB_Argv(2));
start = atof(GIB_Argv(1));
if (GIB_Argc () == 4)
inc = atof(GIB_Argv(3));
if (GIB_Argc () == 4 && (inc = atof(GIB_Argv(3))) == 0.0)
return;
else
inc = limit < start ? -1.0 : 1.0;
if (inc == 0.0) {
GIB_Return ("");
return;
}
if (!(ifs = GIB_Var_Get_Local (cbuf_active, "ifs")))
ifs = " ";
dstr = dstring_newstr ();
for (i = atof(GIB_Argv(1)); inc < 0 ? i >= limit : i <= limit; i += inc)
dasprintf(dstr, "%.1s%.10g", ifs, i);
GIB_Return (dstr->str[0] ? dstr->str+1 : "");
dstring_delete (dstr);
dasprintf(dstr, "%.10g%.1s", i, ifs);
dstr->str[dstr->size-2] = 0;
}
void
@ -882,6 +889,7 @@ GIB_Builtin_Init (qboolean sandbox)
GIB_Builtin_Add ("regex::extract", GIB_Regex_Extract_f, GIB_BUILTIN_NORMAL);
GIB_Builtin_Add ("thread::create", GIB_Thread_Create_f, GIB_BUILTIN_NORMAL);
GIB_Builtin_Add ("thread::kill", GIB_Thread_Kill_f, GIB_BUILTIN_NORMAL);
GIB_Builtin_Add ("event::register", GIB_Event_Register_f, GIB_BUILTIN_NORMAL);
GIB_Builtin_Add ("file::read", GIB_File_Read_f, GIB_BUILTIN_NORMAL);
GIB_Builtin_Add ("file::write", GIB_File_Write_f, GIB_BUILTIN_NORMAL);
GIB_Builtin_Add ("file::find", GIB_File_Find_f, GIB_BUILTIN_NORMAL);

View file

@ -38,6 +38,7 @@ static const char rcsid[] =
#include "QF/gib_parse.h"
#include "QF/gib_builtin.h"
#include "QF/gib_regex.h"
#include "QF/gib_thread.h"
#include "QF/cmd.h"
#include "QF/sys.h"
#include "QF/zone.h"
@ -88,4 +89,6 @@ GIB_Init (qboolean sandbox)
GIB_Regex_Init ();
// Initialize builtins
GIB_Builtin_Init (sandbox);
// Initialize event system
GIB_Event_Init ();
}

View file

@ -33,6 +33,7 @@ static const char rcsid[] =
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "QF/sys.h"
#include "QF/cbuf.h"
@ -40,8 +41,10 @@ static const char rcsid[] =
#include "QF/gib_thread.h"
#include "QF/gib_function.h"
#include "QF/dstring.h"
#include "QF/hash.h"
gib_thread_t *gib_threads;
hashtab_t *gib_events;
static unsigned long int nextid = 0;
void
@ -114,10 +117,45 @@ GIB_Thread_Execute (void)
}
}
void
GIB_Thread_Callback (const char *func, unsigned int argc, ...)
const char *
GIB_Event_Get_Key (void *ele, void *ptr)
{
gib_function_t *f = GIB_Function_Find (func);
return ((gib_event_t *)ele)->name;
}
void
GIB_Event_Free (void *ele, void *ptr)
{
gib_event_t *ev = (gib_event_t *)ele;
free ((void *)ev->name);
free (ev);
}
gib_event_t *
GIB_Event_New (const char *name)
{
gib_event_t *new;
new = calloc (1, sizeof (gib_event_t));
new->name = strdup (name);
Hash_Add (gib_events, new);
return new;
}
int
GIB_Event_Register (const char *name, gib_function_t *func)
{
gib_event_t *ev;
if (!(ev = Hash_Find (gib_events, name)))
return -1;
ev->func = func;
return 0;
}
void
GIB_Event_Callback (gib_event_t *event, unsigned int argc, ...)
{
gib_function_t *f = event->func;
gib_thread_t *thread;
cbuf_args_t *args;
va_list ap;
@ -131,7 +169,7 @@ GIB_Thread_Callback (const char *func, unsigned int argc, ...)
va_start (ap, argc);
Cbuf_ArgsAdd (args, func);
Cbuf_ArgsAdd (args, f->name->str);
for (i = 0; i < argc; i++)
Cbuf_ArgsAdd (args, va_arg (ap, const char *));
@ -141,3 +179,9 @@ GIB_Thread_Callback (const char *func, unsigned int argc, ...)
GIB_Thread_Add (thread);
Cbuf_ArgsDelete (args);
}
void
GIB_Event_Init (void)
{
gib_events = Hash_NewTable (1024, GIB_Event_Get_Key, GIB_Event_Free, 0);
}

View file

@ -56,4 +56,6 @@ extern struct cvar_s *cl_cshift_contents;
extern struct cvar_s *cl_cshift_damage;
extern struct cvar_s *cl_cshift_powerup;
extern struct gib_event_s *cl_player_health_e, *cl_chat_e;
#endif // _CL_MAIN_H

View file

@ -180,6 +180,9 @@ cvar_t *rate;
cvar_t *noaim;
cvar_t *msg;
/* GIB events */
gib_event_t *cl_player_health_e, *cl_chat_e;
static int cl_usleep_cache;
client_static_t cls;
@ -1224,6 +1227,8 @@ CL_Init (void)
"to people on your team");
Cmd_AddCommand ("serverinfo", CL_Cmd_ForwardToServer, "Report the current "
"server info");
cl_player_health_e = GIB_Event_New ("player.health");
cl_chat_e = GIB_Event_New ("chat");
}
static void

View file

@ -1095,10 +1095,6 @@ CL_ServerInfo (void)
void
CL_SetStat (int stat, int value)
{
int j;
unsigned int changed;
const char *arm, *cb;
if (stat < 0 || stat >= MAX_CL_STATS)
Host_Error ("CL_SetStat: %i is invalid", stat);
@ -1112,67 +1108,15 @@ CL_SetStat (int stat, int value)
switch (stat) {
case STAT_ITEMS:
changed = cl.stats[STAT_ITEMS] ^ value;
Sbar_Changed ();
if ((changed & IT_KEY1 || changed & IT_KEY2) &&
(cb = GIB_Var_Get_Global ("player.key.callback")))
GIB_Thread_Callback (cb, 0);
GIB_Var_Set_Global ("player.key.1", value & IT_KEY1 ? "1" : "0");
GIB_Var_Set_Global ("player.key.2", value & IT_KEY2 ? "1" : "0");
if (value & IT_ARMOR1)
arm = "green";
else if (value & IT_ARMOR2)
arm = "yellow";
else if (value & IT_ARMOR3)
arm = "red";
else
arm = "none";
GIB_Var_Set_Global ("player.armor.type", arm);
if ((changed & 127 || changed & IT_AXE) &&
(cb = GIB_Var_Get_Global ("player.weapon.callback")))
GIB_Thread_Callback (cb, 0);
GIB_Var_Set_Global ("player.weapon.1", value & IT_AXE ? "1" : "0");
for (j = 0; j < 7; j++)
GIB_Var_Set_Global (va("player.weapon.%i", j+2),
value & (1 << j) ? "1" : "0");
for (j = 0; j < 32; j++)
if ((value & (1 << j)) && !(cl.stats[stat] & (1 << j)))
cl.item_gettime[j] = cl.time;
break;
case STAT_HEALTH:
if ((cb = GIB_Var_Get_Global ("player.health.callback")))
GIB_Thread_Callback (cb, 1, va("%i", value));
GIB_Var_Set_Global ("player.health", va("%i", value));
if (cl_player_health_e->func)
GIB_Event_Callback (cl_player_health_e, 1, va("%i", value));
if (value <= 0)
Team_Dead ();
break;
case STAT_ARMOR:
if ((cb = GIB_Var_Get_Global ("player.armor.callback")))
GIB_Thread_Callback (cb, 1, va("%i", value));
GIB_Var_Set_Global ("player.armor", va("%i", value));
break;
case STAT_SHELLS:
if ((cb = GIB_Var_Get_Global ("player.ammo.shells.callback")))
GIB_Thread_Callback (cb, 1, va("%i", value));
GIB_Var_Set_Global ("player.ammo.shells", va("%i", value));
break;
case STAT_NAILS:
if ((cb = GIB_Var_Get_Global ("player.ammo.nails.callback")))
GIB_Thread_Callback (cb, 1, va("%i", value));
GIB_Var_Set_Global ("player.ammo.nails", va("%i", value));
break;
case STAT_ROCKETS:
if ((cb = GIB_Var_Get_Global ("player.ammo.rockets.callback")))
GIB_Thread_Callback (cb, 1, va("%i", value));
GIB_Var_Set_Global ("player.ammo.rockets", va("%i", value));
break;
case STAT_CELLS:
if ((cb = GIB_Var_Get_Global ("player.ammo.cells.callback")))
GIB_Thread_Callback (cb, 1, va("%i", value));
GIB_Var_Set_Global ("player.ammo.cells", va("%i", value));
break;
}
cl.stats[stat] = value;
}
@ -1290,6 +1234,8 @@ CL_ParseServerMessage (void)
}
Con_SetOrMask (128);
S_LocalSound ("misc/talk.wav");
if (cl_chat_e->func)
GIB_Event_Callback (cl_chat_e, 1, s);
Team_ParseChat(s);
}
Con_Printf ("%s", s);

View file

@ -54,6 +54,7 @@ static const char rcsid[] =
#include "QF/quakefs.h"
#include "QF/sys.h"
#include "QF/va.h"
#include "QF/gib_thread.h"
#include "bothdefs.h"
#include "compat.h"
@ -92,6 +93,8 @@ cvar_t *sv_timekick_interval;
cvar_t *sv_timecheck_fuzz;
cvar_t *sv_timecheck_decay;
gib_event_t *sv_chat_e;
// USER STRINGCMD EXECUTION host_client and sv_player will be valid.
/*
@ -823,6 +826,9 @@ SV_Say (qboolean team)
SV_Printf ("%s", text);
if (sv_chat_e->func)
GIB_Event_Callback (sv_chat_e, 1, text);
for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++) {
if (client->state < cs_connected) // Clients connecting can hear.
continue;
@ -1847,4 +1853,5 @@ SV_UserInit (void)
"\"forgiven\".");
sv_kickfake = Cvar_Get ("sv_kickfake", "1", CVAR_NONE, NULL,
"Kick users sending to send fake talk messages");
sv_chat_e = GIB_Event_New ("chat");
}