From ab6c52a3eed5399bee366835fe2fe770617fcb97 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Thu, 19 May 2011 14:11:05 -0300 Subject: [PATCH] rework on resources system --- data/modules/mainmenu/mainmenu.yml | 14 +-- data/modules/mainmenu/menustate.lua | 2 +- data/modules/messagebox/messagebox.lua | 4 +- src/framework/core/configs.cpp | 6 +- src/framework/core/resources.cpp | 142 +++++++++++++++++------ src/framework/core/resources.h | 36 +++--- src/framework/graphics/font.cpp | 7 +- src/framework/graphics/fonts.cpp | 8 +- src/framework/graphics/textureloader.cpp | 4 +- src/framework/graphics/textureloader.h | 2 +- src/framework/graphics/textures.cpp | 8 +- src/framework/platform/x11platform.cpp | 2 +- src/framework/prerequisites.h | 1 + src/framework/script/luafunctions.cpp | 2 +- src/framework/script/luascript.cpp | 131 ++++++++++++--------- src/framework/script/luascript.h | 5 +- src/framework/ui/uielementskin.cpp | 4 +- src/framework/ui/uiloader.cpp | 35 +++--- src/framework/ui/uiloader.h | 20 ++-- src/framework/ui/uiskins.cpp | 16 +-- src/framework/ui/uiskins.h | 2 +- src/framework/util/apngloader.cpp | 82 +++++++------ src/framework/util/apngloader.h | 4 +- src/main.cpp | 5 +- 24 files changed, 319 insertions(+), 223 deletions(-) diff --git a/data/modules/mainmenu/mainmenu.yml b/data/modules/mainmenu/mainmenu.yml index 5f4addcd..84489f30 100644 --- a/data/modules/mainmenu/mainmenu.yml +++ b/data/modules/mainmenu/mainmenu.yml @@ -6,16 +6,16 @@ panel#background: anchors.bottom: parent.bottom panel#icos4d: - skin: - image: lightness/mouse.png + skin: + image: /skins/lightness/mouse.png anchors.left: parent.left anchors.top: parent.top margin.left: -2 margin.top: 70 panel#mouse: - skin: - image: lightness/icos4d.png + skin: + image: /skins/lightness/icos4d.png anchors.right: parent.right anchors.bottom: parent.bottom margin.left: 60 @@ -34,7 +34,7 @@ panel#background: anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter margin.top: 16 - onClick: UI.load("mainmenu/entergamewindow.yml") + onClick: UI.load("entergamewindow.yml") button#accessAccountButton: text: Access Account @@ -48,14 +48,14 @@ panel#background: anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter margin.top: 76 - onClick: UI.load("mainmenu/optionswindow.yml") + onClick: UI.load("optionswindow.yml") button#infoButton: text: Info anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter margin.top: 106 - onClick: UI.load("mainmenu/infowindow.yml") + onClick: UI.load("infowindow.yml") button#exitGameButton: text: Exit diff --git a/data/modules/mainmenu/menustate.lua b/data/modules/mainmenu/menustate.lua index 2c7070ba..fb8929c1 100644 --- a/data/modules/mainmenu/menustate.lua +++ b/data/modules/mainmenu/menustate.lua @@ -1,6 +1,6 @@ -- menu state function onEnterMenuState() - mainMenu = UI.load("mainmenu/mainmenu.yml") + mainMenu = UI.load("mainmenu.yml") end function onLeaveMenuState() diff --git a/data/modules/messagebox/messagebox.lua b/data/modules/messagebox/messagebox.lua index 307384c6..a27dd959 100644 --- a/data/modules/messagebox/messagebox.lua +++ b/data/modules/messagebox/messagebox.lua @@ -3,9 +3,9 @@ function autoDestroyParent() end function messageBox(title, text) - local msgBox = UI.load("modules/messagebox/messagebox.yml") + local msgBox = UI.load("messagebox.yml") msgBox.locked = true msgBox.title = title msgBox:child("textLabel").text = text - msgBox:child("okButton").onClick = autoDestroyParent + msgBox:child("okButton").onClick = autoDestroyParentz end diff --git a/src/framework/core/configs.cpp b/src/framework/core/configs.cpp index 64d59779..fa9ad26a 100644 --- a/src/framework/core/configs.cpp +++ b/src/framework/core/configs.cpp @@ -35,12 +35,10 @@ bool Configs::load(const std::string& fileName) if(!g_resources.fileExists(fileName)) return false; - std::string fileContents = g_resources.loadTextFile(fileName); - if(!fileContents.size()) + std::stringstream fin; + if(!g_resources.loadFile(fileName, fin)) return false; - std::istringstream fin(fileContents); - try { YAML::Parser parser(fin); diff --git a/src/framework/core/resources.cpp b/src/framework/core/resources.cpp index 554b1a48..53e84b95 100644 --- a/src/framework/core/resources.cpp +++ b/src/framework/core/resources.cpp @@ -24,6 +24,7 @@ #include #include +#include #include @@ -32,6 +33,29 @@ Resources g_resources; void Resources::init(const char *argv0) { PHYSFS_init(argv0); + + // try to find data directory + std::list searchPaths; + std::string dir; + std::string baseDir = PHYSFS_getBaseDir(); + + std::list possibleDirs; + possibleDirs.push_back("data"); + possibleDirs.push_back(baseDir + "data"); + possibleDirs.push_back(baseDir + "../data"); + possibleDirs.push_back(baseDir + "../share/data"); + possibleDirs.push_back(""); + + foreach(dir, possibleDirs) + if(g_resources.addToSearchPath(dir)) + break; + + // setup write directory + dir = Platform::getAppUserDir(); + if(g_resources.setWriteDir(dir)) + g_resources.addToSearchPath(dir); + else + logError("ERROR: could not setup write directory"); } void Resources::terminate() @@ -41,59 +65,63 @@ void Resources::terminate() bool Resources::setWriteDir(const std::string& path) { - bool ret = (bool)PHYSFS_setWriteDir(path.c_str()); - - if(!ret) - flogError("ERROR: Could not set the path \"%s\" as write directory, file write will not work correctly.", path.c_str()); - return ret; + if(!PHYSFS_setWriteDir(path.c_str())) + return false; + return true; } bool Resources::addToSearchPath(const std::string& path, bool insertInFront /*= true*/) { - if(!PHYSFS_addToSearchPath(path.c_str(), insertInFront ? 0 : 1)) { - flogError("ERROR: Error while adding \"%s\" to resources search path: %s", path.c_str() % PHYSFS_getLastError()); + if(!PHYSFS_addToSearchPath(path.c_str(), insertInFront ? 0 : 1)) return false; - } return true; } -bool Resources::fileExists(const std::string& filePath) +void Resources::addPackagesToSearchPath(const std::string &packagesDirectory, const std::string &packageExtension, bool append) { - return PHYSFS_exists(filePath.c_str()); + auto files = listDirectoryFiles(resolvePath(packagesDirectory)); + foreach(const std::string& file, files) { + if(boost::ends_with(file, packageExtension)) + addToSearchPath(packagesDirectory + "/" + file, !append); + } } -uchar *Resources::loadFile(const std::string& fileName, uint *fileSize) +bool Resources::fileExists(const std::string& fileName) { - PHYSFS_file *file = PHYSFS_openRead(fileName.c_str()); - if(!file) { - flogError("ERROR: Failed to load file \"%s\": %s", fileName.c_str() % PHYSFS_getLastError()); - *fileSize = 0; - return NULL; - } + return (PHYSFS_exists(resolvePath(fileName).c_str()) && !PHYSFS_isDirectory(resolvePath(fileName).c_str())); +} - *fileSize = PHYSFS_fileLength(file); - uchar *buffer = new uchar[*fileSize + 1]; - PHYSFS_read(file, (void*)buffer, 1, *fileSize); - buffer[*fileSize] = 0; - PHYSFS_close(file); - return buffer; +bool Resources::directoryExists(const std::string& directoryName) +{ + return (PHYSFS_exists(resolvePath(directoryName).c_str()) && PHYSFS_isDirectory(resolvePath(directoryName).c_str())); } -std::string Resources::loadTextFile(const std::string& fileName) +bool Resources::loadFile(const std::string& fileName, std::iostream& out) { - std::string text; - uint fileSize; - char *buffer = (char *)loadFile(fileName, &fileSize); - if(buffer) { - text.assign(buffer); - delete[] buffer; + out.clear(std::ios::goodbit); + PHYSFS_file *file = PHYSFS_openRead(resolvePath(fileName).c_str()); + if(!file) { + flogError("ERROR: Failed to load file \"%s\": %s", fileName.c_str() % PHYSFS_getLastError()); + out.clear(std::ios::failbit); + return false; + } else { + int fileSize = PHYSFS_fileLength(file); + if(fileSize > 0) { + char *buffer = new char[fileSize]; + PHYSFS_read(file, (void*)buffer, 1, fileSize); + out.write(buffer, fileSize); + delete buffer; + } else + out.clear(std::ios::eofbit); + PHYSFS_close(file); + out.seekg(0, std::ios::beg); + return true; } - return text; } bool Resources::saveFile(const std::string &fileName, const uchar *data, uint size) { - PHYSFS_file *file = PHYSFS_openWrite(fileName.c_str()); + PHYSFS_file *file = PHYSFS_openWrite(resolvePath(fileName).c_str()); if(!file) { flogError("ERROR: Failed to save file \"%s\": %s", fileName.c_str() % PHYSFS_getLastError()); return false; @@ -104,15 +132,29 @@ bool Resources::saveFile(const std::string &fileName, const uchar *data, uint si return true; } -bool Resources::saveTextFile(const std::string &fileName, std::string text) +bool Resources::saveFile(const std::string &fileName, std::istream& in) { - return saveFile(fileName, (const uchar*)text.c_str(), text.size()); + std::streampos oldPos = in.tellg(); + in.seekg(0, std::ios::end); + std::streampos size = in.tellg(); + in.seekg(0, std::ios::beg); + char *buffer = new char[size]; + in.read(buffer, size); + bool ret = saveFile(fileName, (const uchar*)buffer, size); + delete[] buffer; + in.seekg(oldPos, std::ios::beg); + return ret; +} + +bool Resources::deleteFile(const std::string& fileName) +{ + return PHYSFS_delete(resolvePath(fileName).c_str()) != 0; } -std::list Resources::getDirectoryFiles(const std::string& directory) +std::list Resources::listDirectoryFiles(const std::string& directoryPath) { std::list files; - char **rc = PHYSFS_enumerateFiles(directory.c_str()); + char **rc = PHYSFS_enumerateFiles(resolvePath(directoryPath).c_str()); for(char **i = rc; *i != NULL; i++) files.push_back(*i); @@ -120,3 +162,31 @@ std::list Resources::getDirectoryFiles(const std::string& directory PHYSFS_freeList(rc); return files; } + + +void Resources::pushCurrentPath(const std::string ¤tPath) +{ + m_currentPaths.push(currentPath); +} + +void Resources::popCurrentPath() +{ + m_currentPaths.pop(); +} + +std::string Resources::resolvePath(const std::string& path) +{ + std::string fullPath; + if(boost::starts_with(path, "/")) + fullPath = path.substr(1); + else { + if(m_currentPaths.size() > 0) { + std::string currentPath = m_currentPaths.top(); + if(currentPath.length() > 0) + fullPath += currentPath + "/"; + } + fullPath += path; + } + return fullPath; +} + diff --git a/src/framework/core/resources.h b/src/framework/core/resources.h index ce289172..d690d447 100644 --- a/src/framework/core/resources.h +++ b/src/framework/core/resources.h @@ -35,36 +35,32 @@ public: void init(const char *argv0); void terminate(); - /// Sets the write directory + /// Set output files dir bool setWriteDir(const std::string &path); - /// Adds a directory or zip archive to the search path + /// Add an package or directory to the search path bool addToSearchPath(const std::string& path, bool insertInFront = true); + /// Add all packages from a directory + void addPackagesToSearchPath(const std::string &packagesDirectory, const std::string &packageExtension, bool append); - /// Checks whether the given file exists in the search path - bool fileExists(const std::string& filePath); + bool fileExists(const std::string& fileName); + bool directoryExists(const std::string& directoryName); - /// Searches for zip files and adds them to the search path - void searchAndAddArchives(const std::string &path, - const std::string &ext, - const bool append); + bool loadFile(const std::string& fileName, std::iostream& out); - /** Load a file by allocating a buffer and filling it with the file contents - * where fileSize will be set to the file size. - * The returned buffer must be freed with delete[]. */ - uchar *loadFile(const std::string &fileName, uint *fileSize); + bool saveFile(const std::string& fileName, const uchar *data, uint size); + bool saveFile(const std::string& fileName, std::istream& in); - /// Loads a text file into a std::string - std::string loadTextFile(const std::string &fileName); + bool deleteFile(const std::string& fileName); - /// Save a file into write directory - bool saveFile(const std::string &fileName, const uchar *data, uint size); + std::list listDirectoryFiles(const std::string& directoryPath = ""); - /// Save a text file into write directory - bool saveTextFile(const std::string &fileName, std::string text); + void pushCurrentPath(const std::string ¤tPath); + void popCurrentPath(); + std::string resolvePath(const std::string& path); - /// Get a list with all files in a directory - std::list getDirectoryFiles(const std::string& directory); +private: + std::stack m_currentPaths; }; extern Resources g_resources; diff --git a/src/framework/graphics/font.cpp b/src/framework/graphics/font.cpp index b219025d..367fdc69 100644 --- a/src/framework/graphics/font.cpp +++ b/src/framework/graphics/font.cpp @@ -68,13 +68,12 @@ void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize) bool Font::load(const std::string& file) { - std::string fileContents = g_resources.loadTextFile(file); - if(!fileContents.size()) { + std::stringstream fin; + if(!g_resources.loadFile(file, fin)) { flogError("ERROR: Coult not load font file \"%s", file.c_str()); return false; } - std::istringstream fin(fileContents); std::string textureName; Size glyphSize; @@ -94,7 +93,7 @@ bool Font::load(const std::string& file) m_glyphSpacing = yamlRead(doc, "glyph spacing", Size(0,0)); // load texture - m_texture = g_textures.get("fonts/" + textureName); + m_texture = g_textures.get(textureName); if(!m_texture) { flogError("ERROR: Failed to load image for font file \"%s\"", file.c_str()); return false; diff --git a/src/framework/graphics/fonts.cpp b/src/framework/graphics/fonts.cpp index b69cdde9..a8a26439 100644 --- a/src/framework/graphics/fonts.cpp +++ b/src/framework/graphics/fonts.cpp @@ -30,17 +30,21 @@ Fonts g_fonts; void Fonts::init() { + g_resources.pushCurrentPath("fonts"); + // load all fonts - std::list files = g_resources.getDirectoryFiles("fonts"); + std::list files = g_resources.listDirectoryFiles(); foreach(const std::string& file, files) { if(boost::ends_with(file, ".yml")) { std::string name = file; boost::erase_first(name, ".yml"); FontPtr font(new Font(name)); - if(font->load("fonts/" + file)) + if(font->load(file)) m_fonts.push_back(font); } } + + g_resources.popCurrentPath(); } FontPtr Fonts::get(const std::string& fontName) diff --git a/src/framework/graphics/textureloader.cpp b/src/framework/graphics/textureloader.cpp index 05c3116a..14597cfe 100644 --- a/src/framework/graphics/textureloader.cpp +++ b/src/framework/graphics/textureloader.cpp @@ -28,12 +28,12 @@ #include #include "animatedtexture.h" -TexturePtr TextureLoader::loadPNG(uchar *fileData, uint fileSize) +TexturePtr TextureLoader::loadPNG(std::stringstream& file) { TexturePtr texture; apng_data apng; - if(load_apng(fileData, fileSize, &apng) == 0) { + if(load_apng(file, &apng) == 0) { if(apng.num_frames > 1) { // animated texture uchar *framesdata = apng.pdata + (apng.first_frame * apng.width * apng.height * apng.bpp); texture = TexturePtr(new AnimatedTexture(apng.width, apng.height, apng.bpp, apng.num_frames, framesdata, (int*)apng.frames_delay)); diff --git a/src/framework/graphics/textureloader.h b/src/framework/graphics/textureloader.h index 9bf83abe..1a3158cf 100644 --- a/src/framework/graphics/textureloader.h +++ b/src/framework/graphics/textureloader.h @@ -32,7 +32,7 @@ class TextureLoader { public: /// Load a png textures - static TexturePtr loadPNG(uchar *fileData, uint fileSize); + static TexturePtr loadPNG(std::stringstream& file); }; #endif // TEXTURELOADER_H diff --git a/src/framework/graphics/textures.cpp b/src/framework/graphics/textures.cpp index fb679d6f..602df1c5 100644 --- a/src/framework/graphics/textures.cpp +++ b/src/framework/graphics/textures.cpp @@ -52,19 +52,17 @@ TexturePtr Textures::get(const std::string& textureFile) } // load texture file data - uint fileSize; - uchar *textureFileData = g_resources.loadFile(textureFile, &fileSize); - if(!textureFileData) { + std::stringstream fin; + if(!g_resources.loadFile(textureFile, fin)) { flogError("ERROR: Unable to load texture %s, file could not be read.", textureFile.c_str()); return texture; } // load the texture - texture = TexturePtr(TextureLoader::loadPNG(textureFileData, fileSize)); + texture = TexturePtr(TextureLoader::loadPNG(fin)); if(!texture) flogError("ERROR: Unable to load texture %s", textureFile.c_str()); - delete[] textureFileData; } return texture; } diff --git a/src/framework/platform/x11platform.cpp b/src/framework/platform/x11platform.cpp index a377bea6..2fc8590a 100644 --- a/src/framework/platform/x11platform.cpp +++ b/src/framework/platform/x11platform.cpp @@ -834,7 +834,7 @@ bool Platform::isWindowMaximized() std::string Platform::getAppUserDir() { std::stringstream sdir; - sdir << PHYSFS_getUserDir() << "/." << x11.appName << "/"; + sdir << PHYSFS_getUserDir() << "." << x11.appName; if((mkdir(sdir.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) && (errno != EEXIST)) flogError("ERROR: Couldn't create directory for saving configuration file. (%s)", sdir.str().c_str()); return sdir.str(); diff --git a/src/framework/prerequisites.h b/src/framework/prerequisites.h index 7a1d8308..d23fdbc7 100644 --- a/src/framework/prerequisites.h +++ b/src/framework/prerequisites.h @@ -55,6 +55,7 @@ typedef int8_t int8; #include #include #include +#include #include #include #include diff --git a/src/framework/script/luafunctions.cpp b/src/framework/script/luafunctions.cpp index 853196ee..e67b6d7d 100644 --- a/src/framework/script/luafunctions.cpp +++ b/src/framework/script/luafunctions.cpp @@ -98,7 +98,7 @@ int lua_UI_load() UIElementPtr element; if(parent) - element = UILoader::loadFile(uiFile.c_str(), parent); + element = g_uiLoader.loadFromYAML(uiFile.c_str(), parent); else g_lua.reportErrorWithTraceback("invalid parent container"); diff --git a/src/framework/script/luascript.cpp b/src/framework/script/luascript.cpp index e44f79f2..b65f2f4b 100644 --- a/src/framework/script/luascript.cpp +++ b/src/framework/script/luascript.cpp @@ -54,9 +54,9 @@ void LuaScript::terminate() void LuaScript::loadAllModules() { - std::list modules = g_resources.getDirectoryFiles("modules"); + std::list modules = g_resources.listDirectoryFiles("modules"); foreach(const std::string& module, modules) { - std::list moduleFiles = g_resources.getDirectoryFiles(std::string("modules/") + module); + std::list moduleFiles = g_resources.listDirectoryFiles("modules/" + module); foreach(const std::string& moduleFile, moduleFiles) { if(boost::ends_with(moduleFile, ".lua")) loadFile(std::string("modules/") + module + "/" + moduleFile); @@ -66,42 +66,24 @@ void LuaScript::loadAllModules() bool LuaScript::loadFile(const std::string& fileName) { - if(!g_resources.fileExists(fileName)) { + std::stringstream fin; + if(g_resources.loadFile(fileName, fin)) + return loadBuffer(fin.str(), fileName); + else flogError("ERROR: script file '%s' doesn't exist", fileName.c_str()); - return false; - } - std::string fileContents = g_resources.loadTextFile(fileName); - return loadBuffer(fileContents, fileName); + return false; } 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){ - reportError(popString()); - return false; - } - - // check if is loaded as a function - if(lua_isfunction(L, -1) == 0) { - pop(); - return false; - } - - // execute it - ret = lua_pcall(L, 0, 0, 0); - if(ret != 0){ - reportError(popString()); - return false; - } - - return true; + if(loadBufferAsFunction(text, what) && callFunction()) + return true; + return false; } bool LuaScript::loadBufferAsFunction(const std::string& text, const std::string& what) { - int ret = luaL_loadbuffer(L, text.c_str(), text.length(), what.c_str()); + int ret = luaL_loadbuffer(L, text.c_str(), text.length(), ("@" + what).c_str()); if(ret != 0){ reportError(popString()); return false; @@ -111,7 +93,6 @@ bool LuaScript::loadBufferAsFunction(const std::string& text, const std::string& pop(); return false; } - return true; } @@ -145,7 +126,15 @@ int LuaScript::getStackSize() void LuaScript::insert(int index) { - lua_insert(L, index); + if(index != -1) + lua_insert(L, index); +} + +void LuaScript::swap(int index) +{ + insert(index); + pushValue(index+1); + remove(index); } void LuaScript::remove(int index) @@ -390,23 +379,61 @@ void LuaScript::pushRef(int ref) lua_rawgeti(L, LUA_REGISTRYINDEX, ref); } -void LuaScript::callFunction(int numArgs) +std::string LuaScript::getFunctionSourcePath() { - int size = lua_gettop(L); - int errorIndex = -(numArgs + 2); + std::string path; + + lua_Debug ar; + memset(&ar, 0, sizeof(ar)); + lua_getinfo(L, ">Sn", &ar); + + // c function, we must get information of level above + if(strcmp("C", ar.what) == 0) { + memset(&ar, 0, sizeof(ar)); + if(lua_getstack(L, 1, &ar) == 1) { + lua_getinfo(L, "f", &ar); + return getFunctionSourcePath(); + } + + } else { + if(ar.source) { + std::string source = ar.source; + std::size_t pos = source.find_last_of('/'); + if(source[0] == '@' && pos != std::string::npos) + path = source.substr(1, pos - 1); + } else { + logError("no source"); + } + } + return path; +} + +bool LuaScript::callFunction(int numArgs, int numRets) +{ + pushValue(-numArgs - 1); + g_resources.pushCurrentPath(getFunctionSourcePath()); + + int size = getStackSize(); + int errorIndex = -numArgs - 2; lua_pushcfunction(L, &LuaScript::luaErrorHandler); - lua_insert(L, errorIndex); + insert(errorIndex); - int ret = lua_pcall(L, numArgs, 0, errorIndex); + int ret = lua_pcall(L, numArgs, numRets, errorIndex); if(ret != 0) { reportError(popString()); + pop(); // pop error func + return false; } - // pop error func - lua_pop(L, 1); + remove(-numRets - 1); // pop error func - if(lua_gettop(L) != size - numArgs - 1) + if(getStackSize() != size - numArgs - 1 + numRets) { reportError("stack size changed!"); + return false; + } + + g_resources.popCurrentPath(); + return true; } void LuaScript::callModuleField(const std::string& module, const std::string& field) @@ -581,8 +608,9 @@ int LuaScript::luaPackageLoader(lua_State* L) std::string fileName = lua_tostring(L, -1); fileName += ".lua"; if(g_resources.fileExists(fileName)) { - std::string fileContents = g_resources.loadTextFile(fileName); - luaL_loadbuffer(L, fileContents.c_str(), fileContents.length(), fileName.c_str()); + std::stringstream fin; + if(g_resources.loadFile(fileName, fin)) + luaL_loadbuffer(L, fin.str().c_str(), fin.str().length(), fileName.c_str()); } else { lua_pushfstring(L, "\n\tcould not load lua script " LUA_QS, fileName.c_str()); } @@ -601,16 +629,8 @@ int LuaScript::luaIndexMetaMethod(lua_State* L) if(!lua_isnil(L, -1)) { lua_remove(L, -2); // get_method, obj lua_insert(L, -2); // obj, get_method - lua_pushcfunction(L, &LuaScript::luaErrorHandler); // errorfunc, obj,get_method - lua_insert(L, -3); // obj, get_method, errorfunc - int ret = lua_pcall(L, 1, 1, -3); // ret, errorfunc - if(ret != 0) { - g_lua.reportError(g_lua.popString()); // errofunc - lua_pop(L, 1); // (empty) - lua_pushnil(L); // nil - } else { - lua_remove(L, -2); // ret - } + if(!g_lua.callFunction(1, 1)) + lua_pushnil(L); return 1; } else { lua_pop(L, 1); // mt, obj @@ -618,7 +638,7 @@ int LuaScript::luaIndexMetaMethod(lua_State* L) lua_getfield(L, -1, key.c_str()); // method, methods, mt, obj lua_remove(L, -2); // method, mt, obj if(!lua_isnil(L, -1)) { - lua_insert(L, -3); // obj, mt, method + lua_insert(L, -3); // mt, obj, method lua_pop(L, 2); // method return 1; } @@ -654,12 +674,7 @@ int LuaScript::luaNewIndexMetaMethod(lua_State* L) if(!lua_isnil(L, -1)) { lua_remove(L, -2); // set_method, value, obj lua_insert(L, -3); // value, obj, set_method - lua_pushcfunction(L, &LuaScript::luaErrorHandler); // errorfunc, value, obj, set_method - lua_insert(L, -4); // value, obj, set_method, errorfunc - int ret = lua_pcall(L, 2, 0, -4); // errorfunc - if(ret != 0) - g_lua.reportError(g_lua.popString()); // errofunc - lua_pop(L, 1); // (empty) + g_lua.callFunction(2); return 1; } lua_pop(L, 2); // mt, value, obj diff --git a/src/framework/script/luascript.h b/src/framework/script/luascript.h index 2c933cb1..4ffb0a9d 100644 --- a/src/framework/script/luascript.h +++ b/src/framework/script/luascript.h @@ -52,6 +52,7 @@ public: int getStackSize(); void insert(int index); + void swap(int index); void remove(int index); bool next(int index = -2); void releaseRef(int ref); @@ -103,7 +104,9 @@ public: void pushValue(int index = -1); void pushRef(int ref); - void callFunction(int numArgs = 0); + std::string getFunctionSourcePath(); + + bool callFunction(int numArgs = 0, int numRets = 0); void callModuleField(const std::string& module, const std::string& field); typedef int (*LuaCFunction)(); diff --git a/src/framework/ui/uielementskin.cpp b/src/framework/ui/uielementskin.cpp index c867633c..dbca54b2 100644 --- a/src/framework/ui/uielementskin.cpp +++ b/src/framework/ui/uielementskin.cpp @@ -69,7 +69,7 @@ ImagePtr UIElementSkin::loadImage(const YAML::Node& node) std::string textureName = yamlRead(cnode, "source", std::string()); if(!textureName.empty()) - texture = g_textures.get("skins/" + textureName); + texture = g_textures.get(textureName); else texture = g_uiSkins.getDefaultTexture(); @@ -89,7 +89,7 @@ ImagePtr UIElementSkin::loadImage(const YAML::Node& node) if(!image) logError(yamlErrorDesc(cnode, "failed to load bordered image")); } else if(yamlHasValue(node, "image")) { - texture = g_textures.get("skins/" + yamlRead(node, "image")); + texture = g_textures.get(yamlRead(node, "image")); if(texture) image = ImagePtr(new Image(texture)); if(!m_defaultSize.isValid()) diff --git a/src/framework/ui/uiloader.cpp b/src/framework/ui/uiloader.cpp index 0a74bfb9..8bad19d4 100644 --- a/src/framework/ui/uiloader.cpp +++ b/src/framework/ui/uiloader.cpp @@ -30,6 +30,8 @@ #include