|
We are using lua for our ai. We have a
main lua state that has all the global data for the
game. Then we have what we call
acts. Each act has a coroutine setup for it off of the main state. Then in the acts we have various
scenes. These also have a coroutine for running scripts in them. The problem we encountered was we were
running out of memory. This was
because we never got ride of the lua coroutines. I finally
figured out how to get the garbage collector to do that. We were still running into memory
problems, just after playing longer.
We found out that lua was fragmenting pretty bad and the garbage collector seemed to have problems at
find stuff it could dump. So now I’m
reworking the scripting stuff to only have have 3 things going. The lua state, and 2 coroutines. I found out that the coroutines
would use the global table and function table from the
original state. This was no good
because it was like having all the lua stuff in
memory all the time. So I found out
how to load a new global table and meta table. Now I’m trying to sync the states
and kind of use them as templates. I
first load the main lua state and throw the global
variables in there. Then when an
act starts it loads the globals from the lua state and then loads its global variables and
functions. Then when a scene is
entered the scene could take all the acts globals and
functions and load those, after that it would load it’s
local stuff. This way when I get
ride of that coroutine I would be assured that all
the lua memory was freed. The problem I’m having now is when
I load the globals from the act it looks good, but
the game acts like the globals were loaded but the
values weren’t. Can anyone
see any logic errors in these 2 functions. Thanks, Jake void
ScriptObject::CopyGlobalsToCoroutine(lua_State* env) { /* table is in the stack at index `t' */ lua_pushnil(env); /* first key */ while(lua_next(env, LUA_GLOBALSINDEX)
!= 0) { /* `key' is at index -2 and `value' at
index -1 */ bool
proceed = true; const
char* string = lua_tostring(env, -2); lua_getglobal(m_Coroutine, string); if(lua_type(m_Coroutine, 1) ==
LUA_TNIL) { switch(lua_type(env, -1)) { case
LUA_TNUMBER: lua_pushnumber(m_Coroutine, lua_tonumber(env, -1)); break; case
LUA_LUASTRING: lua_pushstring(m_Coroutine, lua_tostring(env, -1)); break; case
LUA_TBOOLEAN: lua_pushboolean(m_Coroutine, lua_toboolean(env, -1)); break; case
LUA_TUSERDATA: case
LUA_TLIGHTUSERDATA: lua_pushlightuserdata(m_Coroutine, lua_touserdata(env, -1)); break; case
LUA_TFUNCTION: lua_pushcfunction(m_Coroutine, lua_tocfunction(env, -1)); break; case
LUA_TNIL: case
LUA_TTHREAD: case
LUA_TTABLE: default: proceed = false; break; } if(proceed
== true) { lua_setglobal(m_Coroutine, string); } } lua_pop(env, 1); /* removes `value'; keeps `key' for next
iteration */ lua_pop(m_Coroutine, 1);//
get ride of the global value } } void
ScriptObject::CopyGlobalsFromCoroutine(lua_State* env) { /* table is in the stack at index `t' */ lua_pushnil(env); /* first key */ while(lua_next(env, LUA_GLOBALSINDEX)
!= 0) { bool
proceed = true; const
char* string = lua_tostring(env, -2); lua_getglobal(m_Coroutine, string); /* `key' is at index -2 and `value' at
index -1 */ switch(lua_type(env, -1)) { case
LUA_TNUMBER: lua_pushnumber(env, lua_tonumber(m_Coroutine, 1)); break; case
LUA_LUASTRING: lua_pushstring(env, lua_tostring(m_Coroutine, 1)); break; case
LUA_TBOOLEAN: lua_pushboolean(env, lua_toboolean(m_Coroutine, 1)); break; case
LUA_TUSERDATA: case
LUA_TLIGHTUSERDATA: lua_pushlightuserdata(env, lua_touserdata(m_Coroutine, 1)); break; case
LUA_TNIL: case
LUA_TTHREAD: case
LUA_TFUNCTION: case
LUA_TTABLE: default: proceed = false; break; } if(proceed
== true) { lua_setglobal(env, string); } lua_pop(env, 1); /* removes `value'; keeps `key' for next
iteration */ lua_pop(m_Coroutine, 1);//
get ride of the global value } } |