rework on resources system

This commit is contained in:
Eduardo Bart 2011-05-19 14:11:05 -03:00
parent e1af35f061
commit ab6c52a3ee
24 changed files with 322 additions and 226 deletions

View File

@ -7,7 +7,7 @@ panel#background:
panel#icos4d:
skin:
image: lightness/mouse.png
image: /skins/lightness/mouse.png
anchors.left: parent.left
anchors.top: parent.top
margin.left: -2
@ -15,7 +15,7 @@ panel#background:
panel#mouse:
skin:
image: lightness/icos4d.png
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

View File

@ -1,6 +1,6 @@
-- menu state
function onEnterMenuState()
mainMenu = UI.load("mainmenu/mainmenu.yml")
mainMenu = UI.load("mainmenu.yml")
end
function onLeaveMenuState()

View File

@ -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

View File

@ -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);

View File

@ -24,6 +24,7 @@
#include <prerequisites.h>
#include <core/resources.h>
#include <core/platform.h>
#include <physfs.h>
@ -32,6 +33,29 @@ Resources g_resources;
void Resources::init(const char *argv0)
{
PHYSFS_init(argv0);
// try to find data directory
std::list<std::string> searchPaths;
std::string dir;
std::string baseDir = PHYSFS_getBaseDir();
std::list<std::string> 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());
return (PHYSFS_exists(resolvePath(fileName).c_str()) && !PHYSFS_isDirectory(resolvePath(fileName).c_str()));
}
bool Resources::directoryExists(const std::string& directoryName)
{
return (PHYSFS_exists(resolvePath(directoryName).c_str()) && PHYSFS_isDirectory(resolvePath(directoryName).c_str()));
}
bool Resources::loadFile(const std::string& fileName, std::iostream& out)
{
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());
*fileSize = 0;
return NULL;
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;
}
*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;
}
std::string Resources::loadTextFile(const std::string& fileName)
{
std::string text;
uint fileSize;
char *buffer = (char *)loadFile(fileName, &fileSize);
if(buffer) {
text.assign(buffer);
delete[] buffer;
}
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;
}
std::list<std::string> Resources::getDirectoryFiles(const std::string& directory)
bool Resources::deleteFile(const std::string& fileName)
{
return PHYSFS_delete(resolvePath(fileName).c_str()) != 0;
}
std::list<std::string> Resources::listDirectoryFiles(const std::string& directoryPath)
{
std::list<std::string> 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<std::string> Resources::getDirectoryFiles(const std::string& directory
PHYSFS_freeList(rc);
return files;
}
void Resources::pushCurrentPath(const std::string &currentPath)
{
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;
}

View File

@ -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<std::string> 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 &currentPath);
void popCurrentPath();
std::string resolvePath(const std::string& path);
/// Get a list with all files in a directory
std::list<std::string> getDirectoryFiles(const std::string& directory);
private:
std::stack<std::string> m_currentPaths;
};
extern Resources g_resources;

View File

@ -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;

View File

@ -30,17 +30,21 @@ Fonts g_fonts;
void Fonts::init()
{
g_resources.pushCurrentPath("fonts");
// load all fonts
std::list<std::string> files = g_resources.getDirectoryFiles("fonts");
std::list<std::string> 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)

View File

@ -28,12 +28,12 @@
#include <util/apngloader.h>
#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));

View File

@ -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

View File

@ -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;
}

View File

@ -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();

View File

@ -55,6 +55,7 @@ typedef int8_t int8;
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <list>

View File

@ -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");

View File

@ -54,9 +54,9 @@ void LuaScript::terminate()
void LuaScript::loadAllModules()
{
std::list<std::string> modules = g_resources.getDirectoryFiles("modules");
std::list<std::string> modules = g_resources.listDirectoryFiles("modules");
foreach(const std::string& module, modules) {
std::list<std::string> moduleFiles = g_resources.getDirectoryFiles(std::string("modules/") + module);
std::list<std::string> 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);
lua_pushcfunction(L, &LuaScript::luaErrorHandler);
lua_insert(L, errorIndex);
std::string path;
int ret = lua_pcall(L, numArgs, 0, errorIndex);
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);
insert(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

View File

@ -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)();

View File

@ -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<std::string>(node, "image"));
texture = g_textures.get(yamlRead<std::string>(node, "image"));
if(texture)
image = ImagePtr(new Image(texture));
if(!m_defaultSize.isValid())

