Skip to content

Commit

Permalink
Lua API: Fix ai table sometimes unexpectedly becoming read-only
Browse files Browse the repository at this point in the history
This could happen if an AI action was checked or executed, and that action made use of an aspect or goal that was implemented in Lua.
  • Loading branch information
CelticMinstrel committed Mar 24, 2016
1 parent cccf1f8 commit 18b1356
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
26 changes: 23 additions & 3 deletions src/ai/lua/core.cpp
Expand Up @@ -1046,8 +1046,23 @@ lua_ai_action_handler* lua_ai_action_handler::create(lua_State *L, char const *c

int lua_ai_load::refcount = 0;

lua_ai_load::lua_ai_load(lua_ai_context& ctx, bool read_only) : L(ctx.L)
lua_ai_load::lua_ai_load(lua_ai_context& ctx, bool read_only) : L(ctx.L), was_readonly(false)
{
refcount++;
// Check if the AI table is already loaded. If so, we have less work to do.
lua_getglobal(L, "ai");
if(!lua_isnoneornil(L, -1)) {
// Save the previous read-only state
lua_getfield(L, -1, "read_only");
was_readonly = luaW_toboolean(L, -1);
lua_pop(L, 1);
// Update the read-only state
lua_pushstring(L, "read_only");
lua_pushboolean(L, read_only);
lua_rawset(L, -3);
return; // Leave the AI table on the stack, as requested
}
lua_pop(L, 1); // Pop the nil value off the stack
lua_pushlightuserdata(L, static_cast<void *>(const_cast<char *>(&aisKey))); // [-1: key]
lua_rawget(L, LUA_REGISTRYINDEX); // [-1: AI registry]
lua_rawgeti(L, -1, ctx.num_); // [-1: AI state -2: AI registry]
Expand All @@ -1059,8 +1074,6 @@ lua_ai_load::lua_ai_load(lua_ai_context& ctx, bool read_only) : L(ctx.L)
lua_pushboolean(L, read_only); // [-1: value -2: key -3: AI functions -4: AI state]
lua_rawset(L, -3); // [-1: AI functions -2: AI state]
lua_setglobal(L, "ai"); // [-1: AI state]

refcount++;
}

lua_ai_load::~lua_ai_load()
Expand All @@ -1070,6 +1083,13 @@ lua_ai_load::~lua_ai_load()
// Remove the AI functions from the global scope
lua_pushnil(L);
lua_setglobal(L, "ai");
} else {
// Restore the read-only state
lua_getglobal(L, "ai");
lua_pushstring(L, "read_only");
lua_pushboolean(L, was_readonly);
lua_rawset(L, -3);
lua_pop(L, 1);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/ai/lua/core.hpp
Expand Up @@ -60,6 +60,7 @@ class lua_ai_load
lua_State* L;
static int refcount;
public:
bool was_readonly;
lua_ai_load(lua_ai_context& ctx, bool read_only);
~lua_ai_load();
};
Expand Down

0 comments on commit 18b1356

Please sign in to comment.