git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7477 c06c8d41-db1a-0410-9941-cceddc491573
JPFT2IRK2624J6QS72PSRMPYJQRIWSV567GFLC2JOJD7246XHOTAC EJ4GIPFSSQCQASUMRF4CR2WPUQOTEHFRGLOYEZ7BH6YEMIR6DN4QC GQL5SIGBHLU3FMCE54XVGLRY5AZHRM6DUEB722REA2DPLGJSN6EQC 7Y5HSDFKA5TPLS2TWTRFMQVX6UXUDHXU5MUMXQSDFAIY4THQ3BIQC YE7M665QKDGI7Y5WMERCWJNDZ4FUZ6GRUCK4E6GZH4SWCUM6RWLAC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC Q2FZIIGQECGP2FKKWLGDBBQVGCFZ4JTY53PFPJP6X7YKC23AQGFQC JDPJS5SNW6ZTY5DYV5QUBG2WVJ45FJ4CAOK6KDJKPEI2HLIHVLRQC W52PCSHX72WAMWKG6L4BPUBVMO6E72KYYBNKAA7554KNOTY6V7WQC // Remove the Lua marker table from the registry.if (initialised){lua_pushlightuserdata(dlua, this);lua_pushnil(dlua);lua_settable(dlua, LUA_REGISTRYINDEX);}
// First save the unmarshall Lua function.lua_pushlightuserdata(dlua, const_cast<map_lua_marker*>(this));lua_gettable(dlua, LUA_REGISTRYINDEX);return (lua_istable(dlua, -1));
if (marker_table.get()){marker_table->push();return (lua_istable(dlua, -1));}else{return (false);}
class lua_shutdown_listener{public:virtual void shutdown(CLua &lua) = 0;};// A convenience class to keep a reference to a lua object on the stack.// This is useful to hang on to things that cannot be directly retrieved by// C++ code, such as Lua function references.class lua_datum : public lua_shutdown_listener{public:lua_datum(CLua &lua, int stackpos = -1, bool pop = true);lua_datum(const lua_datum &other);void shutdown(CLua &lua);
// Copy the listener vector, because listeners may remove// themselves from the listener list when we notify them of a// shutdown.const std::vector<lua_shutdown_listener*> slisteners = shutdown_listeners;for (int i = 0, size = slisteners.size(); i < size; ++i)slisteners[i]->shutdown(*this);
}void CLua::add_shutdown_listener(lua_shutdown_listener *listener){if (std::find(shutdown_listeners.begin(), shutdown_listeners.end(),listener) == shutdown_listeners.end())shutdown_listeners.push_back(listener);}void CLua::remove_shutdown_listener(lua_shutdown_listener *listener){std::vector<lua_shutdown_listener*>::iterator i =std::find(shutdown_listeners.begin(), shutdown_listeners.end(),listener);if (i != shutdown_listeners.end())shutdown_listeners.erase(i);
}/////////////////////////////////////////////////////////////////////lua_datum::lua_datum(CLua &_lua, int stackpos, bool pop): need_cleanup(true), lua(_lua){// Store the datum in the registry indexed by "this".lua_pushvalue(lua, stackpos);lua_pushlightuserdata(lua, this);// Move the key (this) before the value.lua_insert(lua, -2);lua_settable(lua, LUA_REGISTRYINDEX);if (pop && stackpos < 0)lua_pop(lua, -stackpos);lua.add_shutdown_listener(this);}lua_datum::lua_datum(const lua_datum &o): need_cleanup(true), lua(o.lua){lua_pushlightuserdata(lua, this);o.push();lua_settable(lua, LUA_REGISTRYINDEX);lua.add_shutdown_listener(this);}void lua_datum::push() const{lua_pushlightuserdata(lua, const_cast<lua_datum*>(this));lua_gettable(lua, LUA_REGISTRYINDEX);// The value we saved is now on top of the Lua stack.}lua_datum::~lua_datum(){cleanup();
void lua_datum::shutdown(CLua &){cleanup();}void lua_datum::cleanup(){if (need_cleanup){need_cleanup = false;lua.remove_shutdown_listener(this);lua_pushlightuserdata(lua, this);lua_pushnil(lua);lua_settable(lua, LUA_REGISTRYINDEX);}}