lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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

      }

}