mirror of
https://github.com/UberGames/rpgxEF.git
synced 2024-11-10 07:11:34 +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 ){
|
||||
char* message;
|
||||
timedMessage_t *msg;
|
||||
|
||||
if(!level.timedMessages->length) {
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -7439,7 +7439,8 @@ static void Cmd_Camtest_f(gentity_t *ent) {
|
|||
}
|
||||
|
||||
void Cmd_CamtestEnd_f(gentity_t *ent) {
|
||||
Cinematic_DeactivateCameraMode(ent);
|
||||
//Cinematic_DeactivateCameraMode(ent);
|
||||
G_LuaNumThreads();
|
||||
}
|
||||
// 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_EntityReached(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);
|
||||
qboolean G_LuaInit(void);
|
||||
|
@ -2099,5 +2101,10 @@ struct safeZone_s {
|
|||
vec3_t mins;
|
||||
} safeZone_s;
|
||||
|
||||
// timed messages
|
||||
typedef struct timedMessage_s timedMessage_t;
|
||||
struct timedMessage_s {
|
||||
char* message;
|
||||
} timedMessage_s;
|
||||
|
||||
#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);
|
||||
vm->error++;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -264,22 +281,22 @@ qboolean G_LuaStartVM(lvm_t * vm)
|
|||
if(lua_istable(vm->L, -1))
|
||||
{
|
||||
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, LUA_DIRSEP, LUA_DIRSEP));
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP));
|
||||
lua_setfield(vm->L, -2, "path");
|
||||
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, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
|
||||
lua_setfield(vm->L, -2, "cpath");
|
||||
}
|
||||
lua_pop(vm->L, 1);
|
||||
|
||||
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, LUA_DIRSEP, LUA_DIRSEP));
|
||||
homepath, LUA_DIRSEP, gamepath, 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",
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, EXTENSION,
|
||||
homepath, LUA_DIRSEP, gamepath, LUA_DIRSEP, LUA_DIRSEP, LUA_DIRSEP, EXTENSION));
|
||||
Lua_RegisterGlobal(vm->L, "LUA_DIRSEP", LUA_DIRSEP);
|
||||
|
||||
lua_newtable(vm->L);
|
||||
|
@ -588,6 +605,7 @@ qboolean LuaHook_G_EntityThink(char *function, int entnum)
|
|||
continue;
|
||||
}
|
||||
} else {
|
||||
t = vm->L;
|
||||
if(!G_LuaGetFunctionT(t, function))
|
||||
continue;
|
||||
ent = &g_entities[entnum];
|
||||
|
@ -1071,4 +1089,49 @@ qboolean LuaHook_G_EntitySpawn(char *function, int entnum)
|
|||
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
|
|
@ -906,10 +906,11 @@ void SP_target_location (gentity_t *ent);
|
|||
static void G_LoadTimedMessages(void) {
|
||||
fileHandle_t f;
|
||||
char* buffer;
|
||||
char* ptr;
|
||||
char* message;
|
||||
char* textPtr;
|
||||
char* token;
|
||||
int len;
|
||||
int i, n;
|
||||
int i;
|
||||
timedMessage_t *msg;
|
||||
|
||||
len = trap_FS_FOpenFile("timedmessages.cfg", &f, FS_READ);
|
||||
if(!len) return;
|
||||
|
@ -930,26 +931,49 @@ static void G_LoadTimedMessages(void) {
|
|||
}
|
||||
|
||||
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(n = 0; ptr[n] != ';' && ptr[n] != 0; n++);
|
||||
if(ptr[n] == 0) break;
|
||||
message = (char *)malloc(sizeof(char)*(n+1));
|
||||
if(!message) {
|
||||
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;
|
||||
token = COM_Parse(&textPtr);
|
||||
|
||||
if(!token[0]) {
|
||||
break;
|
||||
}
|
||||
|
||||
memset(message, 0, sizeof(message));
|
||||
strncpy(message, ptr, n);
|
||||
list_add(level.timedMessages, message, strlen(message));
|
||||
if(!strcmp(token, "message")) {
|
||||
if(COM_ParseString(&textPtr, &token)) {
|
||||
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);
|
||||
|
|
|
@ -738,6 +738,35 @@ char* Q_strrchr( const char* string, int c )
|
|||
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
|
||||
|
|
|
@ -688,9 +688,17 @@ int Q_isalpha( int c );
|
|||
int Q_stricmp (const char *s1, const char *s2);
|
||||
int Q_strncmp (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_strupr( char *s1 );
|
||||
char *Q_strrchr( const char* string, int c );
|
||||
char* Q_strlwr( char *s1 );
|
||||
char* Q_strupr( char *s1 );
|
||||
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
|
||||
void Q_strncpyz( char *dest, const char *src, int destsize );
|
||||
|
|
Loading…
Reference in a new issue