View File

@ -30,6 +30,8 @@
#include <script/luafunctions.h>
#include "uianchorlayout.h"
UILoader g_uiLoader;
UIElementPtr UILoader::createElementFromId(const std::string& id)
{
UIElementPtr element;
@ -65,20 +67,15 @@ UIElementPtr UILoader::createElementFromId(const std::string& id)
return element;
}
UIElementPtr UILoader::loadFile(const std::string& file, const UIContainerPtr& parent)
UIElementPtr UILoader::loadFromYAML(std::string filePath, const UIContainerPtr& parent)
{
// try to find the file
std::string filePath = "modules/" + file;
if(!g_resources.fileExists(filePath))
filePath = "addons/" + file;
if(!g_resources.fileExists(filePath))
filePath = file;
if(!g_resources.fileExists(filePath)) {
flogError("ERROR: Could not load ui file \"%s", file.c_str());
std::stringstream fin;
if(!g_resources.loadFile(filePath, fin)) {
flogError("ERROR: Could not load ui file \"%s", filePath.c_str());
return UIElementPtr();
}
std::istringstream fin(g_resources.loadTextFile(filePath));
m_currentFile = filePath;
try {
YAML::Parser parser(fin);
@ -110,7 +107,7 @@ UIElementPtr UILoader::loadFile(const std::string& file, const UIContainerPtr& p
element->onLoad();
return element;
} catch (YAML::Exception& e) {
flogError("ERROR: Failed to load ui file \"%s\":\n %s", file.c_str() % e.what());
flogError("ERROR: Failed to load ui file \"%s\":\n %s", filePath.c_str() % e.what());
}
return UIElementPtr();
@ -208,7 +205,7 @@ void UILoader::loadElement(const UIElementPtr& element, const YAML::Node& node)
// load events
if(yamlHasValue(node, "onLoad")) {
const YAML::Node& cnode = node["onLoad"];
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), element->getId() + ":onLoad"))
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), getElementSourceDesc(element, "onLoad")))
g_lua.setScriptableField(element, "onLoad");
else
logError(yamlErrorDesc(cnode, "failed to parse inline lua script"));
@ -216,7 +213,7 @@ void UILoader::loadElement(const UIElementPtr& element, const YAML::Node& node)
if(yamlHasValue(node, "onDestroy")) {
const YAML::Node& cnode = node["onDestroy"];
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), element->getId() + ":onDestroy"))
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), getElementSourceDesc(element, "onDestroy")))
g_lua.setScriptableField(element, "onDestroy");
else
logError(yamlErrorDesc(cnode, "failed to parse inline lua script"));
@ -273,9 +270,19 @@ void UILoader::loadButton(const UIButtonPtr& button, const YAML::Node& node)
// set on click event
if(yamlHasValue(node, "onClick")) {
const YAML::Node& cnode = node["onClick"];
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), button->getId() + ":onClick"))
if(g_lua.loadBufferAsFunction(yamlRead<std::string>(cnode), getElementSourceDesc(button, "onClick")))
g_lua.setScriptableField(button, "onClick");
else
logError(yamlErrorDesc(cnode, "failed to parse inline lua script"));
}
}
std::string UILoader::getElementSourceDesc(const UIElementPtr& element, const std::string& key)
{
std::string desc;
desc += g_resources.resolvePath(m_currentFile) + ":" + element->getId();
if(key.length() > 0)
desc += "[" + key + "]";
return desc;
}

View File

@ -34,26 +34,32 @@ class UILoader
{
public:
/// Loads an UIElement and it's children from a YAML file
static UIElementPtr loadFile(const std::string& file, const UIContainerPtr& parent = UIContainer::getRoot());
UIElementPtr loadFromYAML(std::string filePath, const UIContainerPtr& parent = UIContainer::getRoot());
private:
/// Detect element type and create it
static UIElementPtr createElementFromId(const std::string& id);
UIElementPtr createElementFromId(const std::string& id);
/// Populate container children from a YAML node
static void populateContainer(const UIContainerPtr& parent, const YAML::Node& node);
void populateContainer(const UIContainerPtr& parent, const YAML::Node& node);
/// Load element and its children from a YAML node
static void loadElements(const UIElementPtr& parent, const YAML::Node& node);
void loadElements(const UIElementPtr& parent, const YAML::Node& node);
/// Load element proprieties from a YAML node
static void loadElement(const UIElementPtr& element, const YAML::Node& node);
void loadElement(const UIElementPtr& element, const YAML::Node& node);
/// Load anchor from a YAML node
static void loadElementAnchor(const UIElementPtr& anchoredElement, UI::AnchorPoint anchoredEdge, const YAML::Node& node);
void loadElementAnchor(const UIElementPtr& anchoredElement, UI::AnchorPoint anchoredEdge, const YAML::Node& node);
// specific elements loading
static void loadButton(const UIButtonPtr& button, const YAML::Node& node);
void loadButton(const UIButtonPtr& button, const YAML::Node& node);
std::string getElementSourceDesc(const UIElementPtr& element, const std::string& key = "");
std::string m_currentFile;
};
extern UILoader g_uiLoader;
#endif // UILOADER_H

View File

@ -35,13 +35,13 @@
UISkins g_uiSkins;
void UISkins::load(const std::string& skinsFile)
void UISkins::load(const std::string& skinName)
{
std::string fileContents = g_resources.loadTextFile(skinsFile);
if(!fileContents.size())
flogFatal("FATAL ERROR: Could not load skin file \"%s", skinsFile.c_str());
g_resources.pushCurrentPath("skins");
std::istringstream fin(fileContents);
std::stringstream fin;
if(!g_resources.loadFile(skinName + ".yml", fin))
flogFatal("FATAL ERROR: Could not load skin \"%s", skinName.c_str());
try {
YAML::Parser parser(fin);
@ -57,7 +57,7 @@ void UISkins::load(const std::string& skinsFile)
std::string defaultTextureName = yamlRead(doc, "default texture", std::string());
if(!defaultTextureName.empty())
m_defaultTexture = g_textures.get("skins/" + defaultTextureName);
m_defaultTexture = g_textures.get(defaultTextureName);
{
const YAML::Node& node = doc["buttons"];
@ -133,8 +133,10 @@ void UISkins::load(const std::string& skinsFile)
}
}
} catch (YAML::Exception& e) {
flogFatal("FATAL ERROR: Malformed skin file \"%s\":\n %s", skinsFile.c_str() % e.what());
flogFatal("FATAL ERROR: Malformed skin file \"%s\":\n %s", skinName.c_str() % e.what());
}
g_resources.popCurrentPath();
}
void UISkins::terminate()

View File

@ -35,7 +35,7 @@ class UISkins
public:
UISkins() { }
void load(const std::string& skinsFile);
void load(const std::string& skinName);
void terminate();
UIElementSkinPtr getElementSkin(UI::ElementType elementType, const std::string& name = "default");

View File

@ -507,7 +507,7 @@ void compose6(unsigned char * dst, unsigned int dstbytes, unsigned char * src, u
}
}
int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *apng)
int load_apng(std::stringstream& file, struct apng_data *apng)
{
unsigned int i, j;
unsigned int rowbytes;
@ -522,8 +522,6 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
unsigned char coltype, compr, filter, interl;
z_stream zstream;
memset(apng, 0, sizeof(struct apng_data));
std::istringstream f1;
f1.rdbuf()->pubsetbuf((char*)filedata, filesize);
for (i=0; i<256; i++)
{
@ -560,21 +558,21 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
unsigned char * pDst2;
unsigned int * frames_delay;
f1.read((char*)sig, 8);
if(f1.good() && memcmp(sig, png_sign, 8) == 0) {
len = read32(f1);
chunk = read32(f1);
file.read((char*)sig, 8);
if(!file.eof() && memcmp(sig, png_sign, 8) == 0) {
len = read32(file);
chunk = read32(file);
if ((len == 13) && (chunk == 0x49484452)) /* IHDR */
{
w = w0 = read32(f1);
h = h0 = read32(f1);
f1.read((char*)&depth, 1);
f1.read((char*)&coltype, 1);
f1.read((char*)&compr, 1);
f1.read((char*)&filter, 1);
f1.read((char*)&interl, 1);
crc = read32(f1);
w = w0 = read32(file);
h = h0 = read32(file);
file.read((char*)&depth, 1);
file.read((char*)&coltype, 1);
file.read((char*)&compr, 1);
file.read((char*)&filter, 1);
file.read((char*)&interl, 1);
crc = read32(file);
channels = 1;
if (coltype == 2)
@ -616,17 +614,17 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
memset(pOut1, 0, outimg1);
memset(pOut2, 0, outimg2);
while (!f1.eof())
while (!file.eof())
{
len = read32(f1);
chunk = read32(f1);
len = read32(file);
chunk = read32(file);
if (chunk == 0x504C5445) /* PLTE */
{
unsigned int col;
for (i=0; i<len; i++)
{
f1.read((char*)&c, 1);
file.read((char*)&c, 1);
col = i/3;
if (col<256)
{
@ -634,14 +632,14 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
palsize = col+1;
}
}
crc = read32(f1);
crc = read32(file);
}
else if (chunk == 0x74524E53) /* tRNS */
{
hasTRNS = 1;
for (i=0; i<len; i++)
{
f1.read((char*)&c, 1);
file.read((char*)&c, 1);
if (i<256)
{
trns[i] = c;
@ -671,16 +669,16 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
trns[5] = trns[4]; trns[4] = 0;
}
}
crc = read32(f1);
crc = read32(file);
}
else if (chunk == 0x6163544C) /* acTL */
{
frames = read32(f1);
frames = read32(file);
if(frames_delay)
free(frames_delay);
frames_delay = (unsigned int*)malloc(frames*sizeof(int));
loops = read32(f1);
crc = read32(f1);
loops = read32(file);
crc = read32(file);
if (pOut1)
free(pOut1);
if (pOut2)
@ -748,16 +746,16 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
}
}
seq = read32(f1);
w0 = read32(f1);
h0 = read32(f1);
x0 = read32(f1);
y0 = read32(f1);
d1 = read16(f1);
d2 = read16(f1);
f1.read((char*)&dop, 1);
f1.read((char*)&bop, 1);
crc = read32(f1);
seq = read32(file);
w0 = read32(file);
h0 = read32(file);
x0 = read32(file);
y0 = read32(file);
d1 = read16(file);
d2 = read16(file);
file.read((char*)&dop, 1);
file.read((char*)&bop, 1);
crc = read32(file);
if(d2 == 0)
d2 = 100;
@ -780,17 +778,17 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
}
else if (chunk == 0x49444154) /* IDAT */
{
f1.read((char*)(pData + zsize), len);
file.read((char*)(pData + zsize), len);
zsize += len;
crc = read32(f1);
crc = read32(file);
}
else if (chunk == 0x66644154) /* fdAT */
{
seq = read32(f1);
seq = read32(file);
len -= 4;
f1.read((char*)(pData + zsize), len);
file.read((char*)(pData + zsize), len);
zsize += len;
crc = read32(f1);
crc = read32(file);
}
else if (chunk == 0x49454E44) /* IEND */
{
@ -818,8 +816,8 @@ int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *
c = (unsigned char)(chunk & 0xFF);
if (notabc(c)) break;
f1.seekg(len, std::ios_base::cur);
crc = read32(f1);
file.seekg(len, std::ios_base::cur);
crc = read32(file);
}
}
/* apng decoding - end */

View File

@ -25,6 +25,8 @@
#ifndef APNGLOADER_H
#define APNGLOADER_H
#include <sstream>
struct apng_data {
unsigned char *pdata;
unsigned int width;
@ -39,7 +41,7 @@ struct apng_data {
};
// returns -1 on error, 0 on success
int load_apng(unsigned char *filedata, unsigned int filesize, struct apng_data *apng);
int load_apng(std::stringstream& file, struct apng_data *apng);
void free_apng(struct apng_data *apng);
#endif // APNGLOADER_H

View File

@ -101,9 +101,6 @@ int main(int argc, const char *argv[])
// init resources
g_resources.init(args[0].c_str());
if(g_resources.setWriteDir(Platform::getAppUserDir()))
g_resources.addToSearchPath(Platform::getAppUserDir());
g_resources.addToSearchPath("data");
// before loading configurations set the default ones
setDefaultConfigs();
@ -127,7 +124,7 @@ int main(int argc, const char *argv[])
g_engine.enableFpsCounter();
// load ui skins
g_uiSkins.load("skins/lightness.yml");
g_uiSkins.load("lightness");
// load script modules
g_lua.loadAllModules();