diff options
author | Paul Gilbert | 2010-08-01 01:49:06 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2010-10-12 22:16:21 +0000 |
commit | 2d8e94e4ff71cefb9822732741bc7eb1a9116e07 (patch) | |
tree | 25d3e5c93e475ceb62f25869b25724270aef899c /engines/sword25/script/luabindhelper.cpp | |
parent | ea29e41b86dd6efad5b044220505ded798b2503e (diff) | |
download | scummvm-rg350-2d8e94e4ff71cefb9822732741bc7eb1a9116e07.tar.gz scummvm-rg350-2d8e94e4ff71cefb9822732741bc7eb1a9116e07.tar.bz2 scummvm-rg350-2d8e94e4ff71cefb9822732741bc7eb1a9116e07.zip |
SWORD25: Converted Lua interface classes
svn-id: r53195
Diffstat (limited to 'engines/sword25/script/luabindhelper.cpp')
-rw-r--r-- | engines/sword25/script/luabindhelper.cpp | 285 |
1 files changed, 147 insertions, 138 deletions
diff --git a/engines/sword25/script/luabindhelper.cpp b/engines/sword25/script/luabindhelper.cpp index 79c7f21efc..06e97ad2e2 100644 --- a/engines/sword25/script/luabindhelper.cpp +++ b/engines/sword25/script/luabindhelper.cpp @@ -39,97 +39,99 @@ #include "sword25/kernel/kernel.h" #include "sword25/script/luabindhelper.h" #include "sword25/script/luascript.h" -#include <sstream> #define BS_LOG_PREFIX "LUABINDHELPER" // ----------------------------------------------------------------------------- -namespace -{ +namespace { const char * METATABLES_TABLE_NAME = "__METATABLES"; const char * PERMANENTS_TABLE_NAME = "Permanents"; - bool RegisterPermanent(lua_State * L, const std::string & Name) - { - // Eine C-Funktion muss auf dem Stack liegen. + bool RegisterPermanent(::lua_State *L, const Common::String &Name) { + // A C function has to be on the stack if (!lua_iscfunction(L, -1)) return false; - // Sicherstellen, dass die Permanents-Tabelle oben auf dem Stack liegt. + // Make sure that the Permanents-Table is on top of the stack lua_getfield(L, LUA_REGISTRYINDEX, PERMANENTS_TABLE_NAME); - if (lua_isnil(L, -1)) - { - // Permanents-Tabelle existiert noch nicht, sie muss erstellt werden. + if (lua_isnil(L, -1)) { + // Permanents-Table does not yet exist, so it has to be created - // Nil vom Stack poppen. + // Pop nil from the stack lua_pop(L, 1); - // Permanents-Tabelle erstellen und eine zweite Referenz darauf auf den Stack legen. + // Create Permanents-Table and insert a second reference to it on the stack lua_newtable(L); lua_pushvalue(L, -1); - // Permanents-Tabelle in der Registry speichern. Die zweite Referenz verbleibt auf dem Stack um im Anschluss benutzt zu werden. + // Store the Permanents-Table in the registry. The second reference is left + // on the stack to be used in the connection lua_setfield(L, LUA_REGISTRYINDEX, PERMANENTS_TABLE_NAME); } - // C-Funktion mit dem Namen als Index in der Permanents-Tabelle ablegen. + // C function with the name of an index in the Permanents-Table lua_insert(L, -2); lua_setfield(L, -2, Name.c_str()); - // Permanents-Tabelle vom Stack nehmen. + // Remove the Permanents-Table from the stack lua_pop(L, 1); return true; } } +namespace Sword25 { + // ----------------------------------------------------------------------------- -bool BS_LuaBindhelper::AddFunctionsToLib(lua_State * L, const std::string & LibName, const luaL_reg * Functions) -{ +/** + * Registers a set of functions into a Lua library. + * @param L A pointer to the Lua VM + * @param LibName The name of the library. + * If this is an empty string, the functions will be added to the global namespace. + * @param Functions An array of function pointers along with their names. + * The array must be terminated with the enry (0, 0) + * @return Returns true if successful, otherwise false. + */ +bool BS_LuaBindhelper::AddFunctionsToLib(::lua_State *L, const Common::String &LibName, const luaL_reg *Functions) { #ifdef DEBUG int __startStackDepth = lua_gettop(L); #endif - // Wenn der Tabellenname leer ist, werden die Funktionen zum globalen Namensraum hinzugefügt. - if (LibName.size() == 0) - { - for (; Functions->name; ++Functions) - { + // If the table name is empty, the functions are to be added to the global namespace + if (LibName.size() == 0) { + for (; Functions->name; ++Functions) { lua_pushstring(L, Functions->name); lua_pushcclosure(L, Functions->func, 0); lua_settable(L, LUA_GLOBALSINDEX); - // Funktion als permanent registrieren, damit sie beim Persistieren ignoriert wird. + // Function is being permanently registed, so persistence can be ignored lua_pushstring(L, Functions->name); lua_gettable(L, LUA_GLOBALSINDEX); RegisterPermanent(L, Functions->name); } } - // Wenn der Tabellenname nicht leer ist, werden die Funktionen zu dieser Tabelle hinzugefügt. - else - { - // Sicherstellen, dass die Library-Table existiert. + // If the table name is not empty, the functions are added to the given table + else { + // Ensure that the library table exists if (!_CreateTable(L, LibName)) return false; - // Die einzelnen Funktionen in der Table registrieren. - for (; Functions->name; ++Functions) - { - // Funktion registrieren. + // Register each function into the table + for (; Functions->name; ++Functions) { + // Function registration lua_pushstring(L, Functions->name); lua_pushcclosure(L, Functions->func, 0); lua_settable(L, -3); - // Funktion als permanent registrieren, damit sie beim Persistieren ignoriert wird. + // Function is being permanently registed, so persistence can be ignored lua_pushstring(L, Functions->name); lua_gettable(L, -2); RegisterPermanent(L, LibName + "." + Functions->name); } - // Library-Table vom Lua-Stack nehmen. + // Remove the library table from the Lua stack lua_pop(L, 1); } - #ifdef DEBUG BS_ASSERT(__startStackDepth == lua_gettop(L)); @@ -140,37 +142,41 @@ bool BS_LuaBindhelper::AddFunctionsToLib(lua_State * L, const std::string & LibN // ----------------------------------------------------------------------------- -bool BS_LuaBindhelper::AddConstantsToLib(lua_State * L, const std::string & LibName, const lua_constant_reg * Constants) -{ +/** + * Adds a set of constants to the Lua library + * @param L A pointer to the Lua VM + * @param LibName The name of the library. + * If this is an empty string, the functions will be added to the global namespace. + * @param Constants An array of the constant values along with their names. + * The array must be terminated with the enry (0, 0) + * @return Returns true if successful, otherwise false. + */ +bool BS_LuaBindhelper::AddConstantsToLib(::lua_State *L, const Common::String &LibName, const lua_constant_reg *Constants) { #ifdef DEBUG int __startStackDepth = lua_gettop(L); #endif - // Wenn der Tabellenname leer ist, werden die Konstanten zum globalen Namensraum hinzugefügt. - if (LibName.size() == 0) - { - for (; Constants->Name; ++Constants) - { + // If the table is empty, the constants are added to the global namespace + if (LibName.size() == 0) { + for (; Constants->Name; ++Constants) { lua_pushstring(L, Constants->Name); lua_pushnumber(L, Constants->Value); lua_settable(L, LUA_GLOBALSINDEX); } } - // Wenn der Tabellenname nicht leer ist, werden die Konstanten zu dieser Tabelle hinzugefügt. - else - { - // Sicherstellen, dass die Library-Table existiert. + // If the table name is nto empty, the constants are added to that table + else { + // Ensure that the library table exists if (!_CreateTable(L, LibName)) return false; - // Die einzelnen Konstanten in der Table registrieren - for (; Constants->Name; ++Constants) - { + // Register each constant in the table + for (; Constants->Name; ++Constants) { lua_pushstring(L, Constants->Name); lua_pushnumber(L, Constants->Value); lua_settable(L, -3); } - // Library-Tabelle vom Lua-Stack nehmen + // Remove the library table from the Lua stack lua_pop(L, 1); } @@ -183,29 +189,36 @@ bool BS_LuaBindhelper::AddConstantsToLib(lua_State * L, const std::string & LibN // ----------------------------------------------------------------------------- -bool BS_LuaBindhelper::AddMethodsToClass(lua_State * L, const std::string & ClassName, const luaL_reg * Methods) -{ +/** + * Adds a set of methods to a Lua class + * @param L A pointer to the Lua VM + * @param ClassName The name of the class + * When the class name specified does not exist, it is created. + * @param Methods An array of function pointers along with their method names. + * The array must be terminated with the enry (0, 0) + * @return Returns true if successful, otherwise false. + */ +bool BS_LuaBindhelper::AddMethodsToClass(::lua_State *L, const Common::String &ClassName, const luaL_reg *Methods) { #ifdef DEBUG int __startStackDepth = lua_gettop(L); #endif - // Metatable auf den Lua-Stack laden + // Load the metatable onto the Lua stack if (!GetMetatable(L, ClassName)) return false; - // Die einzelnen Methoden in der Metatable registrieren - for (; Methods->name; ++Methods) - { + // Register each method in the Metatable + for (; Methods->name; ++Methods) { lua_pushstring(L, Methods->name); lua_pushcclosure(L, Methods->func, 0); lua_settable(L, -3); - // Funktion als permanent registrieren, damit sie beim Persistieren ignoriert wird. + // Function is being permanently registed, so persistence can be ignored lua_pushstring(L, Methods->name); lua_gettable(L, -2); RegisterPermanent(L, ClassName + "." + Methods->name); } - // Metatable vom Lua-Stack nehmen + // Remove the metatable from the stack lua_pop(L, 1); #ifdef DEBUG @@ -217,26 +230,33 @@ bool BS_LuaBindhelper::AddMethodsToClass(lua_State * L, const std::string & Clas // ----------------------------------------------------------------------------- -bool BS_LuaBindhelper::SetClassGCHandler(lua_State * L, const std::string & ClassName, lua_CFunction GCHandler) -{ +/** + * Sets the garbage collector callback method when items of a particular class are deleted + * @param L A pointer to the Lua VM + * @param ClassName The name of the class + * When the class name specified does not exist, it is created. + * @param GCHandler A function pointer + * @return Returns true if successful, otherwise false. + */ +bool BS_LuaBindhelper::SetClassGCHandler(::lua_State *L, const Common::String &ClassName, lua_CFunction GCHandler) { #ifdef DEBUG int __startStackDepth = lua_gettop(L); #endif - // Metatable auf den Lua-Stack laden + // Load the metatable onto the Lua stack if (!GetMetatable(L, ClassName)) return false; - // Den GC-Handler in die Metatable schreiben + // Add the GC handler to the Metatable lua_pushstring(L, "__gc"); lua_pushcclosure(L, GCHandler, 0); lua_settable(L, -3); - // Funktion als permanent registrieren, damit sie beim Persistieren ignoriert wird. + // Function is being permanently registed, so persistence can be ignored lua_pushstring(L, "__gc"); lua_gettable(L, -2); RegisterPermanent(L, ClassName + ".__gc"); - // Metatable vom Lua-Stack nehmen + // Remove the metatable from the stack lua_pop(L, 1); #ifdef DEBUG @@ -246,22 +266,21 @@ bool BS_LuaBindhelper::SetClassGCHandler(lua_State * L, const std::string & Clas return true; } +} // End of namespace Sword25 + // ----------------------------------------------------------------------------- -namespace -{ - void PushMetatableTable(lua_State * L) - { - // Tabelle mit den Metatabellen auf den Stack legen. +namespace { + void PushMetatableTable(::lua_State *L) { + // Push the Metatable table onto the stack lua_getglobal(L, METATABLES_TABLE_NAME); - // Wenn die Tabelle noch nicht existiert, muss sie erstellt werden. - if (lua_isnil(L, -1)) - { - // nil vom Stack poppen. + // If the table doesn't yet exist, it must be created + if (lua_isnil(L, -1)) { + // Pop nil from stack lua_pop(L, 1); - // Neue Tabelle erstellen, in die globale Table eintragen und eine Referenz auf dem Stack lassen. + // New table has been created, so add it to the global table and leave reference on stack lua_newtable(L); lua_pushvalue(L, -1); lua_setglobal(L, METATABLES_TABLE_NAME); @@ -269,36 +288,35 @@ namespace } } +namespace Sword25 { -bool BS_LuaBindhelper::GetMetatable(lua_State * L, const std::string & TableName) -{ - // Tabelle mit den Metatabellen auf den Stack legen. +bool BS_LuaBindhelper::GetMetatable(::lua_State *L, const Common::String &TableName) { + // Push the Metatable table onto the stack PushMetatableTable(L); // Versuchen, die gewünschte Metatabelle auf den Stack zu legen. Wenn sie noch nicht existiert, muss sie erstellt werden. lua_getfield(L, -1, TableName.c_str()); - if (lua_isnil(L, -1)) - { - // nil vom Stack poppen. + if (lua_isnil(L, -1)) { + // Pop nil from stack lua_pop(L, 1); - // Neue Tabelle erstellen. + // Create new table lua_newtable(L); - // Das __index Feld der Metatabele zeigt auf die Metatabelle selbst. + // Set the __index field in the table lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); - // Persistfeld auf true setzen. Dies sorgt dafür, dass Objekte mit dieser Metatabelle direkt gespeichert werden. + // Flag the table as persisted. This ensures that objects within this table get stored lua_pushbooleancpp(L, true); lua_setfield(L, -2, "__persist"); - // Metatabelle in die Tabelle für Metatabellen eintragen und eine Referenz auf dem Stack lassen. + // Set the table name and push it onto the stack lua_pushvalue(L, -1); lua_setfield(L, -3, TableName.c_str()); } - // Tabelle mit den Metatabellen vom Stack nehmen. + // Remove the Metatable table from the stack lua_remove(L, -2); return true; @@ -306,49 +324,41 @@ bool BS_LuaBindhelper::GetMetatable(lua_State * L, const std::string & TableName // ----------------------------------------------------------------------------- -bool BS_LuaBindhelper::_CreateTable(lua_State * L, const std::string & TableName) -{ - // Der Tabellenname wird an den Punkten auseinandergetrennt und jeweils die Untertabellen erstellt. - // Auf diese Weise können auch Tabellen mit Untertabellen erstellt werden (z.B. Foo.Bar). - std::string::size_type PartBegin = 0; - while (PartBegin <= TableName.size()) - { - std::string::size_type PartEnd; - PartEnd = TableName.find(".", PartBegin); - if (PartEnd == std::string::npos) PartEnd = TableName.size(); - std::string SubTableName = TableName.substr(PartBegin, PartEnd - PartBegin); - - // Tabellen mit einen leeren String als Namen sind nicht zulässig. +bool BS_LuaBindhelper::_CreateTable(::lua_State *L, const Common::String &TableName) { + const char *PartBegin = TableName.c_str(); + + while (PartBegin) { + const char *PartEnd = strchr(PartBegin, '.'); + if (!PartEnd) PartEnd = PartBegin + strlen(PartBegin); + Common::String SubTableName(PartBegin, PartEnd - PartBegin); + + // Tables with an empty string as the name are not allowed if (SubTableName.size() == 0) return false; - // Überprüfen, ob die Tabelle mit dem Namen bereits existiert. - // Beim ersten Durchgang wird im globalen Namensbereich gesucht, bei späteren Durchgängen in der entsprechenden Elterntabelle auf dem Stack. - if (PartBegin == 0) - { + // Verify that the table with the name already exists + // The first round will be searched in the global namespace, with later passages + // in the corresponding parent table in the stack + if (PartBegin == 0) { lua_pushstring(L, SubTableName.c_str()); lua_gettable(L, LUA_GLOBALSINDEX); - } - else - { + } else { lua_pushstring(L, SubTableName.c_str()); lua_gettable(L, -2); if (!lua_isnil(L, -1)) lua_remove(L, -2); } - // Wenn nicht, Table erstellen - if (lua_isnil(L, -1)) - { - // nil-Wert vom Stack holen + // If it doesn't exist, create table + if (lua_isnil(L, -1)) { + // Pop nil from stack lua_pop(L, 1); - // Neue Tabelle erstellen + // Create new table lua_newtable(L); lua_pushstring(L, SubTableName.c_str()); lua_pushvalue(L, -2); if (PartBegin == 0) lua_settable(L, LUA_GLOBALSINDEX); - else - { + else { lua_settable(L, -4); lua_remove(L, -2); } @@ -360,12 +370,11 @@ bool BS_LuaBindhelper::_CreateTable(lua_State * L, const std::string & TableName return true; } -namespace -{ - std::string GetLuaValueInfo(lua_State * L, int StackIndex) - { - switch (lua_type(L, StackIndex)) - { +} // End of namespace Sword25 + +namespace { + Common::String GetLuaValueInfo(::lua_State *L, int StackIndex) { + switch (lua_type(L, StackIndex)) { case LUA_TNUMBER: lua_pushstring(L, lua_tostring(L, StackIndex)); break; @@ -387,48 +396,48 @@ namespace break; } - std::string Result(lua_tostring(L, -1)); + Common::String Result(lua_tostring(L, -1)); lua_pop(L, 1); return Result; } } -std::string BS_LuaBindhelper::StackDump(lua_State *L) -{ - std::ostringstream oss; +namespace Sword25 { + +Common::String BS_LuaBindhelper::StackDump(::lua_State *L) { + Common::String oss; int i = lua_gettop(L); - oss << "------------------- Stack Dump -------------------\n"; + oss += "------------------- Stack Dump -------------------\n"; - while(i) - { - oss << i << ": " << GetLuaValueInfo(L, i) << "\n"; + while (i) { + oss += i + ": " + GetLuaValueInfo(L, i) + "\n"; i--; } - oss << "-------------- Stack Dump Finished ---------------\n"; + oss += "-------------- Stack Dump Finished ---------------\n"; - return oss.str(); + return oss; } -std::string BS_LuaBindhelper::TableDump(lua_State * L) -{ - std::ostringstream oss; +Common::String BS_LuaBindhelper::TableDump(::lua_State *L) { + Common::String oss; - oss << "------------------- Table Dump -------------------\n"; + oss += "------------------- Table Dump -------------------\n"; lua_pushnil(L); - while (lua_next(L, -2) != 0) - { - // Der Wert des aktuellen Elementes liegt oben auf dem Stack, darunter der Index. - oss << GetLuaValueInfo(L, -2) << " : " << GetLuaValueInfo(L, -1) << "\n"; + while (lua_next(L, -2) != 0) { + // Get the value of the current element on top of the stack, including the index + oss += GetLuaValueInfo(L, -2) + " : " + GetLuaValueInfo(L, -1) + "\n"; - // 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); } - oss << "-------------- Table Dump Finished ---------------\n"; + oss += "-------------- Table Dump Finished ---------------\n"; - return oss.str(); + return oss; } + +} // End of namespace Sword25 |