diff options
author | Thorbjørn Lindeijer <thorbjorn@lindeijer.nl> | 2012-02-02 22:42:09 +0100 |
---|---|---|
committer | Thorbjørn Lindeijer <thorbjorn@lindeijer.nl> | 2012-02-03 20:54:20 +0100 |
commit | 55d2cf8c86df8655fd826443ebe34b1005a9cf90 (patch) | |
tree | d5f06084ffac68074963e2038fe0dd8b2c995e18 /src/scripting/luautil.cpp | |
parent | 48d44a13e525375ef289ef577e5fc6abf1735e19 (diff) | |
download | manaserv-55d2cf8c86df8655fd826443ebe34b1005a9cf90.tar.gz manaserv-55d2cf8c86df8655fd826443ebe34b1005a9cf90.tar.bz2 manaserv-55d2cf8c86df8655fd826443ebe34b1005a9cf90.tar.xz manaserv-55d2cf8c86df8655fd826443ebe34b1005a9cf90.zip |
Added a generic Lua user data cache
Based on a native Lua table with weak values, so that the user data objects
that are created can be garbage collected when no longer referenced.
Reviewed-by: Yohann Ferreira
Diffstat (limited to 'src/scripting/luautil.cpp')
-rw-r--r-- | src/scripting/luautil.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/scripting/luautil.cpp b/src/scripting/luautil.cpp index b7680c6b..7580ac21 100644 --- a/src/scripting/luautil.cpp +++ b/src/scripting/luautil.cpp @@ -51,6 +51,65 @@ void raiseWarning(lua_State *, const char *format, ...) LOG_WARN("Lua script error: "<< message); } + +char UserDataCache::mRegistryKey; + +bool UserDataCache::retrieve(lua_State *s, void *object) +{ + // Retrieve the cache table + lua_pushlightuserdata(s, &mRegistryKey); // key + lua_rawget(s, LUA_REGISTRYINDEX); // Cache? + + if (lua_isnil(s, -1)) + { + lua_pop(s, 1); + return false; + } + + lua_pushlightuserdata(s, object); // Cache, object + lua_rawget(s, -2); // Cache, UD? + + if (lua_isnil(s, -1)) + { + lua_pop(s, 2); // ... + return false; + } + + lua_replace(s, -2); // UD + return true; +} + +void UserDataCache::insert(lua_State *s, void *object) +{ + // Retrieve the cache table + lua_pushlightuserdata(s, &mRegistryKey); // UD, key + lua_rawget(s, LUA_REGISTRYINDEX); // UD, Cache? + + // Create the cache when it doesn't exist yet + if (lua_isnil(s, -1)) + { + lua_pop(s, 1); // UD + lua_newtable(s); // UD, Cache + + // The metatable that makes the values in the table above weak + lua_newtable(s); // UD, Cache, {} + lua_pushstring(s, "__mode"); + lua_pushstring(s, "v"); + lua_rawset(s, -3); // UD, Cache, { __mode = "v" } + lua_setmetatable(s, -2); // UD, Cache + + lua_pushlightuserdata(s, &mRegistryKey);// UD, Cache, key + lua_pushvalue(s, -2); // UD, Cache, key, Cache + lua_rawset(s, LUA_REGISTRYINDEX); // UD, Cache + } + + lua_pushlightuserdata(s, object); // UD, Cache, object + lua_pushvalue(s, -3); // UD, Cache, object, UD + lua_rawset(s, -3); // UD, Cache { object = UD } + lua_pop(s, 1); // UD +} + + /* Functions below are unsafe, as they assume the script has passed pointers to objects which have not yet been destroyed. If the script never keeps pointers around, there will be no problem. In order to be safe, the engine |