diff --git a/CMakeLists.txt b/CMakeLists.txt index 80282616..cae11dbc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,8 +55,6 @@ ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug") SET(SOURCES # game sources src/main.cpp - src/menustate.cpp - src/teststate.cpp # game net src/protocollogin.cpp @@ -66,6 +64,7 @@ SET(SOURCES src/framework/core/configs.cpp src/framework/core/resources.cpp src/framework/core/engine.cpp + src/framework/core/modules.cpp # framework script src/framework/script/luascript.cpp diff --git a/data/modules/mainmenu/entergamewindow.yml b/data/modules/mainmenu/entergamewindow.yml index 0a38b1c8..5e3d7abd 100644 --- a/data/modules/mainmenu/entergamewindow.yml +++ b/data/modules/mainmenu/entergamewindow.yml @@ -50,8 +50,8 @@ window#enterGameWindow: margin.bottom: 10 margin.right: 13 onClick: | - enterGameWindow:destroy() - enterGameWindow = nil + self:getParent():destroy() + self:getParent():getParent():unlock() textEdit#accountNameTextEdit: anchors.right: parent.right diff --git a/data/modules/mainmenu/infowindow.yml b/data/modules/mainmenu/infowindow.yml index 466c00f3..de909b93 100644 --- a/data/modules/mainmenu/infowindow.yml +++ b/data/modules/mainmenu/infowindow.yml @@ -57,4 +57,6 @@ window#infoWindow: anchors.left: parent.left anchors.top: parent.top margin.top: 191 - margin.left: 188 \ No newline at end of file + margin.left: 188 + onClick: | + self:getParent():destroy() \ No newline at end of file diff --git a/data/modules/mainmenu/mainmenu.lua b/data/modules/mainmenu/mainmenu.lua index 32529fbf..bbbf4d26 100644 --- a/data/modules/mainmenu/mainmenu.lua +++ b/data/modules/mainmenu/mainmenu.lua @@ -1,6 +1,15 @@ --- events +-- main menu methods +function MainMenu_create() + mainMenu = loadUI("modules/mainmenu/mainmenu.yml") +end + +function MainMenu_destroy() + mainMenu:destroy() +end + function MainMenu_enterGameClicked() enterGameWindow = loadUI("modules/mainmenu/entergamewindow.yml") + enterGameWindow:getParent():lock(enterGameWindow) end function MainMenu_optionsClicked() @@ -12,12 +21,5 @@ function MainMenu_infoClicked() end function MainMenu_exitClicked() - exitGame() + onApplicationClose() end - --- create main menu -function MainMenu_create() - menuPanel = loadUI("modules/mainmenu/mainmenu.yml") -end - -MainMenu_create() \ No newline at end of file diff --git a/data/modules/mainmenu/mainmenu.yml b/data/modules/mainmenu/mainmenu.yml index 58b99944..6ee69152 100644 --- a/data/modules/mainmenu/mainmenu.yml +++ b/data/modules/mainmenu/mainmenu.yml @@ -1,41 +1,51 @@ -panel#mainMenu: - skin: roundedGridPanel - size: [117, 171] +panel#background: + skin: + image: background.png + antialised: true + size: [500, 500] anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top anchors.bottom: parent.bottom - margin.left: 60 - margin.bottom: 70 - button#enterGameButton: - text: Enter Game - anchors.top: parent.top - anchors.horizontalCenter: parent.horizontalCenter - margin.top: 16 - onClick: MainMenu_enterGameClicked() + panel#mainMenu: + skin: roundedGridPanel + size: [117, 171] + anchors.left: parent.left + anchors.bottom: parent.bottom + margin.left: 60 + margin.bottom: 70 + + button#enterGameButton: + text: Enter Game + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + margin.top: 16 + onClick: MainMenu_enterGameClicked() - button#accessAccountButton: - text: Access Account - anchors.top: parent.top - anchors.horizontalCenter: parent.horizontalCenter - margin.top: 46 + button#accessAccountButton: + text: Access Account + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + margin.top: 46 - button#optionsButton: - text: Options - anchors.top: parent.top - anchors.horizontalCenter: parent.horizontalCenter - margin.top: 76 - onClick: MainMenu_optionsClicked() + button#optionsButton: + text: Options + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + margin.top: 76 + onClick: MainMenu_optionsClicked() - button#infoButton: - text: Info - anchors.top: parent.top - anchors.horizontalCenter: parent.horizontalCenter - margin.top: 106 - onClick: MainMenu_infoClicked() + button#infoButton: + text: Info + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + margin.top: 106 + onClick: MainMenu_infoClicked() - button#exitGameButton: - text: Exit - anchors.top: parent.top - anchors.horizontalCenter: parent.horizontalCenter - margin.top: 136 - onClick: MainMenu_exitClicked() \ No newline at end of file + button#exitGameButton: + text: Exit + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + margin.top: 136 + onClick: MainMenu_exitClicked() \ No newline at end of file diff --git a/data/modules/mainmenu/menustate.lua b/data/modules/mainmenu/menustate.lua new file mode 100644 index 00000000..7def30b1 --- /dev/null +++ b/data/modules/mainmenu/menustate.lua @@ -0,0 +1,20 @@ +-- menu state +function onEnterMenuState() + MainMenu_create() +end + +function onLeaveMenuState() + MainMenu_destroy() +end + +function onApplicationClose() + onLeaveMenuState() + exitGame() +end + +-- here is where everything starts +if not initialStateLoaded then + onEnterMenuState() + setOnApplicationClose(onApplicationClose) + initialStateLoaded = true +end \ No newline at end of file diff --git a/data/modules/mainmenu/module.yml b/data/modules/mainmenu/module.yml new file mode 100644 index 00000000..8056a813 --- /dev/null +++ b/data/modules/mainmenu/module.yml @@ -0,0 +1,10 @@ +title: Main menu +notes: Used to create the main menu +enabled: true +#dependencies +interface: 020 +author: edubart +version: 0.2 +scripts: + - menustate.lua + - mainmenu.lua diff --git a/data/modules/mainmenu/optionswindow.yml b/data/modules/mainmenu/optionswindow.yml index 61c4f18c..acc0327c 100644 --- a/data/modules/mainmenu/optionswindow.yml +++ b/data/modules/mainmenu/optionswindow.yml @@ -110,5 +110,4 @@ window#optionsWindow: margin.right: 10 margin.bottom: 13 onClick: | - optionsWindow:destroy() - optionsWindow = nil \ No newline at end of file + self:getParent():destroy() \ No newline at end of file diff --git a/src/framework/core/engine.cpp b/src/framework/core/engine.cpp index 31b1fb13..19255cc5 100644 --- a/src/framework/core/engine.cpp +++ b/src/framework/core/engine.cpp @@ -42,14 +42,23 @@ void Engine::init() void Engine::terminate() { - // force last state exit - changeState(NULL); - // terminate stuff g_fonts.terminate(); g_graphics.terminate(); } +void Engine::poll() +{ + // poll platform events + Platform::poll(); + + // poll network events + Connection::poll(); + + // poll diaptcher tasks + g_dispatcher.poll(); +} + void Engine::run() { std::string fpsText; @@ -65,14 +74,7 @@ void Engine::run() while(!m_stopping) { m_lastFrameTicks = Platform::getTicks(); - // poll platform events - Platform::poll(); - - // poll network events - Connection::poll(); - - // poll diaptcher tasks - g_dispatcher.poll(); + poll(); // render only when visible if(Platform::isWindowVisible()) { @@ -93,8 +95,6 @@ void Engine::run() // render g_graphics.beginRender(); - if(m_currentState) - m_currentState->render(); UIContainer::getRootContainer()->render(); // render fps @@ -117,39 +117,19 @@ void Engine::stop() m_stopping = true; } -void Engine::changeState(GameState* newState) -{ - if(m_currentState) - m_currentState->onLeave(); - m_currentState = newState; - if(m_currentState) - m_currentState->onEnter(); -} - void Engine::onClose() { - if(m_currentState) - m_currentState->onClose(); + if(m_onCloseCallback) + g_dispatcher.addTask(m_onCloseCallback); } void Engine::onResize(const Size& size) { g_graphics.resize(size); UIContainer::getRootContainer()->setSize(size); - - if(m_currentState) - m_currentState->onResize(size); } void Engine::onInputEvent(const InputEvent& event) { - bool eventCaptured = false; - - // events goes to the state first - if(m_currentState) - eventCaptured = m_currentState->onInputEvent(event); - - // if the state didn't capture the input then goes to the gui - if(!eventCaptured) - UIContainer::getRootContainer()->onInputEvent(event); + UIContainer::getRootContainer()->onInputEvent(event); } diff --git a/src/framework/core/engine.h b/src/framework/core/engine.h index ac8848bc..dad4b388 100644 --- a/src/framework/core/engine.h +++ b/src/framework/core/engine.h @@ -26,19 +26,20 @@ #define ENGINE_H #include -#include +#include class Engine { public: Engine() : m_stopping(false), m_running(false), - m_calculateFps(false), - m_currentState(NULL) { } + m_calculateFps(false) { } void init(); void terminate(); + /// Poll events + void poll(); /// Main loop void run(); @@ -46,8 +47,6 @@ public: void stop(); /// Change current game state - void changeState(GameState *newState); - bool isRunning() const { return m_running; } bool isStopping() const { return m_stopping; } @@ -64,13 +63,16 @@ public: /// Return the current ticks on this frame int getCurrentFrameTicks() const { return m_lastFrameTicks; } + void setOnClose(Callback onCloseCallback) { m_onCloseCallback = onCloseCallback; } + private: bool m_stopping; bool m_running; bool m_calculateFps; - GameState *m_currentState; int m_lastFrameTicks; + + Callback m_onCloseCallback; }; extern Engine g_engine; diff --git a/src/framework/core/gamestate.h b/src/framework/core/gamestate.h deleted file mode 100644 index 199e64a4..00000000 --- a/src/framework/core/gamestate.h +++ /dev/null @@ -1,55 +0,0 @@ -/* The MIT License - * - * Copyright (c) 2010 OTClient, https://github.com/edubart/otclient - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#ifndef GAMESTATE_H -#define GAMESTATE_H - -#include -#include - -struct InputEvent; - -class GameState -{ -public: - GameState() { } - virtual ~GameState() { } - - /// Fired when enter the state - virtual void onEnter() = 0; - /// Fired when leaves the state - virtual void onLeave() = 0; - - /// Fired when user tries to close the window - virtual void onClose() = 0; - /// Fired for every user input event, this is called before processing UI input and if it returns false the input is not passed to the UI - virtual bool onInputEvent(const InputEvent& event) = 0; - /// Fired when main window is resized - virtual void onResize(const Size& size) = 0; - - /// Fired before redering the UI - virtual void render() = 0; -}; - -#endif // GAMESTATE_H diff --git a/src/teststate.h b/src/framework/core/modules.cpp similarity index 73% rename from src/teststate.h rename to src/framework/core/modules.cpp index 1c64dafc..d398505c 100644 --- a/src/teststate.h +++ b/src/framework/core/modules.cpp @@ -22,26 +22,5 @@ */ -#ifndef TESTSTATE_H -#define TESTSTATE_H +#include "modules.h" -#include -#include - -class TestState : public GameState -{ -public: - TestState() { } - - void onEnter(); - void onLeave(); - - void onClose(); - bool onInputEvent(const InputEvent& event); - void onResize(const Size& size); - - virtual void render(); - virtual void update(int ticks, int elapsedTicks); -}; - -#endif // TESTSTATE_H diff --git a/src/teststate.cpp b/src/framework/core/modules.h similarity index 74% rename from src/teststate.cpp rename to src/framework/core/modules.h index b75a856c..a3ed8d63 100644 --- a/src/teststate.cpp +++ b/src/framework/core/modules.h @@ -22,41 +22,11 @@ */ -#include -#include -#include "teststate.h" +#ifndef MODULES_H +#define MODULES_H -void TestState::onEnter() +class Modules { +}; -} - -void TestState::onLeave() -{ - -} - -void TestState::onClose() -{ - g_engine.stop(); -} - -bool TestState::onInputEvent(const InputEvent& event) -{ - return false; -} - -void TestState::onResize(const Size& size) -{ - -} - -void TestState::render() -{ - -} - -void TestState::update(int ticks, int elapsedTicks) -{ - -} +#endif // MODULES_H diff --git a/src/framework/graphics/image.cpp b/src/framework/graphics/image.cpp index 01ea42c9..c0cfa7f1 100644 --- a/src/framework/graphics/image.cpp +++ b/src/framework/graphics/image.cpp @@ -27,9 +27,16 @@ #include #include +Image::Image(TexturePtr texture) + : m_texture(texture) +{ + m_textureCoords = Rect(0, 0, m_texture->getSize()); +} + Image::Image(const std::string& texture) { m_texture = g_textures.get(texture); + m_textureCoords = Rect(0, 0, m_texture->getSize()); } Image::Image(const std::string& texture, Rect textureCoords) : diff --git a/src/framework/graphics/image.h b/src/framework/graphics/image.h index e1b59b92..482263f9 100644 --- a/src/framework/graphics/image.h +++ b/src/framework/graphics/image.h @@ -31,7 +31,7 @@ class Image { public: - Image(TexturePtr texture) : m_texture(texture) { } + Image(TexturePtr texture); Image(TexturePtr texture, Rect textureCoords) : m_texture(texture), m_textureCoords(textureCoords) { } Image(const std::string& texture); Image(const std::string& texture, Rect textureCoords); diff --git a/src/framework/script/luafunctions.cpp b/src/framework/script/luafunctions.cpp index 165c5fdf..645c3183 100644 --- a/src/framework/script/luafunctions.cpp +++ b/src/framework/script/luafunctions.cpp @@ -33,6 +33,7 @@ void LuaScript::registerFunctions() registerGlobalFunction("exitGame", &LuaScript::lua_exitGame); registerGlobalFunction("loadUI", &LuaScript::lua_loadUI); registerGlobalFunction("getUIRootContainer", &LuaScript::lua_getUIRootContainer); + registerGlobalFunction("setOnApplicationClose", &LuaScript::lua_setOnApplicationClose); registerClass("UILayout"); registerClass("UIElement", "UILayout"); @@ -42,8 +43,11 @@ void LuaScript::registerFunctions() registerClass("UIContainer", "UIElement"); registerClass("UIWindow", "UIContainer"); + registerMemberFunction("UIElement", "getParent", &LuaScript::lua_UIElement_getParent); registerMemberFunction("UIElement", "destroy", &LuaScript::lua_UIElement_destroy); registerMemberFunction("UIContainer", "getChildByID", &LuaScript::lua_UIContainer_getChildByID); + registerMemberFunction("UIContainer", "lock", &LuaScript::lua_UIContainer_lock); + registerMemberFunction("UIContainer", "unlock", &LuaScript::lua_UIContainer_unlock); registerMemberFunction("UIButton", "setOnClick", &LuaScript::lua_UIButton_setOnClick); } @@ -74,10 +78,34 @@ int LuaScript::lua_getUIRootContainer() return 1; } + +int LuaScript::lua_setOnApplicationClose() +{ + int funcRef = popFunction(); + g_engine.setOnClose([this, funcRef] { + pushFunction(funcRef); + callFunction(); + }); + return 1; +} + int LuaScript::lua_UIElement_destroy() { UIElementPtr element = boost::static_pointer_cast(popClassInstance()); - element->destroy(); + if(element) + element->destroy(); + else + pushNil(); + return 1; +} + +int LuaScript::lua_UIElement_getParent() +{ + UIElementPtr element = boost::static_pointer_cast(popClassInstance()); + if(element) + pushClassInstance(element->getParent()); + else + pushNil(); return 1; } @@ -87,8 +115,9 @@ int LuaScript::lua_UIButton_setOnClick() UIButtonPtr button = boost::static_pointer_cast(popClassInstance()); if(button) { int funcRef = popFunction(); - button->setOnClick([this, funcRef] { + button->setOnClick([this, funcRef](UIButtonPtr button) { pushFunction(funcRef); + setSelf(button); callFunction(); }); } else { @@ -100,13 +129,29 @@ int LuaScript::lua_UIButton_setOnClick() int LuaScript::lua_UIContainer_getChildByID() { std::string id = popString(); - ScriptablePtr object = popClassInstance(); - if(object && strcmp("UIContainer", object->getScriptableName()) == 0) { - UIContainerPtr container = boost::static_pointer_cast(object); + UIContainerPtr container = boost::static_pointer_cast(popClassInstance()); + if(container) pushClassInstance(container->getChildById(id)); - } else { + else pushNil(); + return 1; +} + +int LuaScript::lua_UIContainer_lock() +{ + UIElementPtr element = boost::static_pointer_cast(popClassInstance()); + UIContainerPtr container = boost::static_pointer_cast(popClassInstance()); + if(container && element) { + container->lockElement(element); } + return 1; +} +int LuaScript::lua_UIContainer_unlock() +{ + UIContainerPtr container = boost::static_pointer_cast(popClassInstance()); + if(container) { + container->unlockElement(); + } return 1; -} \ No newline at end of file +} diff --git a/src/framework/script/luascript.cpp b/src/framework/script/luascript.cpp index 397596cd..6b7ead6f 100644 --- a/src/framework/script/luascript.cpp +++ b/src/framework/script/luascript.cpp @@ -49,10 +49,22 @@ LuaScript::~LuaScript() lua_close(L); } +void LuaScript::loadAllModules() +{ + std::list modules = g_resources.getDirectoryFiles("modules"); + foreach(const std::string& module, modules) { + std::list moduleFiles = g_resources.getDirectoryFiles(std::string("modules/") + module); + foreach(const std::string& moduleFile, moduleFiles) { + if(boost::ends_with(moduleFile, ".lua")) + loadFile(std::string("modules/") + module + "/" + moduleFile); + } + } +} + bool LuaScript::loadFile(const std::string& fileName) { if(!g_resources.fileExists(fileName)) { - logError("lua script file '%s' doesn't exist", fileName.c_str()); + logError("script file '%s' doesn't exist", fileName.c_str()); return false; } std::string fileContents = g_resources.loadTextFile(fileName); @@ -64,20 +76,19 @@ bool LuaScript::loadBuffer(const std::string& text, const std::string& what) // load buffer int ret = luaL_loadbuffer(L, text.c_str(), text.length(), what.c_str()); if(ret != 0){ - logError((std::string("while parsing lua code: ") + popString()).c_str()); + reportError(popString()); return false; } - // check if that is loaded as a function + // check if is loaded as a function if(lua_isfunction(L, -1) == 0) { - logError("lua code not loaded as function"); return false; } // execute it ret = lua_pcall(L, 0, 0, 0); if(ret != 0){ - logError((std::string("while loading lua code: ") + popString()).c_str()); + reportError(popString()); return false; } @@ -86,21 +97,30 @@ bool LuaScript::loadBuffer(const std::string& text, const std::string& what) int LuaScript::loadBufferAsFunction(const std::string& text, const std::string& what) { - int ret = luaL_loadstring(L, text.c_str()); + int ret = luaL_loadbuffer(L, text.c_str(), text.length(), what.c_str()); if(ret != 0){ - logError((std::string("while parsing lua code: ") + popString()).c_str()); + reportError(popString()); return LUA_REFNIL; } - // check if that is loaded as a function + // check if is loaded as a function if(lua_isfunction(L, -1) == 0) { - logError("lua code not loaded as function"); return LUA_REFNIL; } return popFunction(); } +void LuaScript::reportError(const std::string& errorDesc, const char *funcName) +{ + std::stringstream ss; + ss << "LUA script error"; + if(funcName) + ss << " in " << funcName << "()"; + ss << ": " << errorDesc << std::endl; + logError(ss.str().c_str()); +} + int LuaScript::getStackSize() { return lua_gettop(L); @@ -120,23 +140,15 @@ bool LuaScript::popBoolean() int32_t LuaScript::popInteger() { - double d; - if(lua_istable(L, -1)) { - lua_getfield(L, -1, "__intValue"); - d = lua_tonumber(L, -1); - pop(2); - } - else{ - d = lua_tonumber(L, -1); - pop(1); - } + double d = lua_tonumber(L, -1); + pop(1); return (int)d; } std::string LuaScript::popString() { size_t len; - const char* cstr = lua_tolstring(L, -1, &len); + const char *cstr = lua_tolstring(L, -1, &len); std::string str(cstr, len); pop(); return str; @@ -169,24 +181,35 @@ void LuaScript::pushUserdata(void* ptr) void LuaScript::pushClassInstance(const ScriptablePtr& object) { - if(object->getScriptableName()) { + if(object && object->getScriptableName()) { new(lua_newuserdata(L, sizeof(ScriptableWeakPtr))) ScriptableWeakPtr(object); lua_getfield(L, LUA_REGISTRYINDEX, (std::string(object->getScriptableName()) + "_mt").c_str()); lua_setmetatable(L, -2); + } else { + lua_pushnil(L); } } ScriptablePtr LuaScript::popClassInstance() { if(!lua_isuserdata(L, -1)) { - logError("Couldn't pop a class instance, top objet is not a valid type (%s)", luaL_typename(L, -1)); + reportError(format("couldn't pop a class instance, top objet is not a valid type (%s)", luaL_typename(L, -1))); lua_pop(L, 1); return ScriptablePtr(); } ScriptableWeakPtr *objectRef = (ScriptableWeakPtr *)lua_touserdata(L, -1); lua_pop(L, 1); - return objectRef->lock(); + + ScriptablePtr object = objectRef->lock(); + if(!object) + reportError(format("attempt to retrive class instance from a object that is already expired")); + return object; +} + +void LuaScript::pushFunction(int functionRef) +{ + lua_rawgeti(L, LUA_REGISTRYINDEX, functionRef); } int LuaScript::popFunction() @@ -194,14 +217,35 @@ int LuaScript::popFunction() return luaL_ref(L, LUA_REGISTRYINDEX); } -void LuaScript::pushFunction(int functionRef) +void LuaScript::releaseFunction(int functionRef) { - lua_rawgeti(L, LUA_REGISTRYINDEX, functionRef); + luaL_unref(L, LUA_REGISTRYINDEX, functionRef); +} + +void LuaScript::callFunction(int numArgs) +{ + int size = lua_gettop(L); + int errorIndex = size - numArgs; + lua_pushcfunction(L, &LuaScript::luaErrorHandler); + lua_insert(L, errorIndex); + + int ret = lua_pcall(L, numArgs, 0, errorIndex); + if(ret != 0) { + reportError(popString()); + } + + lua_remove(L, errorIndex); + + if(lua_gettop(L) + numArgs + 1 != size) + reportError("stack size changed!"); } -void LuaScript::callFunction(int numArgs, bool itReturnsValue) +void LuaScript::setSelf(const ScriptablePtr& scriptable, int envIndex) { - lua_call(L, numArgs, itReturnsValue ? 1 : 0); + lua_getfenv(L, envIndex); + pushClassInstance(scriptable); + lua_setfield(L, -2, "self"); + lua_pop(L, 1); } void LuaScript::setupPackageLoader() @@ -342,3 +386,20 @@ int LuaScript::luaFunctionCallback(lua_State* L) return (g_lua.*(g_lua.m_functions[id]))(); } +int LuaScript::luaErrorHandler(lua_State *L) +{ + lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + if(!lua_istable(L, -1)) { + lua_pop(L, 1); + return 1; + } + lua_getfield(L, -1, "traceback"); + if(!lua_isfunction(L, -1)) { + lua_pop(L, 2); + return 1; + } + lua_pushvalue(L, 1); + lua_pushinteger(L, 2); + lua_call(L, 2, 1); + return 1; +} diff --git a/src/framework/script/luascript.h b/src/framework/script/luascript.h index dc488b97..cdd4a415 100644 --- a/src/framework/script/luascript.h +++ b/src/framework/script/luascript.h @@ -29,15 +29,19 @@ #include