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:
Bill Currie 2004-11-11 04:06:00 +00:00 committed by Jeff Teunissen
parent 7b4edb2859
commit 5ef382d2a7
10 changed files with 433 additions and 14 deletions

View file

@ -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);

View file

@ -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

View file

@ -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
View 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);
}

View file

@ -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
View 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

View file

@ -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);
}

View file

@ -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
View 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;

View file

@ -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;
};