mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-21 09:51:41 +00:00
Add a rua wrapper for scripts (seems, to work, too:). Also added generic resource handle support based on strref handling in pr_strings.c.
This is an imperfect revision of history.
This commit is contained in:
parent
7b4edb2859
commit
5ef382d2a7
10 changed files with 433 additions and 14 deletions
|
@ -33,10 +33,6 @@
|
|||
#define __rua_internal_h
|
||||
|
||||
#include "QF/quakeio.h"
|
||||
#define QFILE_MAX_HANDLES 20
|
||||
typedef struct {
|
||||
QFile *handles[QFILE_MAX_HANDLES];
|
||||
} qfile_resources_t;
|
||||
|
||||
void RUA_Cbuf_Init (struct progs_s *pr, int secure);
|
||||
|
||||
|
@ -54,6 +50,7 @@ void RUA_Obj_Init (struct progs_s *pr, int secure);
|
|||
|
||||
void RUA_Plist_Init (struct progs_s *pr, int secure);
|
||||
|
||||
void RUA_Script_Init (progs_t *pr, int secure);
|
||||
void RUA_String_Init (struct progs_s *pr, int secure);
|
||||
|
||||
void RUA_QFile_Init (struct progs_s *pr, int secure);
|
||||
|
|
|
@ -9,5 +9,5 @@ libQFruamoko_la_LDFLAGS= -version-info 1:0:0 -no-undefined
|
|||
libQFruamoko_la_LIBADD= $(top_builddir)/libs/gamecode/engine/libQFgamecode.la $(top_builddir)/libs/util/libQFutil.la
|
||||
libQFruamoko_la_SOURCES= \
|
||||
rua_cbuf.c rua_cmd.c rua_cvar.c rua_file.c rua_hash.c rua_init.c \
|
||||
rua_obj.c rua_plist.c rua_qfile.c rua_qfs.c rua_string.c \
|
||||
rua_math.c
|
||||
rua_math.c rua_obj.c rua_plist.c rua_qfile.c rua_qfs.c rua_script.c \
|
||||
rua_string.c
|
||||
|
|
|
@ -48,6 +48,7 @@ static void (*init_funcs[])(progs_t *, int) = {
|
|||
RUA_Plist_Init,
|
||||
RUA_QFile_Init,
|
||||
RUA_QFS_Init,
|
||||
RUA_Script_Init,
|
||||
RUA_String_Init,
|
||||
};
|
||||
|
||||
|
|
222
libs/ruamoko/rua_script.c
Normal file
222
libs/ruamoko/rua_script.c
Normal file
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
rua_script.c
|
||||
|
||||
Script api for ruamoko
|
||||
|
||||
Copyright (C) 2004 Bill Currie
|
||||
|
||||
Author: Bill Currie
|
||||
Date: 2002/11/11
|
||||
|
||||
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 <stdlib.h>
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "QF/progs.h"
|
||||
#include "QF/script.h"
|
||||
|
||||
#include "rua_internal.h"
|
||||
|
||||
typedef struct {
|
||||
script_t script;
|
||||
string_t dstr;
|
||||
progs_t *pr;
|
||||
string_t err_msg;
|
||||
} rua_script_t;
|
||||
|
||||
typedef struct {
|
||||
PR_RESMAP(rua_script_t) scripts;
|
||||
} script_resources_t;
|
||||
|
||||
static rua_script_t *
|
||||
script_new (script_resources_t *res)
|
||||
{
|
||||
PR_RESNEW (rua_script_t, res->scripts);
|
||||
}
|
||||
|
||||
static void
|
||||
script_free (script_resources_t *res, rua_script_t *script)
|
||||
{
|
||||
PR_RESFREE (rua_script_t, res->scripts, script);
|
||||
}
|
||||
|
||||
static void
|
||||
script_reset (script_resources_t *res)
|
||||
{
|
||||
PR_RESRESET (rua_script_t, res->scripts);
|
||||
}
|
||||
|
||||
static inline rua_script_t *
|
||||
script_get (script_resources_t *res, int index)
|
||||
{
|
||||
PR_RESGET(res->scripts, index);
|
||||
}
|
||||
|
||||
static inline int
|
||||
script_index (script_resources_t *res, rua_script_t *script)
|
||||
{
|
||||
PR_RESINDEX(res->scripts, script);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_script_clear (progs_t *pr, void *data)
|
||||
{
|
||||
script_resources_t *res = (script_resources_t *) data;
|
||||
script_reset (res);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_script_error (script_t *_script, const char *msg)
|
||||
{
|
||||
rua_script_t *script = (rua_script_t *)_script;
|
||||
script->err_msg = PR_SetString (script->pr, msg);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Script_New (progs_t *pr)
|
||||
{
|
||||
script_resources_t *res = PR_Resources_Find (pr, "Script");
|
||||
rua_script_t *script = script_new (res);
|
||||
|
||||
if (!script)
|
||||
PR_RunError (pr, "out of memory");
|
||||
|
||||
script->dstr = PR_NewMutableString (pr);
|
||||
script->script.token = PR_GetMutableString (pr, script->dstr);
|
||||
script->script.error = bi_script_error;
|
||||
script->pr = pr;
|
||||
R_INT (pr) = script_index (res, script);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Script_Delete (progs_t *pr)
|
||||
{
|
||||
script_resources_t *res = PR_Resources_Find (pr, "Script");
|
||||
rua_script_t *script = script_get (res, P_INT (pr, 0));
|
||||
|
||||
if (!script)
|
||||
PR_RunError (pr, "invalid script handle");
|
||||
PR_FreeString (pr, script->dstr);
|
||||
script_free (res, script);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Script_Start (progs_t *pr)
|
||||
{
|
||||
script_resources_t *res = PR_Resources_Find (pr, "Script");
|
||||
rua_script_t *script = script_get (res, P_INT (pr, 0));
|
||||
|
||||
if (!script)
|
||||
PR_RunError (pr, "invalid script handle");
|
||||
Script_Start (&script->script, P_GSTRING (pr, 1), P_GSTRING (pr, 2));
|
||||
R_STRING (pr) = script->dstr;
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Script_TokenAvailable (progs_t *pr)
|
||||
{
|
||||
script_resources_t *res = PR_Resources_Find (pr, "Script");
|
||||
rua_script_t *script = script_get (res, P_INT (pr, 0));
|
||||
|
||||
if (!script)
|
||||
PR_RunError (pr, "invalid script handle");
|
||||
R_INT (pr) = Script_TokenAvailable (&script->script, P_INT (pr, 1));
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Script_GetToken (progs_t *pr)
|
||||
{
|
||||
script_resources_t *res = PR_Resources_Find (pr, "Script");
|
||||
rua_script_t *script = script_get (res, P_INT (pr, 0));
|
||||
|
||||
if (!script)
|
||||
PR_RunError (pr, "invalid script handle");
|
||||
R_INT (pr) = Script_GetToken (&script->script, P_INT (pr, 1));
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Script_UngetToken (progs_t *pr)
|
||||
{
|
||||
script_resources_t *res = PR_Resources_Find (pr, "Script");
|
||||
rua_script_t *script = script_get (res, P_INT (pr, 0));
|
||||
|
||||
if (!script)
|
||||
PR_RunError (pr, "invalid script handle");
|
||||
Script_UngetToken (&script->script);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Script_Error (progs_t *pr)
|
||||
{
|
||||
script_resources_t *res = PR_Resources_Find (pr, "Script");
|
||||
rua_script_t *script = script_get (res, P_INT (pr, 0));
|
||||
|
||||
if (!script)
|
||||
PR_RunError (pr, "invalid script handle");
|
||||
R_STRING (pr) = script->err_msg;
|
||||
script->err_msg = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
bi_Script_NoQuoteLines (progs_t *pr)
|
||||
{
|
||||
script_resources_t *res = PR_Resources_Find (pr, "Script");
|
||||
rua_script_t *script = script_get (res, P_INT (pr, 0));
|
||||
|
||||
if (!script)
|
||||
PR_RunError (pr, "invalid script handle");
|
||||
R_INT (pr) = script->script.no_quote_lines;
|
||||
script->script.no_quote_lines = P_INT (pr, 1);
|
||||
}
|
||||
|
||||
static builtin_t builtins[] = {
|
||||
{"Script_New", bi_Script_New, -1},
|
||||
{"Script_Delete", bi_Script_Delete, -1},
|
||||
{"Script_Start", bi_Script_Start, -1},
|
||||
{"Script_TokenAvailable", bi_Script_TokenAvailable, -1},
|
||||
{"Script_GetToken", bi_Script_GetToken, -1},
|
||||
{"Script_UngetToken", bi_Script_UngetToken, -1},
|
||||
{"Script_Error", bi_Script_Error, -1},
|
||||
{"Script_NoQuoteLines", bi_Script_NoQuoteLines, -1},
|
||||
{0}
|
||||
};
|
||||
|
||||
void
|
||||
RUA_Script_Init (progs_t *pr, int secure)
|
||||
{
|
||||
script_resources_t *res = calloc (1, sizeof (script_resources_t));
|
||||
|
||||
PR_Resources_Register (pr, "Script", res, bi_script_clear);
|
||||
|
||||
PR_RegisterBuiltins (pr, builtins);
|
||||
}
|
|
@ -3,7 +3,7 @@ pkgincludedir= $(includedir)/QF/ruamoko
|
|||
nobase_pkginclude_HEADERS= \
|
||||
crudefile.h debug.h entities.h infokey.h math.h message.h nq_message.h \
|
||||
physics.h qfile.h qfs.h qw_message.h qw_physics.h qw_sys.h server.h \
|
||||
sound.h string.h system.h \
|
||||
sound.h script.h string.h system.h \
|
||||
\
|
||||
draw.h key.h \
|
||||
\
|
||||
|
|
16
ruamoko/include/script.h
Normal file
16
ruamoko/include/script.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef __ruamoko_script_h
|
||||
#define __ruamoko_script_h
|
||||
|
||||
typedef struct rua_script [] script_t;
|
||||
|
||||
@extern script_t Script_New (void);
|
||||
@extern void Script_Delete (script_t script);
|
||||
// returns the token string
|
||||
@extern string Script_Start (script_t script, string file, string data);
|
||||
@extern integer Script_TokenAvailable (script_t script, integer crossline);
|
||||
@extern integer Script_GetToken (script_t script, integer crossline);
|
||||
@extern void Script_UngetToken (script_t script);
|
||||
@extern string Script_Error (script_t script);
|
||||
@extern integer Script_NoQuoteLines (script_t script);
|
||||
|
||||
#endif//__ruamoko_script_h
|
|
@ -1,7 +1,25 @@
|
|||
#include "Entity.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "entities.h"
|
||||
#include "plist.h"
|
||||
#include "script.h"
|
||||
#include "string.h"
|
||||
|
||||
typedef void () void_function;
|
||||
|
||||
integer PR_SetField (entity ent, string field, string value) = #0;
|
||||
function PR_FindFunction (string func) = #0;
|
||||
|
||||
@static void ParseEntities (string ent_data);
|
||||
|
||||
@implementation Entity
|
||||
|
||||
- (void) own
|
||||
{
|
||||
own = 1;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
return [self initWithEntity: spawn ()];
|
||||
|
@ -14,15 +32,117 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void) free
|
||||
- (void) dealloc
|
||||
{
|
||||
remove (ent);
|
||||
[super free];
|
||||
if (own)
|
||||
remove (ent);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (entity) ent
|
||||
{
|
||||
return self.ent;
|
||||
return ent;
|
||||
}
|
||||
|
||||
+ (void) load
|
||||
{
|
||||
//XXX EntityParseFunction (ParseEntities);
|
||||
}
|
||||
|
||||
+ createFromPlist:(plitem_t) dict
|
||||
{
|
||||
local string classname;
|
||||
local Class class;
|
||||
local entity ent;
|
||||
local integer count;
|
||||
local string field, value;
|
||||
local plitem_t keys;
|
||||
local function func;
|
||||
local Entity e;
|
||||
|
||||
classname = PL_String (PL_ObjectForKey (dict, "classname"));
|
||||
if (classname == "worldspawn")
|
||||
ent = NIL;
|
||||
else
|
||||
ent = spawn ();
|
||||
if ((class = obj_lookup_class (classname))) {
|
||||
e = [[class alloc] initWithEntity:ent fromPlist:dict];
|
||||
} else {
|
||||
e = [[Entity alloc] initWithEntity:ent];
|
||||
keys = PL_D_AllKeys (dict);
|
||||
count = PL_A_NumObjects (keys);
|
||||
while (count--) {
|
||||
field = PL_String (PL_ObjectAtIndex (keys, count));
|
||||
value = PL_String (PL_ObjectForKey (dict, field));
|
||||
PR_SetField (ent, field, value);
|
||||
}
|
||||
PL_Free (keys);
|
||||
if ((func = PR_FindFunction (classname))) {
|
||||
//dprint ("calling " + classname + "\n");
|
||||
@self = ent;
|
||||
func ();
|
||||
} else {
|
||||
//dprint ("no spawn function for " + classname + "\n");
|
||||
}
|
||||
}
|
||||
if (ent)
|
||||
[e own];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@static void ParseEntities (string ent_data)
|
||||
{
|
||||
local script_t script;
|
||||
local plitem_t plist, ent, key, value;
|
||||
local string token;
|
||||
local integer anglehack, i, count;
|
||||
|
||||
script = Script_New ();
|
||||
token = Script_Start (script, "ent data", ent_data);
|
||||
if (Script_GetToken (script, 1)) {
|
||||
if (token == "(") {
|
||||
plist = PL_GetPropertyList (ent_data);
|
||||
} else {
|
||||
Script_UngetToken (script);
|
||||
plist = PL_NewArray ();
|
||||
while (Script_GetToken (script, 1)) {
|
||||
if (token != "{")
|
||||
return; // abort, bad ent data
|
||||
ent = PL_NewDictionary ();
|
||||
while (1) {
|
||||
if (!Script_GetToken (script, 1))
|
||||
return; // abort, bad ent data
|
||||
if (token == "}")
|
||||
break;
|
||||
anglehack = 0;
|
||||
if (token == "angle") {
|
||||
key = PL_NewString ("angles");
|
||||
anglehack = 1;
|
||||
} else if (token == "light") {
|
||||
key = PL_NewString ("light_lev");
|
||||
} else {
|
||||
key = PL_NewString (token);
|
||||
}
|
||||
if (!Script_GetToken (script, 0))
|
||||
return; // abort, bad ent data
|
||||
if (token == "}")
|
||||
return; // abort, bad ent data
|
||||
if (anglehack)
|
||||
value = PL_NewString ("0 " + token + " 0");
|
||||
else
|
||||
value = PL_NewString (token);
|
||||
PL_D_AddObject (ent, key, value);
|
||||
}
|
||||
PL_A_AddObject (plist, ent);
|
||||
}
|
||||
}
|
||||
//dprint (PL_WritePropertyList (plist));
|
||||
count = PL_A_NumObjects (plist);
|
||||
for (i = 0; i < count; i++) {
|
||||
ent = PL_ObjectAtIndex (plist, i);
|
||||
[Entity createFromPlist:ent];
|
||||
}
|
||||
}
|
||||
Script_Delete (script);
|
||||
}
|
||||
|
|
|
@ -17,16 +17,16 @@ typedef struct list_bucket_s list_bucket_t;
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void) free
|
||||
- (void) dealloc
|
||||
{
|
||||
local list_bucket_t [] e, t = NIL; //FIXME t uninitialized
|
||||
|
||||
for (e = head; e; e = t) {
|
||||
t = e.next;
|
||||
[e.obj free];
|
||||
[e.obj release];
|
||||
obj_free (e);
|
||||
}
|
||||
[super free];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id) getItemAt: (integer) index
|
||||
|
|
11
ruamoko/lib/script.r
Normal file
11
ruamoko/lib/script.r
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "script.h"
|
||||
|
||||
script_t Script_New (void) = #0;
|
||||
void Script_Delete (script_t script) = #0;
|
||||
// returns the token string
|
||||
string Script_Start (script_t script, string file, string data) = #0;
|
||||
integer Script_TokenAvailable (script_t script, integer crossline) = #0;
|
||||
integer Script_GetToken (script_t script, integer crossline) = #0;
|
||||
void Script_UngetToken (script_t script) = #0;
|
||||
string Script_Error (script_t script) = #0;
|
||||
integer Script_NoQuoteLines (script_t script) = #0;
|
|
@ -1,3 +1,53 @@
|
|||
string read_file (string filename)
|
||||
{
|
||||
local QFile file;
|
||||
local string data = NIL, d;
|
||||
file = Qopen (filename, "rtz");
|
||||
if (!file) {
|
||||
printf ("Can't open %s for reading."
|
||||
" Probably a bad hardcoded filename:)\n");
|
||||
return NIL;
|
||||
}
|
||||
while ((d = Qgetline (file)))
|
||||
data = data + d;
|
||||
//FIXME can't read to a string, can't convert a pointer to a string ...
|
||||
//Qread (file, data, 1023);
|
||||
Qclose (file);
|
||||
d = str_new ();
|
||||
str_copy (d, data);
|
||||
return d;
|
||||
}
|
||||
|
||||
void test_plist (void)
|
||||
{
|
||||
local string data, l;
|
||||
local plitem_t pl;
|
||||
|
||||
data = read_file ("/home/bill/.quakeforge.dir");
|
||||
pl = PL_GetPropertyList ("{" + data + "}");
|
||||
l = PL_WritePropertyList (pl);
|
||||
printf ("%s", data);
|
||||
printf ("%s", l);
|
||||
PL_Free (pl);
|
||||
str_free (data);
|
||||
}
|
||||
|
||||
void test_script (void)
|
||||
{
|
||||
local script_t script;
|
||||
local string token;
|
||||
local string data;
|
||||
|
||||
data = read_file ("progs.src");
|
||||
script = Script_New ();
|
||||
token = Script_Start (script, "progs.src", data);
|
||||
while (Script_GetToken (script, 1)) {
|
||||
printf ("%s\n", token);
|
||||
}
|
||||
Script_Delete (script);
|
||||
str_free (data);
|
||||
}
|
||||
|
||||
void () test_str =
|
||||
{
|
||||
local string a,b,c,d;
|
||||
|
@ -47,5 +97,7 @@ integer (integer argc, string []argv) main =
|
|||
} else
|
||||
print ("did not find selector for `run:with:me:'\n");
|
||||
test_str ();
|
||||
test_script ();
|
||||
test_plist ();
|
||||
return 0;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue