From 3b703db4d4983a615f3d5c26efbcb72337c701a7 Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Sun, 13 Apr 2003 20:43:52 +0000 Subject: [PATCH] Added the beginnings of an interface between Ruamoko and GIB. Although the API is by no means finalized, it's now possible to write GIB builtins in Ruamoko that can take arguments and return values to GIB. --- include/QF/csqc.h | 2 + include/QF/gib_builtin.h | 6 +- libs/console/menu.c | 1 + libs/gamecode/builtins/Makefile.am | 2 +- libs/gamecode/builtins/bi_gib.c | 157 +++++++++++++++++++++++++++++ libs/gamecode/builtins/bi_init.c | 1 + libs/gib/gib_builtin.c | 27 ++++- ruamoko/cl_menu/client_menu.qc | 13 +++ ruamoko/include/Makefile.am | 2 +- ruamoko/include/gib.h | 7 ++ ruamoko/lib/Makefile.am | 2 +- ruamoko/lib/gib.r | 4 + 12 files changed, 214 insertions(+), 10 deletions(-) create mode 100644 libs/gamecode/builtins/bi_gib.c create mode 100644 ruamoko/include/gib.h create mode 100644 ruamoko/lib/gib.r diff --git a/include/QF/csqc.h b/include/QF/csqc.h index d098de476..0b0898707 100644 --- a/include/QF/csqc.h +++ b/include/QF/csqc.h @@ -49,6 +49,8 @@ void File_Progs_Init (struct progs_s *pr); void Hash_Progs_Init (struct progs_s *pr); +void GIB_Progs_Init (struct progs_s *pr); + void InputLine_Progs_Init (struct progs_s *pr); void InputLine_Progs_SetDraw (struct progs_s *pr, void (*draw)(struct inputline_s*)); diff --git a/include/QF/gib_builtin.h b/include/QF/gib_builtin.h index f1649776a..458d64eb2 100644 --- a/include/QF/gib_builtin.h +++ b/include/QF/gib_builtin.h @@ -34,7 +34,7 @@ #include "QF/dstring.h" // For ->str typedef struct gib_builtin_s { - struct dstring_s *name; + const char *name; void (*func) (void); } gib_builtin_t; @@ -53,6 +53,8 @@ extern char gib_null_string[]; void GIB_Arg_Strip_Delim (unsigned int arg); dstring_t *GIB_Return (const char *str); void GIB_Error (const char *type, const char *fmt, ...); -void GIB_Builtin_Add (const char *name, void (*func) (void)); +gib_builtin_t *GIB_Builtin_Add (const char *name, void (*func) (void)); +void GIB_Builtin_Remove (const char *name); +qboolean GIB_Builtin_Exists (const char *name); gib_builtin_t *GIB_Builtin_Find (const char *name); void GIB_Builtin_Init (qboolean sandbox); diff --git a/libs/console/menu.c b/libs/console/menu.c index c3c74ea45..bb664902a 100644 --- a/libs/console/menu.c +++ b/libs/console/menu.c @@ -444,6 +444,7 @@ Menu_Init (void) Cbuf_Progs_Init (&menu_pr_state); Cmd_Progs_Init (&menu_pr_state); + GIB_Progs_Init (&menu_pr_state); Cvar_Progs_Init (&menu_pr_state); File_Progs_Init (&menu_pr_state); InputLine_Progs_Init (&menu_pr_state); diff --git a/libs/gamecode/builtins/Makefile.am b/libs/gamecode/builtins/Makefile.am index 534f43b08..25f1fb807 100644 --- a/libs/gamecode/builtins/Makefile.am +++ b/libs/gamecode/builtins/Makefile.am @@ -10,6 +10,6 @@ libQFgamecode_builtins_la_SOURCES= pr_cmds.c libQFcsqc_la_LDFLAGS= -version-info 1:0:0 libQFcsqc_la_SOURCES=\ - bi_cbuf.c bi_cmd.c bi_cvar.c bi_file.c bi_hash.c bi_init.c \ + bi_cbuf.c bi_cmd.c bi_cvar.c bi_file.c bi_gib.c bi_hash.c bi_init.c \ bi_inputline.c bi_plist.c \ bi_qfile.c bi_qfs.c diff --git a/libs/gamecode/builtins/bi_gib.c b/libs/gamecode/builtins/bi_gib.c new file mode 100644 index 000000000..0e5a7e72f --- /dev/null +++ b/libs/gamecode/builtins/bi_gib.c @@ -0,0 +1,157 @@ +/* + bi_gib.c + + GIB <-> Ruamoko interface + + Copyright (C) 2003 Brian Koropoff + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +static __attribute__ ((unused)) const char rcsid[] = + "$Id$"; + +#include +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + +#include "QF/cmd.h" +#include "QF/csqc.h" +#include "QF/hash.h" +#include "QF/progs.h" +#include "QF/sys.h" +#include "QF/gib_builtin.h" + +typedef struct bi_gib_builtin_s { + struct bi_gib_builtin_s *next; + gib_builtin_t *builtin; + progs_t *pr; + func_t func; +} bi_gib_builtin_t; + +typedef struct bi_gib_resources_s { + bi_gib_builtin_t *builtins; +} bi_gib_resources_t; + +static hashtab_t *bi_gib_builtins; + +static const char * +bi_gib_builtin_get_key (void *c, void *unused) +{ + return ((bi_gib_builtin_t *)c)->builtin->name; +} + +static void +bi_gib_builtin_free (void *_c, void *unused) +{ + bi_gib_builtin_t *c = (bi_gib_builtin_t *) _c; + + free (c); +} + +static void +bi_gib_builtin_f (void) +{ + bi_gib_builtin_t *builtin = Hash_Find (bi_gib_builtins, GIB_Argv(0)); + pr_type_t *pr_list; + unsigned int i; + + if (!builtin) + Sys_Error ("bi_gib_bultin_f: unexpected call %s", GIB_Argv (0)); + + pr_list = PR_Zone_Malloc (builtin->pr, GIB_Argc() * sizeof (pr_type_t)); + + for (i = 0; i < GIB_Argc(); i++) + pr_list[i].integer_var = PR_SetString (builtin->pr, GIB_Argv(i)); + + P_INT (builtin->pr, 0) = GIB_Argc(); + P_INT (builtin->pr, 1) = POINTER_TO_PROG (builtin->pr, pr_list); + PR_ExecuteProgram (builtin->pr, builtin->func); +} + +static void +bi_gib_builtin_clear (progs_t *progs, void *data) +{ + bi_gib_resources_t *res = (bi_gib_resources_t *) data; + bi_gib_builtin_t *cur; + + while ((cur = res->builtins)) { + void *del = Hash_Del (bi_gib_builtins, cur->builtin->name); + GIB_Builtin_Remove (cur->builtin->name); + res->builtins = cur->next; + Hash_Free (bi_gib_builtins, del); + } +} + +static void +bi_GIB_Builtin_Add (progs_t *pr) +{ + bi_gib_resources_t *res = PR_Resources_Find (pr, "GIB"); + bi_gib_builtin_t *builtin; + char *name = P_STRING (pr, 0); + func_t func = P_FUNCTION (pr, 1); + + if (GIB_Builtin_Exists (name)) { + R_INT (pr) = 0; + return; + } + + builtin = malloc (sizeof (bi_gib_builtin_t)); + + builtin->builtin = GIB_Builtin_Add (name, bi_gib_builtin_f); + builtin->pr = pr; + builtin->func = func; + builtin->next = res->builtins; + res->builtins = builtin; + Hash_Add (bi_gib_builtins, builtin); + R_INT (pr) = 1; +} + +static void +bi_GIB_Return (progs_t *pr) +{ + char *str = P_STRING(pr, 0); + + if (str) + GIB_Return (str); + R_INT (pr) = GIB_CanReturn () ? 1 : 0; +} + +void +GIB_Progs_Init (progs_t *pr) +{ + bi_gib_resources_t *res = malloc (sizeof (bi_gib_resources_t)); + res->builtins = 0; + + PR_Resources_Register (pr, "GIB", res, bi_gib_builtin_clear); + + bi_gib_builtins = Hash_NewTable (1021, bi_gib_builtin_get_key, bi_gib_builtin_free, 0); + + PR_AddBuiltin (pr, "GIB_Builtin_Add", bi_GIB_Builtin_Add, -1); + PR_AddBuiltin (pr, "GIB_Return", bi_GIB_Return, -1); +} diff --git a/libs/gamecode/builtins/bi_init.c b/libs/gamecode/builtins/bi_init.c index eecd43e24..3812ab643 100644 --- a/libs/gamecode/builtins/bi_init.c +++ b/libs/gamecode/builtins/bi_init.c @@ -36,6 +36,7 @@ static __attribute__ ((unused)) const char rcsid[] = static void (*const cbuf_progs_init)(progs_t *) = Cbuf_Progs_Init; static void (*const cmd_progs_init)(progs_t *) = Cmd_Progs_Init; +static void (*const gib_progs_init)(progs_t *) = GIB_Progs_Init; static void (*const cvar_progs_init)(progs_t *) = Cvar_Progs_Init; static void (*const file_progs_init)(progs_t *) = File_Progs_Init; static void (*const hash_progs_init)(progs_t *) = Hash_Progs_Init; diff --git a/libs/gib/gib_builtin.c b/libs/gib/gib_builtin.c index 689e3beb9..552698eaa 100644 --- a/libs/gib/gib_builtin.c +++ b/libs/gib/gib_builtin.c @@ -74,7 +74,7 @@ hashtab_t *gib_builtins; static const char * GIB_Builtin_Get_Key (void *ele, void *ptr) { - return ((gib_builtin_t *) ele)->name->str; + return ((gib_builtin_t *) ele)->name; } static void GIB_Builtin_Free (void *ele, void *ptr) @@ -82,7 +82,7 @@ GIB_Builtin_Free (void *ele, void *ptr) gib_builtin_t *b; b = (gib_builtin_t *) ele; - dstring_delete (b->name); + free ((void *)b->name); free (b); } @@ -91,7 +91,8 @@ GIB_Builtin_Free (void *ele, void *ptr) Registers a new builtin GIB command. */ -void + +gib_builtin_t * GIB_Builtin_Add (const char *name, void (*func) (void)) { gib_builtin_t *new; @@ -102,9 +103,25 @@ GIB_Builtin_Add (const char *name, void (*func) (void)) new = calloc (1, sizeof (gib_builtin_t)); new->func = func; - new->name = dstring_newstr (); - dstring_appendstr (new->name, name); + new->name = strdup (name); Hash_Add (gib_builtins, new); + + return new; +} + +void +GIB_Builtin_Remove (const char *name) +{ + gib_builtin_t *del; + + if ((del = Hash_Find (gib_builtins, name))) + Hash_Free (gib_builtins, Hash_DelElement (gib_builtins, del)); +} + +qboolean +GIB_Builtin_Exists (const char *name) +{ + return Hash_Find (gib_builtins, name) ? true : false; } /* diff --git a/ruamoko/cl_menu/client_menu.qc b/ruamoko/cl_menu/client_menu.qc index aef258082..4739761dd 100644 --- a/ruamoko/cl_menu/client_menu.qc +++ b/ruamoko/cl_menu/client_menu.qc @@ -1,6 +1,7 @@ #include "menu.h" #include "file.h" #include "cmd.h" +#include "gib.h" #include "draw.h" #include "key.h" #include "InputLine.h" @@ -11,6 +12,7 @@ #include "options.h" #include "servlist.h" #include "system.h" +#include "debug.h" #include "client_menu.h" //FIXME shouldn't need these @@ -476,6 +478,16 @@ void () main_menu = Menu_End (); }; +void (integer argc, string [] argv) gib_hello_world = +{ + GIB_Return ("Hello, world!"); +}; + +void () gib_menu = +{ + GIB_Builtin_Add ("Ruamoko::helloWorld", gib_hello_world); +}; + void () menu_init = { lanConfig_port_il = [[InputLine alloc] initWithBounds:[[Rect alloc] initWithComponents:126 :lanConfig_cursor_table[0] :8 :4] promptCharacter:' ']; @@ -496,6 +508,7 @@ void () menu_init = quit_menu (); load_menu (); save_menu (); + gib_menu (); Menu_TopMenu ("main"); Menu_SetQuit (quit); }; diff --git a/ruamoko/include/Makefile.am b/ruamoko/include/Makefile.am index 613cf9457..e419e7857 100644 --- a/ruamoko/include/Makefile.am +++ b/ruamoko/include/Makefile.am @@ -7,5 +7,5 @@ include_HEADERS= \ \ draw.h key.h \ \ - cbuf.h cmd.h cvar.h file.h hash.h plist.h \ + cbuf.h cmd.h cvar.h file.h gib.h hash.h plist.h \ Object.h Array.h Entity.h InputLine.h Point.h Rect.h Size.h diff --git a/ruamoko/include/gib.h b/ruamoko/include/gib.h new file mode 100644 index 000000000..67e13e929 --- /dev/null +++ b/ruamoko/include/gib.h @@ -0,0 +1,7 @@ +#ifndef __ruamoko_gib_h +#define __ruamoko_gib_h + +@extern void (string name, void (integer argc, string [] argv) func) GIB_Builtin_Add; +@extern integer (string value) GIB_Return; + +#endif//__ruamoko_gib_h diff --git a/ruamoko/lib/Makefile.am b/ruamoko/lib/Makefile.am index bb12fb3b0..e8a54dbf6 100644 --- a/ruamoko/lib/Makefile.am +++ b/ruamoko/lib/Makefile.am @@ -38,7 +38,7 @@ libgui_a_SOURCES=\ libgui_a_AR=$(PAK) -cf libcsqc_a_SOURCES= \ - cbuf.r cmd.r cvar.r file.r + cbuf.r cmd.r cvar.r file.r gib.r libcsqc_a_AR= $(PAK) -cf CLEANFILES= *.qfo *.o diff --git a/ruamoko/lib/gib.r b/ruamoko/lib/gib.r new file mode 100644 index 000000000..7dabb5975 --- /dev/null +++ b/ruamoko/lib/gib.r @@ -0,0 +1,4 @@ +#include "gib.h" + +void (string name, void (integer argc, string [] argv) func) GIB_Builtin_Add = #0; +integer (string value) GIB_Return = #0;