diff options
Diffstat (limited to 'engines/sword25/script/luascript.cpp')
-rw-r--r-- | engines/sword25/script/luascript.cpp | 328 |
1 files changed, 144 insertions, 184 deletions
diff --git a/engines/sword25/script/luascript.cpp b/engines/sword25/script/luascript.cpp index a497151776..22d2a28072 100644 --- a/engines/sword25/script/luascript.cpp +++ b/engines/sword25/script/luascript.cpp @@ -38,6 +38,8 @@ // Includes // ----------------------------------------------------------------------------- +//namespace { + extern "C" { #include "sword25/util/lua/lua.h" @@ -46,6 +48,8 @@ extern "C" #include "sword25/util/pluto/pluto.h" } +//} + #include "sword25/package/packagemanager.h" #include "sword25/script/luascript.h" #include "sword25/script/luabindhelper.h" @@ -53,41 +57,35 @@ extern "C" #include "sword25/kernel/outputpersistenceblock.h" #include "sword25/kernel/inputpersistenceblock.h" -#include "sword25/kernel/memlog_off.h" -#include <vector> -#include "sword25/kernel/memlog_on.h" +namespace Sword25 { using namespace std; // ----------------------------------------------------------------------------- -// Konstruktion / Destruktion +// Constructor / Destructor // ----------------------------------------------------------------------------- -BS_LuaScriptEngine::BS_LuaScriptEngine(BS_Kernel * KernelPtr) : +BS_LuaScriptEngine::BS_LuaScriptEngine(BS_Kernel *KernelPtr) : BS_ScriptEngine(KernelPtr), m_State(0), - m_PcallErrorhandlerRegistryIndex(0) -{ + m_PcallErrorhandlerRegistryIndex(0) { } // ----------------------------------------------------------------------------- -BS_LuaScriptEngine::~BS_LuaScriptEngine() -{ - // Lua deinitialisieren +BS_LuaScriptEngine::~BS_LuaScriptEngine() { + // Lua de-initialisation if (m_State) lua_close(m_State); } // ----------------------------------------------------------------------------- -BS_Service * BS_LuaScriptEngine_CreateObject(BS_Kernel * KernelPtr) { return new BS_LuaScriptEngine(KernelPtr); } +BS_Service *BS_LuaScriptEngine_CreateObject(BS_Kernel * KernelPtr) { return new BS_LuaScriptEngine(KernelPtr); } // ----------------------------------------------------------------------------- -namespace -{ - int PanicCB(lua_State * L) - { +namespace { + int PanicCB(::lua_State *L) { BS_LOG_ERRORLN("Lua panic. Error message: %s", lua_isnil(L, -1) ? "" : lua_tostring(L, -1)); return 0; } @@ -95,50 +93,46 @@ namespace // ----------------------------------------------------------------------------- -bool BS_LuaScriptEngine::Init() -{ - // Lua-State intialisieren und Standardbibliotheken initialisieren +bool BS_LuaScriptEngine::Init() { + // Lua-State initialisation, as well as standard libaries initialisation m_State = luaL_newstate(); - if (!m_State || ! RegisterStandardLibs() || !RegisterStandardLibExtensions()) - { + if (!m_State || ! RegisterStandardLibs() || !RegisterStandardLibExtensions()) { BS_LOG_ERRORLN("Lua could not be initialized."); return false; } - // Panic-Callbackfunktion registrieren. + // Register panic callback function lua_atpanic(m_State, PanicCB); - // Errorhandlerfunktion für lua_pcall-Aufrufe. - // Der untenstehende Code enthält eine lokale ErrorHandler-Funktion und gibt diese zurück. + // Error handler for lua_pcall calls + // The code below contains a local error handler function const char ErrorHandlerCode[] = "local function ErrorHandler(message) " " return message .. '\\n' .. debug.traceback('', 2) " "end " "return ErrorHandler"; - // Den Code compilieren. - if (luaL_loadbuffer(m_State, ErrorHandlerCode, strlen(ErrorHandlerCode), "PCALL ERRORHANDLER") != 0) - { - // Fehlernachricht ausgeben und Methode beenden. + // Compile the code + if (luaL_loadbuffer(m_State, ErrorHandlerCode, strlen(ErrorHandlerCode), "PCALL ERRORHANDLER") != 0) { + // An error occurred, so dislay the reason and exit BS_LOG_ERRORLN("Couldn't compile luaL_pcall errorhandler:\n%s", lua_tostring(m_State, -1)); lua_pop(m_State, 1); return false; } - // Den Code ausführen, dies legt die Errorhandler-Funktion oben auf den Stack. - if (lua_pcall(m_State, 0, 1, 0) != 0) - { - // Fehlernachricht ausgeben und Methode beenden. + // Running the code, the error handler function sets the top of the stack + if (lua_pcall(m_State, 0, 1, 0) != 0) { + // An error occurred, so dislay the reason and exit BS_LOG_ERRORLN("Couldn't prepare luaL_pcall errorhandler:\n%s", lua_tostring(m_State, -1)); lua_pop(m_State, 1); return false; } - // Die Errorhandler-Funktion in der Lua-Registry ablegen und den Index merken. + // Place the error handler function in the Lua registry, and remember the index m_PcallErrorhandlerRegistryIndex = luaL_ref(m_State, LUA_REGISTRYINDEX); - // Die Pluto Persistenz-Bibliothek initialisieren. + // Initialise the Pluto-Persistence library luaopen_pluto(m_State); lua_pop(m_State, 1); @@ -149,21 +143,19 @@ bool BS_LuaScriptEngine::Init() // ----------------------------------------------------------------------------- -bool BS_LuaScriptEngine::ExecuteFile(const std::string & FileName) -{ +bool BS_LuaScriptEngine::ExecuteFile(const Common::String &FileName) { #ifdef DEBUG int __startStackDepth = lua_gettop(m_State); #endif - // Pointer auf den Packagemanager holen - BS_PackageManager * pPackage = static_cast<BS_PackageManager *>(BS_Kernel::GetInstance()->GetService("package")); + // Get a pointer to the package manager + BS_PackageManager *pPackage = static_cast<BS_PackageManager *>(BS_Kernel::GetInstance()->GetService("package")); BS_ASSERT(pPackage); - // Datei einlesen + // File read unsigned int FileSize; - char * FileData = static_cast<char *>(pPackage->GetFile(FileName, &FileSize)); - if (!FileData) - { + char *FileData = static_cast<char *>(pPackage->GetFile(FileName, &FileSize)); + if (!FileData) { BS_LOG_ERRORLN("Couldn't read \"%s\".", FileName.c_str()); #ifdef DEBUG BS_ASSERT(__startStackDepth == lua_gettop(m_State)); @@ -171,10 +163,9 @@ bool BS_LuaScriptEngine::ExecuteFile(const std::string & FileName) return false; } - // Dateiinhalt ausführen - if (!ExecuteBuffer(FileData, FileSize, "@" + pPackage->GetAbsolutePath(FileName))) - { - // Dateipuffer freigeben + // Run the file content + if (!ExecuteBuffer(FileData, FileSize, "@" + pPackage->GetAbsolutePath(FileName))) { + // Release file buffer delete[] FileData; #ifdef DEBUG BS_ASSERT(__startStackDepth == lua_gettop(m_State)); @@ -182,7 +173,7 @@ bool BS_LuaScriptEngine::ExecuteFile(const std::string & FileName) return false; } - // Dateipuffer freigeben + // Release file buffer delete[] FileData; #ifdef DEBUG @@ -194,26 +185,22 @@ bool BS_LuaScriptEngine::ExecuteFile(const std::string & FileName) // ----------------------------------------------------------------------------- -bool BS_LuaScriptEngine::ExecuteString(const std::string & Code) -{ - return ExecuteBuffer(Code.c_str(), Code.length(), "???"); +bool BS_LuaScriptEngine::ExecuteString(const Common::String &Code) { + return ExecuteBuffer(Code.c_str(), Code.size(), "???"); } // ----------------------------------------------------------------------------- -namespace -{ - void RemoveForbiddenFunctions(lua_State * L) - { - static const char * FORBIDDEN_FUNCTIONS[] = - { +namespace { + + void RemoveForbiddenFunctions(::lua_State *L) { + static const char *FORBIDDEN_FUNCTIONS[] = { "dofile", 0 }; const char ** Iterator = FORBIDDEN_FUNCTIONS; - while (*Iterator) - { + while (*Iterator) { lua_pushnil(L); lua_setfield(L, LUA_GLOBALSINDEX, *Iterator); ++Iterator; @@ -221,8 +208,7 @@ namespace } } -bool BS_LuaScriptEngine::RegisterStandardLibs() -{ +bool BS_LuaScriptEngine::RegisterStandardLibs() { luaL_openlibs(m_State); RemoveForbiddenFunctions(m_State); return true; @@ -230,24 +216,21 @@ bool BS_LuaScriptEngine::RegisterStandardLibs() // ----------------------------------------------------------------------------- -bool BS_LuaScriptEngine::ExecuteBuffer(const char * Data, unsigned int Size, const std::string & Name) const -{ - // Puffer kompilieren - if (luaL_loadbuffer(m_State, Data, Size, Name.c_str()) != 0) - { +bool BS_LuaScriptEngine::ExecuteBuffer(const char *Data, unsigned int Size, const Common::String &Name) const { + // Compile buffer + if (luaL_loadbuffer(m_State, Data, Size, Name.c_str()) != 0) { BS_LOG_ERRORLN("Couldn't compile \"%s\":\n%s", Name.c_str(), lua_tostring(m_State, -1)); lua_pop(m_State, 1); return false; } - // Error-Handler Funktion hinter der auszuführenden Funktion auf den Stack legen. + // Error handling function to be executed after the function is put on the stack lua_rawgeti(m_State, LUA_REGISTRYINDEX, m_PcallErrorhandlerRegistryIndex); lua_insert(m_State, -2); - // Pufferinhalt ausführen - if (lua_pcall(m_State, 0, 0, -2) != 0) - { + // Run buffer contents + if (lua_pcall(m_State, 0, 0, -2) != 0) { BS_LOG_ERRORLN("An error occured while executing \"%s\":\n%s.", Name.c_str(), lua_tostring(m_State, -1)); @@ -256,7 +239,7 @@ bool BS_LuaScriptEngine::ExecuteBuffer(const char * Data, unsigned int Size, con return false; } - // Error-Handler Funktion vom Stack nehmen. + // Remove the error handler function from the stack lua_pop(m_State, 1); return true; @@ -264,12 +247,10 @@ bool BS_LuaScriptEngine::ExecuteBuffer(const char * Data, unsigned int Size, con // ----------------------------------------------------------------------------- -void BS_LuaScriptEngine::SetCommandLine(const vector<string> & CommandLineParameters) -{ +void BS_LuaScriptEngine::SetCommandLine(const Common::StringArray &CommandLineParameters) { lua_newtable(m_State); - for (size_t i = 0; i < CommandLineParameters.size(); ++i) - { + for (size_t i = 0; i < CommandLineParameters.size(); ++i) { lua_pushnumber(m_State, i + 1); lua_pushstring(m_State, CommandLineParameters[i].c_str()); lua_settable(m_State, -3); @@ -280,15 +261,13 @@ void BS_LuaScriptEngine::SetCommandLine(const vector<string> & CommandLineParame // ----------------------------------------------------------------------------- -namespace -{ - const char * PERMANENTS_TABLE_NAME = "Permanents"; +namespace { + const char *PERMANENTS_TABLE_NAME = "Permanents"; // ------------------------------------------------------------------------- - // Diese Array enthält die Namen der globalen Lua-Objekte, die nicht persistiert werden sollen. - const char * STANDARD_PERMANENTS[] = - { + // This array contains the name of global Lua objects that should not be persisted + const char *STANDARD_PERMANENTS[] = { "string", "xpcall", "package", @@ -340,93 +319,87 @@ namespace // ------------------------------------------------------------------------- - enum PERMANENT_TABLE_TYPE - { + enum PERMANENT_TABLE_TYPE { PTT_PERSIST, PTT_UNPERSIST }; // ------------------------------------------------------------------------- - bool PushPermanentsTable(lua_State * L, PERMANENT_TABLE_TYPE TableType) - { - // Permanents-Tabelle erstellen. + bool PushPermanentsTable(::lua_State *L, PERMANENT_TABLE_TYPE TableType) { + // Permanents-Table lua_newtable(L); - // Alle Standard-Permanents in die Tabelle einfügen. + // All standard permanents are inserted into this table unsigned int Index = 0; - while (STANDARD_PERMANENTS[Index]) - { - // Permanent auf den Stack legen, falls es nicht existiert, wird es einfach ignoriert. + while (STANDARD_PERMANENTS[Index]) { + // Permanents are placed onto the stack; if it does not exist, it is simply ignored lua_getglobal(L, STANDARD_PERMANENTS[Index]); - if (!lua_isnil(L, -1)) - { - // Namen des Elementes als einzigartigen Wert auf den Stack legen. + if (!lua_isnil(L, -1)) { + // Name of the element as a unique value on the stack lua_pushstring(L, STANDARD_PERMANENTS[Index]); - // Falls geladen wird, ist der Name der Index und das Objekt der Wert. - // In diesem Fall müssen also die Position von Name und Objekt auf dem Stack vertauscht werden. + // If it is loaded, then it can be used + // In this case, the position of name and object are reversed on the stack if (TableType == PTT_UNPERSIST) lua_insert(L, -2); - // Eintrag in der Tabelle vornehmen. + // Make an entry in the table lua_settable(L, -3); } - else - { - // nil von Stack poppen. + else { + // Pop nil value from stack lua_pop(L, 1); } ++Index; } - // Alle Registrierten C-Funktionen in die Tabelle einfügen. - // BS_LuaBindhelper legt in der Registry eine Tabelle an, in der alle registrierten C-Funktionen gespeichert werden. + // All registered C functions to be inserted into the table + // BS_LuaBindhelper places in the register a table in which all registered C functions + // are stored - // Tabelle mit den C-Permanents auf den Stack legen. + // Table is put on the stack lua_getfield(L, LUA_REGISTRYINDEX, PERMANENTS_TABLE_NAME); - if (!lua_isnil(L, -1)) - { - // Über alle Elemente der Tabelle iterieren. + if (!lua_isnil(L, -1)) { + // Iterate over all elements of the table lua_pushnil(L); - while (lua_next(L, -2) != 0) - { - // Wert und Index auf dem Stack duplizieren und in der Reihenfolge vertauschen. + while (lua_next(L, -2) != 0) { + // Value and index duplicated on the stack and changed in the sequence lua_pushvalue(L, -1); lua_pushvalue(L, -3); - // Falls geladen wird, ist der Name der Index und das Objekt der Wert. - // In diesem Fall müssen also die Position von Name und Objekt auf dem Stack vertauscht werden. + // If it is loaded, then it can be used + // In this case, the position of name and object are reversed on the stack if (TableType == PTT_UNPERSIST) lua_insert(L, -2); - // Eintrag in der Ergebnistabelle vornehmen. + // Make an entry in the results table lua_settable(L, -6); - // Wert vom Stack poppen. Der Index liegt dann oben für den nächsten Aufruf von lua_next(). + // Pop value from the stack. The index is then ready for the next call to lua_next() lua_pop(L, 1); } } - // Tabelle mit den C-Permanents vom Stack poppen. + // Pop the C-Permanents table from the stack lua_pop(L, 1); - // coroutine.yield muss extra in die Permanents-Tabelle eingetragen werden, da inaktive Coroutinen diese C-Funktion auf dem Stack liegen - // haben. + // coroutine.yield must be registered in the extra-Permanents table because they + // are inactive coroutine C functions on the stack - // Funktion coroutine.yield auf den Stack legen. + // Function coroutine.yield placed on the stack lua_getglobal(L, "coroutine"); lua_pushstring(L, "yield"); lua_gettable(L, -2); - // coroutine.yield mit eigenem eindeutigen Wert in der Permanents-Tabelle ablegen. + // Store coroutine.yield with it's own unique value in the Permanents table lua_pushstring(L, "coroutine.yield"); if (TableType == PTT_UNPERSIST) lua_insert(L, -2); lua_settable(L, -4); - // Tabelle coroutine vom Stack poppen. + // Coroutine table is popped from the stack lua_pop(L, 1); return true; @@ -435,33 +408,30 @@ namespace // ----------------------------------------------------------------------------- -namespace -{ - int Chunkwriter(lua_State *L, const void* p, size_t sz, void* ud) - { +namespace { + int Chunkwriter(::lua_State *L, const void *p, size_t sz, void *ud) { vector<unsigned char> & chunkData = *reinterpret_cast<vector<unsigned char> * >(ud); - const unsigned char * buffer = reinterpret_cast<const unsigned char *>(p); + const unsigned char *buffer = reinterpret_cast<const unsigned char *>(p); - while (sz--) chunkData.push_back(*buffer++); + while (sz--) chunkData.push_back(*buffer++) ; return 1; } } -bool BS_LuaScriptEngine::Persist(BS_OutputPersistenceBlock & Writer) -{ - // Den Lua-Stack leeren. pluto_persist() erwartet, dass der Stack bis aus seine Parameter leer ist. +bool BS_LuaScriptEngine::Persist(BS_OutputPersistenceBlock &Writer) { + // Empty the Lua stack. pluto_persist() xepects that the stack is empty except for its parameters lua_settop(m_State, 0); // Garbage Collection erzwingen. lua_gc(m_State, LUA_GCCOLLECT, 0); - // Permanents-Tabelle und die zu persistierende Tabelle auf den Stack legen. - // pluto_persist erwartet diese beiden Objekte auf dem Lua-Stack. + // Permanents-Table is set on the stack + // pluto_persist expects these two items on the Lua stack PushPermanentsTable(m_State, PTT_PERSIST); lua_getglobal(m_State, "_G"); - // Lua persistieren und die Daten in einem vector ablegen. + // Lua persists and stores the data in a vector vector<unsigned char> chunkData; pluto_persist(m_State, Chunkwriter, &chunkData); @@ -476,114 +446,104 @@ bool BS_LuaScriptEngine::Persist(BS_OutputPersistenceBlock & Writer) // ----------------------------------------------------------------------------- -namespace -{ +namespace { // ------------------------------------------------------------------------- - struct ChunkreaderData - { + struct ChunkreaderData { void * BufferPtr; size_t Size; bool BufferReturned; }; - // ------------------------------------------------------------------------- + // ------------------------------------------------------------------------ - const char * Chunkreader(lua_State *L, void *ud, size_t *sz) - { + const char *Chunkreader(::lua_State *L, void *ud, size_t *sz) { ChunkreaderData & cd = *reinterpret_cast<ChunkreaderData *>(ud); - if (!cd.BufferReturned) - { + if (!cd.BufferReturned) { cd.BufferReturned = true; *sz = cd.Size; return reinterpret_cast<const char *>(cd.BufferPtr); - } - else - { + } else { return 0; } } // ------------------------------------------------------------------------- - void ClearGlobalTable(lua_State * L, const char ** Exceptions) - { - // Über alle Elemente der globalen Tabelle iterieren. + void ClearGlobalTable(::lua_State *L, const char **Exceptions) { + // Iterate over all elements of the global table lua_pushvalue(L, LUA_GLOBALSINDEX); lua_pushnil(L); - while (lua_next(L, -2) != 0) - { - // Jetzt liegen der Wert und der Index des aktuellen Elementes auf dem Stack. - // Der Wert interessiert uns nicht, daher wird er vom Stack gepoppt. + while (lua_next(L, -2) != 0) { + // Now the value and the index of the current element is on the stack + // This value does not interest us, so it is popped from the stack lua_pop(L, 1); - // Feststellen, ob das Element auf nil gesetzt , also aus der globalen Tabelle entfernt werden soll. - // Hierfür wird geprüft, ob das Elementname ein String ist und in der Liste der Ausnahmen vorkommt. + // Determine whether the item is set to nil, so you want to remove from the global table. + // For this will determine whether the element name is a string and is present in + // the list of exceptions bool SetElementToNil = true; - if (lua_isstring(L, -1)) - { - const char * IndexString = lua_tostring(L, -1); + if (lua_isstring(L, -1)) { + const char *IndexString = lua_tostring(L, -1); const char ** ExceptionsWalker = Exceptions; - while (*ExceptionsWalker) - { + while (*ExceptionsWalker) { if (strcmp(IndexString, *ExceptionsWalker) == 0) SetElementToNil = false; ++ExceptionsWalker; } } - // Wenn der obige Test ergeben hat, dass das Element entfernt werden soll, wird es entfernt indem der Wert auf nil gesetzt wird. - if (SetElementToNil) - { + // If the above test showed that the item should be removed, it is removed by setting the value to nil. + if (SetElementToNil) { lua_pushvalue(L, -1); lua_pushnil(L); lua_settable(L, LUA_GLOBALSINDEX); } } - // Globale Tabelle vom Stack nehmen. + // Pop the Global table from the stack lua_pop(L, 1); - // Garbage-Collection vornehmen, damit die entfernten Elemente alle gelöscht werden. + // Perform garbage collection, so that all removed elements are deleted lua_gc(L, LUA_GCCOLLECT, 0); } } // ----------------------------------------------------------------------------- -bool BS_LuaScriptEngine::Unpersist(BS_InputPersistenceBlock & Reader) -{ - // Den Lua-Stack leeren. pluto_unpersist() erwartet, dass der Stack bis aus seine Parameter leer ist. +bool BS_LuaScriptEngine::Unpersist(BS_InputPersistenceBlock &Reader) { + // Empty the Lua stack. pluto_persist() xepects that the stack is empty except for its parameters lua_settop(m_State, 0); - // Permanents Tabelle auf den Stack legen. Dies passiert schon an dieser Stelle, da zum Erstellen der Tabelle alle Permanents zugreifbar sein - // müssen. Dies ist nur am Anfang dieser Funktion der Fall, im Folgenden wird die globale Tabelle geleert. + // Permanents table is placed on the stack. This has already happened at this point, because + // to create the table all permanents must be accessible. This is the case only for the + // beginning of the function, because the global table is emptied below PushPermanentsTable(m_State, PTT_UNPERSIST); - // Alle Elemente aus der globalen Tabelle mit Ausnhame von _G und __METATABLES entfernen. - // Danach wird eine Garbage Collection durchgeführt und somit alle von Lua verwalteten Objekte gelöscht. - // __METATABLES wird zunächst nicht entfernt, da die Metatables für die Finalizer der Objekte benötigt werden. - static const char * ClearExceptionsFirstPass[] = - { + // All items from global table of _G and __METATABLES are removed. + // After a garbage collection is performed, and thus all managed objects deleted + + // __METATABLES is not immediately removed becausen the Metatables are needed + // for the finalisers of objects. + static const char *ClearExceptionsFirstPass[] = { "_G", "__METATABLES", 0 }; ClearGlobalTable(m_State, ClearExceptionsFirstPass); - // Im zweiten Durchgang werden auch die Metatables entfernt. - static const char * ClearExceptionsSecondPass[] = - { + // In the second pass, the Metatables are removed + static const char *ClearExceptionsSecondPass[] = { "_G", 0 }; ClearGlobalTable(m_State, ClearExceptionsSecondPass); - // Persistierte Lua-Daten einlesen. + // Persisted Lua data vector<unsigned char> chunkData; Reader.Read(chunkData); - // Chunk-Reader initialisieren. Er wird von pluto_unpersist benutzt um die benötigten Daten einzulesen. + // Chunk-Reader initialisation. It is used with pluto_unpersist to restore read data ChunkreaderData cd; cd.BufferPtr = &chunkData[0]; cd.Size = chunkData.size(); @@ -591,32 +551,32 @@ bool BS_LuaScriptEngine::Unpersist(BS_InputPersistenceBlock & Reader) pluto_unpersist(m_State, Chunkreader, &cd); - // Permanents-Tabelle vom Stack nehmen. + // Permanents-Table is removed from stack lua_remove(m_State, -2); - // Die eingelesenen Elemente in die globale Tabelle eintragen. + // The read elements in the global table about lua_pushnil(m_State); - while (lua_next(m_State, -2) != 0) - { - // Die Referenz auf die globale Tabelle (_G) darf nicht überschrieben werden, sonst tickt Lua total aus. + while (lua_next(m_State, -2) != 0) { + // The referenec to the global table (_G) must not be overwritten, or ticks from Lua total bool IsGlobalReference = lua_isstring(m_State, -2) && strcmp(lua_tostring(m_State, -2), "_G") == 0; - if (!IsGlobalReference) - { + if (!IsGlobalReference) { lua_pushvalue(m_State, -2); lua_pushvalue(m_State, -2); lua_settable(m_State, LUA_GLOBALSINDEX); } - // Wert vom Stack poppen. Der Index liegt dann oben für den nächsten Aufruf von lua_next(). + // Pop value from the stack. The index is then ready for the next call to lua_next() lua_pop(m_State, 1); } - // Tabelle mit den geladenen Daten vom Stack poppen. + // The table with the loaded data is popped from the stack lua_pop(m_State, 1); - // Garbage Collection erzwingen. + // Force garbage collection lua_gc(m_State, LUA_GCCOLLECT, 0); return true; } + +} // End of namespace Sword25 |