mirror of
https://github.com/UberGames/rpgxEF.git
synced 2024-11-13 00:24:06 +00:00
Multiple fixes
* made sure Lua GarbageCollector gets rid of finished lua threads (or at least I hope so) * changed timed message to be stored in a struct as the list isn't safe to use with char* * changed parser and format for timedmessages.cfg
This commit is contained in:
parent
94ffb3ea61
commit
75f20c6eef
7 changed files with 167 additions and 33 deletions
|
@ -512,6 +512,7 @@ list_iter_p iterTimedMessages;
|
||||||
*/
|
*/
|
||||||
static char *TimedMessage( void ){
|
static char *TimedMessage( void ){
|
||||||
char* message;
|
char* message;
|
||||||
|
timedMessage_t *msg;
|
||||||
|
|
||||||
if(!level.timedMessages->length) {
|
if(!level.timedMessages->length) {
|
||||||
return "^1RPG-X ERROR: No messages to display";
|
return "^1RPG-X ERROR: No messages to display";
|
||||||
|
@ -524,7 +525,8 @@ static char *TimedMessage( void ){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
message = (char *)list_cycl_next(iterTimedMessages);
|
msg = (timedMessage_t *)list_cycl_next(iterTimedMessages);
|
||||||
|
message = msg->message;
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7439,7 +7439,8 @@ static void Cmd_Camtest_f(gentity_t *ent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cmd_CamtestEnd_f(gentity_t *ent) {
|
void Cmd_CamtestEnd_f(gentity_t *ent) {
|
||||||
Cinematic_DeactivateCameraMode(ent);
|
//Cinematic_DeactivateCameraMode(ent);
|
||||||
|
G_LuaNumThreads();
|
||||||
}
|
}
|
||||||
// END CCAM
|
// END CCAM
|
||||||
|
|
||||||
|
|
|
@ -1368,6 +1368,8 @@ qboolean LuaHook_G_EntityTrigger(char *function, int entnum, int othernum);
|
||||||
qboolean LuaHook_G_EntitySpawn(char *function, int entnum);
|
qboolean LuaHook_G_EntitySpawn(char *function, int entnum);
|
||||||
qboolean LuaHook_G_EntityReached(char *function, int entnum);
|
qboolean LuaHook_G_EntityReached(char *function, int entnum);
|
||||||
qboolean LuaHook_G_EntityReachedAngular(char *function, int entnum);
|
qboolean LuaHook_G_EntityReachedAngular(char *function, int entnum);
|
||||||
|
void G_LuaNumThreads(void);
|
||||||
|
void G_LuaCollectGarbage(void);
|
||||||
|
|
||||||
void G_LuaStatus(gentity_t * ent);
|
void G_LuaStatus(gentity_t * ent);
|
||||||
qboolean G_LuaInit(void);
|
qboolean G_LuaInit(void);
|
||||||
|
@ -2099,5 +2101,10 @@ struct safeZone_s {
|
||||||
vec3_t mins;
|
vec3_t mins;
|
||||||
} safeZone_s;
|
} safeZone_s;
|
||||||
|
|
||||||
|
// timed messages
|
||||||
|
typedef struct timedMessage_s timedMessage_t;
|
||||||
|
struct timedMessage_s {
|
||||||
|
char* message;
|
||||||
|
} timedMessage_s;
|
||||||
|
|
||||||
#endif //_G_LOCAL_H_
|
#endif //_G_LOCAL_H_
|
||||||
|
|
|
@ -172,7 +172,24 @@ qboolean G_LuaResume(lvm_t *vm, lua_State *T, char *func, int nargs) {
|
||||||
G_Printf(S_COLOR_YELLOW "Lua: traceback error ( %s )\n", vm->filename);
|
G_Printf(S_COLOR_YELLOW "Lua: traceback error ( %s )\n", vm->filename);
|
||||||
vm->error++;
|
vm->error++;
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(vm->L != T) { // this is a thread
|
||||||
|
int n = lua_gettop(vm->L);
|
||||||
|
int i;
|
||||||
|
lua_State *p;
|
||||||
|
|
||||||
|
for(i = 0; i <= n; i++) {
|
||||||
|
if(lua_isthread(vm->L, i)) {
|
||||||
|
p = lua_tothread(vm->L, i);
|
||||||
|
|
||||||
|
if(p == T) {
|
||||||
|
lua_remove(vm->L, i);
|
||||||
|
G_LuaCollectGarbage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,22 +281,22 @@ qboolean G_LuaStartVM(lvm_t * vm)
|
||||||
if(lua_istable(vm->L, -1))
|
if(lua_istable(vm->L, -1))
|
||||||
{
|
{
|
||||||
lua_pushstring(vm->L, va("%s%s%s%s?.lua;%s%s%s%slualib%slua%s?.lua",
|
lua_pushstring(vm->L, va("%s%s%s%s?.lua;%s%s%s%slualib%slua%s?.lua",
|
||||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP,
|
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP,
|
||||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP));
|
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP));
|
||||||
lua_setfield(vm->L, -2, "path");
|
lua_setfield(vm->L, -2, "path");
|
||||||
lua_pushstring(vm->L, va("%s%s%s%s?.%s;%s%s%s%slualib%sclibs%s?.%s",
|
lua_pushstring(vm->L, va("%s%s%s%s?.%s;%s%s%s%slualib%sclibs%s?.%s",
|
||||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
|
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
|
||||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
|
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
|
||||||
lua_setfield(vm->L, -2, "cpath");
|
lua_setfield(vm->L, -2, "cpath");
|
||||||
}
|
}
|
||||||
lua_pop(vm->L, 1);
|
lua_pop(vm->L, 1);
|
||||||
|
|
||||||
Lua_RegisterGlobal(vm->L, "LUA_PATH", va("%s%s%s%s?.lua;%s%s%s%slualib%slua%s?.lua",
|
Lua_RegisterGlobal(vm->L, "LUA_PATH", va("%s%s%s%s?.lua;%s%s%s%slualib%slua%s?.lua",
|
||||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP,
|
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP,
|
||||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP));
|
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP));
|
||||||
Lua_RegisterGlobal(vm->L, "LUA_CPATH", va("%s%s%s%s?.%s;%s%s%s%slualib%sclibs%s?.%s",
|
Lua_RegisterGlobal(vm->L, "LUA_CPATH", va("%s%s%s%s?.%s;%s%s%s%slualib%sclibs%s?.%s",
|
||||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
|
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
|
||||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
|
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
|
||||||
Lua_RegisterGlobal(vm->L, "LUA_DIRSEP", LUA_DIRSEP);
|
Lua_RegisterGlobal(vm->L, "LUA_DIRSEP", LUA_DIRSEP);
|
||||||
|
|
||||||
lua_newtable(vm->L);
|
lua_newtable(vm->L);
|
||||||
|
@ -588,6 +605,7 @@ qboolean LuaHook_G_EntityThink(char *function, int entnum)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
t = vm->L;
|
||||||
if(!G_LuaGetFunctionT(t, function))
|
if(!G_LuaGetFunctionT(t, function))
|
||||||
continue;
|
continue;
|
||||||
ent = &g_entities[entnum];
|
ent = &g_entities[entnum];
|
||||||
|
@ -1071,4 +1089,49 @@ qboolean LuaHook_G_EntitySpawn(char *function, int entnum)
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void G_LuaNumThreads(void) {
|
||||||
|
lvm_t* vm = lVM[0];
|
||||||
|
|
||||||
|
if(vm) {
|
||||||
|
lua_State *p;
|
||||||
|
int n = lua_gettop(vm->L);
|
||||||
|
int i, cnt = 0;
|
||||||
|
|
||||||
|
for(i = 0; i <= n; i++) {
|
||||||
|
if(lua_isthread(vm->L, i)) {
|
||||||
|
cnt++;
|
||||||
|
p = lua_tothread(vm->L, i);
|
||||||
|
if(lua_status(p) == LUA_YIELD) {
|
||||||
|
G_Printf("lua thread %d is YIELDED\n", i);
|
||||||
|
} else if(lua_status(vm->L) == 0) {
|
||||||
|
G_Printf("lua thread %d is RUNNING\n", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
G_Printf("Total lua thread count: %d\n", cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_LuaCollectGarbage(void) {
|
||||||
|
lvm_t *vm;
|
||||||
|
lua_State *p;
|
||||||
|
int i, n, m;
|
||||||
|
|
||||||
|
for(i = 0; i < NUM_VMS; i++) {
|
||||||
|
vm = lVM[i];
|
||||||
|
|
||||||
|
if(vm) {
|
||||||
|
n = lua_gettop(vm->L);
|
||||||
|
|
||||||
|
for(m = n; m > 0; m--) {
|
||||||
|
if(lua_isthread(vm->L, m)) {
|
||||||
|
p = lua_tothread(vm->L, m);
|
||||||
|
lua_gc(p, LUA_GCCOLLECT, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_gc(vm->L, LUA_GCCOLLECT, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -906,10 +906,11 @@ void SP_target_location (gentity_t *ent);
|
||||||
static void G_LoadTimedMessages(void) {
|
static void G_LoadTimedMessages(void) {
|
||||||
fileHandle_t f;
|
fileHandle_t f;
|
||||||
char* buffer;
|
char* buffer;
|
||||||
char* ptr;
|
char* textPtr;
|
||||||
char* message;
|
char* token;
|
||||||
int len;
|
int len;
|
||||||
int i, n;
|
int i;
|
||||||
|
timedMessage_t *msg;
|
||||||
|
|
||||||
len = trap_FS_FOpenFile("timedmessages.cfg", &f, FS_READ);
|
len = trap_FS_FOpenFile("timedmessages.cfg", &f, FS_READ);
|
||||||
if(!len) return;
|
if(!len) return;
|
||||||
|
@ -930,26 +931,49 @@ static void G_LoadTimedMessages(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
trap_FS_Read(buffer, len, f);
|
trap_FS_Read(buffer, len, f);
|
||||||
ptr = buffer;
|
|
||||||
|
textPtr = buffer;
|
||||||
|
COM_BeginParseSession();
|
||||||
|
token = COM_Parse(&textPtr);
|
||||||
|
if(token[0] != '{') {
|
||||||
|
G_Printf("G_LoadTimedMessages - timedmessages.cfg not beginning with '{'\n");
|
||||||
|
trap_FS_FCloseFile(f);
|
||||||
|
free(buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for(i = 0; i < 10; i++) {
|
for(i = 0; i < 10; i++) {
|
||||||
for(n = 0; ptr[n] != ';' && ptr[n] != 0; n++);
|
token = COM_Parse(&textPtr);
|
||||||
if(ptr[n] == 0) break;
|
|
||||||
message = (char *)malloc(sizeof(char)*(n+1));
|
if(!token[0]) {
|
||||||
if(!message) {
|
break;
|
||||||
G_Printf(S_COLOR_RED "ERROR: Was unable to allocate %i byte.\n", (n+1) * sizeof(char) );
|
|
||||||
trap_FS_FCloseFile(f);
|
|
||||||
free(buffer);
|
|
||||||
if(level.timedMessages != NULL) {
|
|
||||||
destroy_list(level.timedMessages);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(message, 0, sizeof(message));
|
if(!strcmp(token, "message")) {
|
||||||
strncpy(message, ptr, n);
|
if(COM_ParseString(&textPtr, &token)) {
|
||||||
list_add(level.timedMessages, message, strlen(message));
|
G_Printf("G_LoadTimedMessages - invalid value '%s'\n", token);
|
||||||
|
SkipRestOfLine(&textPtr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ptr += strlen(message)+1;
|
msg = (timedMessage_t *)malloc(sizeof(timedMessage_s));
|
||||||
|
if(msg == NULL) {
|
||||||
|
G_Printf("G_LoadTimedMessages - was unable to allocate timed message storage\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->message = strdup(token);
|
||||||
|
G_Printf("------------------------------------------------>'%s'\n", token);
|
||||||
|
list_add(level.timedMessages, msg, sizeof(timedMessage_s));
|
||||||
|
} else {
|
||||||
|
G_Printf("G_LoadTimedMessages - invalid token '%s'\n", token);
|
||||||
|
SkipRestOfLine(&textPtr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(token[0] == '}') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trap_FS_FCloseFile(f);
|
trap_FS_FCloseFile(f);
|
||||||
|
|
|
@ -738,6 +738,35 @@ char* Q_strrchr( const char* string, int c )
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* Q_strtok(char* str, const char *tok, int size) {
|
||||||
|
char *ptr;
|
||||||
|
char *result;
|
||||||
|
int i, l;
|
||||||
|
|
||||||
|
if(str == NULL || tok == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = (char *)str;
|
||||||
|
|
||||||
|
for(i = 0; i < strlen(str); i++) {
|
||||||
|
for(l = 0; l < size; l++) {
|
||||||
|
if(ptr[i] == tok[l]) {
|
||||||
|
result = (char *)malloc(sizeof(char)+(i+1));
|
||||||
|
if(result == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
strncpy(result, str, i);
|
||||||
|
result[i] = '\0';
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
Q_strncpyz
|
Q_strncpyz
|
||||||
|
|
|
@ -688,9 +688,17 @@ int Q_isalpha( int c );
|
||||||
int Q_stricmp (const char *s1, const char *s2);
|
int Q_stricmp (const char *s1, const char *s2);
|
||||||
int Q_strncmp (const char *s1, const char *s2, int n);
|
int Q_strncmp (const char *s1, const char *s2, int n);
|
||||||
int Q_stricmpn (const char *s1, const char *s2, int n);
|
int Q_stricmpn (const char *s1, const char *s2, int n);
|
||||||
char *Q_strlwr( char *s1 );
|
char* Q_strlwr( char *s1 );
|
||||||
char *Q_strupr( char *s1 );
|
char* Q_strupr( char *s1 );
|
||||||
char *Q_strrchr( const char* string, int c );
|
char* Q_strrchr( const char* string, int c );
|
||||||
|
/**
|
||||||
|
* Goes through a given str searching for one of the given tokens.
|
||||||
|
* If it finds one it returns a new string containing everything
|
||||||
|
* from str until the found token (Note: remember to free the result
|
||||||
|
* if no longer needed). Returns NULL if no token is found. Make sure
|
||||||
|
* to adjust str for the next call yourself as this function won't do that.
|
||||||
|
*/
|
||||||
|
char* Q_strtok(char* str, const char *tok, int size);
|
||||||
|
|
||||||
// buffer size safe library replacements
|
// buffer size safe library replacements
|
||||||
void Q_strncpyz( char *dest, const char *src, int destsize );
|
void Q_strncpyz( char *dest, const char *src, int destsize );
|
||||||
|
|
Loading…
Reference in a new issue