Refactoring and flexibility changes

* Split game module into game and game_interface
* Move core_lib to corelib
* Move miniwindow to corelib
* Introduce init.lua script for initializing the client, giving much more flexibility
* OTClient is no longer Application derived and is much simpler
This commit is contained in:
Eduardo Bart
2012-06-19 21:15:56 -03:00
parent 9e72860178
commit 8761220deb
115 changed files with 448 additions and 363 deletions

View File

@@ -10,11 +10,7 @@ OPTION(CRASH_HANDLER "Generate crash reports" ON)
OPTION(LUAJIT "Use lua jit" OFF)
SET(OPENGLES "OFF" CACHE "Use OpenGL ES 1.0 or 2.0 (for mobiles devices)" STRING)
SET(BUILD_REVISION "custom" CACHE "Git revision string (intended for releases)" STRING)
# set debug as default build type
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE RelWithDebInfo)
ENDIF()
SET(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE "Build type (Release, MinSizeRel, RelWithDebInfo or Debug)" STRING)
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
SET(ARCH_FLAGS "-m64 -march=x86-64 -mtune=generic")
@@ -26,10 +22,11 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNS_FLAGS} ${ARCH_
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -ggdb")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O1 -ggdb -fno-omit-frame-pointer")
SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
SET(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -static-libgcc -static-libstdc++ -Wl,--as-needed")
IF(CMAKE_BUILD_TYPE STREQUAL "Release")
IF(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,-s")
ENDIF()

View File

@@ -37,7 +37,7 @@
#include <framework/luascript/luainterface.h>
#include <framework/platform/crashhandler.h>
Application *g_app = nullptr;
Application g_app;
void exitSignalHandler(int sig)
{
@@ -53,18 +53,14 @@ void exitSignalHandler(int sig)
}
}
Application::Application(const std::string& appName)
Application::Application()
{
g_app = this;
m_appName = appName;
m_appName = "application";
m_appCompactName = "app";
m_appVersion = "none";
m_foregroundFrameCounter.setMaxFps(60);
}
Application::~Application()
{
g_app = nullptr;
}
void Application::init(const std::vector<std::string>& args)
{
// capture exit signals
@@ -75,24 +71,28 @@ void Application::init(const std::vector<std::string>& args)
installCrashHandler();
#endif
// initialize lua
g_lua.init();
registerLuaFunctions();
std::string startupOptions;
for(uint i=1;i<args.size();++i) {
const std::string& arg = args[i];
startupOptions += " ";
startupOptions += arg;
}
if(startupOptions.length() > 0)
g_logger.info(stdext::format("Startup options: %s", startupOptions));
m_startupOptions = startupOptions;
// initialize resources
g_resources.init(args[0].c_str());
// setup configs write directory
if(!g_resources.setupWriteDir(m_appName))
g_logger.error("Could not setup write directory");
// initialize lua
g_lua.init();
registerLuaFunctions();
// load configs
if(!g_configs.load("/config.otml"))
g_logger.info("Using default configurations.");
// setup platform window
// initialize ui
g_ui.init();
// setup platform window
g_window.init();
g_window.hide();
g_window.setOnResize(std::bind(&Application::resize, this, std::placeholders::_1));
@@ -105,14 +105,9 @@ void Application::init(const std::vector<std::string>& args)
// initialize sound
g_sounds.init();
// fire first resize
// fire first resize event
resize(g_window.getSize());
// display window when the application starts running
//g_eventDispatcher.addEvent([]{ g_window.show(); });
g_modules.discoverModulesPath();
m_initialized = true;
}
@@ -132,15 +127,15 @@ void Application::deinit()
// poll remaining events
poll();
// destroy any remaining widget
g_ui.terminate();
}
void Application::terminate()
{
assert(m_initialized);
// destroy any remaining widget
g_ui.terminate();
// terminate network
Connection::terminate();
@@ -164,7 +159,7 @@ void Application::terminate()
g_graphics.terminate();
g_window.terminate();
g_logger.info("Application ended successfully.");
g_logger.debug("Application ended successfully.");
m_terminated = true;
}
@@ -184,6 +179,9 @@ void Application::run()
// first clock update
g_clock.update();
// show the application window
g_window.show();
while(!m_stopping) {
// poll all events before rendering
poll();

View File

@@ -34,29 +34,31 @@ class Application
};
public:
Application(const std::string& appName);
~Application();
Application();
virtual void init(const std::vector<std::string>& args);
virtual void registerLuaFunctions();
virtual void deinit();
virtual void terminate();
virtual void run();
virtual void exit();
virtual void poll();
virtual void close();
void init(const std::vector<std::string>& args);
void deinit();
void terminate();
void run();
void exit();
void poll();
void close();
bool willRepaint() { return m_mustRepaint; }
void repaint() { m_mustRepaint = true; }
void setForegroundPaneMaxFps(int maxFps) { m_foregroundFrameCounter.setMaxFps(maxFps); }
void setBackgroundPaneMaxFps(int maxFps) { m_backgroundFrameCounter.setMaxFps(maxFps); }
void setName(const std::string& name) { m_appName = name; }
void setCompactName(const std::string& compactName) { m_appCompactName = compactName; }
void setVersion(const std::string& version) { m_appVersion = version; }
bool isRunning() { return m_running; }
bool isStopping() { return m_stopping; }
bool isTermianted() { return m_terminated; }
bool isOnInputEvent() { return m_onInputEvent; }
const std::string& getName() { return m_appName; }
const std::string& getCompactName() { return m_appCompactName; }
const std::string& getVersion() { return m_appVersion; }
int getForegroundPaneFps() { return m_foregroundFrameCounter.getLastFps(); }
@@ -67,14 +69,17 @@ public:
std::string getBuildDate() { return BUILD_DATE; }
std::string getBuildRevision() { return BUILD_REVISION; }
std::string getBuildType() { return BUILD_TYPE; }
std::string getStartupOptions() { return m_startupOptions; }
protected:
virtual void resize(const Size& size);
virtual void inputEvent(const InputEvent& event);
void resize(const Size& size);
void inputEvent(const InputEvent& event);
void registerLuaFunctions();
std::string m_appName;
std::string m_appCompactName;
std::string m_appVersion;
std::string m_appBuildDate;
std::string m_startupOptions;
Boolean<false> m_initialized;
Boolean<false> m_running;
Boolean<false> m_stopping;
@@ -86,7 +91,7 @@ protected:
TexturePtr m_foreground;
};
extern Application *g_app;
extern Application g_app;
#endif

View File

@@ -45,7 +45,7 @@ bool ConfigManager::load(const std::string& file)
m_confsDoc = confsDoc;
return true;
} catch(stdext::exception& e) {
g_logger.error(stdext::format("Unable to load configuration file: %s", e.what()));
g_logger.error(stdext::format("Unable to parse configuration file '%s'", e.what()));
return false;
}
}

View File

@@ -33,7 +33,7 @@ public:
Event(const std::function<void()>& callback) : m_callback(callback), m_canceled(false), m_executed(false) { }
virtual ~Event() {
// assure that we lost callback refs
assert(m_callback == nullptr);
//assert(m_callback == nullptr);
}
virtual void execute() {

View File

@@ -28,6 +28,11 @@ Logger g_logger;
void Logger::log(Fw::LogLevel level, const std::string& message)
{
#ifdef NDEBUG
if(level == Fw::LogDebug)
return;
#endif
static bool ignoreLogs = false;
if(ignoreLogs)
return;

View File

@@ -53,7 +53,7 @@ bool Module::load()
m_loadCallback();
m_loaded = true;
//g_logger.info(stdext::format("Loaded module '%s'", m_name));
g_logger.debug(stdext::format("Loaded module '%s'", m_name));
g_modules.updateModuleLoadOrder(asModule());
for(const std::string& modName : m_loadLaterModules) {

View File

@@ -64,44 +64,6 @@ void ModuleManager::autoLoadModules(int maxPriority)
}
}
void ModuleManager::discoverModulesPath()
{
// search for modules directory
std::string possibleModulesDirs[] = { "modules",
g_resources.getBaseDir() + "modules",
g_resources.getBaseDir() + "../modules",
g_resources.getBaseDir() + "../share/" + g_app->getName() + "/modules",
"" };
bool found = false;
for(const std::string& dir : possibleModulesDirs) {
// try to add module directory
if(g_resources.addToSearchPath(dir, false)) {
//g_logger.info(stdext::format("Using modules directory '%s'", dir.c_str()));
m_modulesPath = dir;
found = true;
break;
}
}
if(!found)
g_logger.fatal("Could not find modules directory");
// search for addons directory
std::string possibleAddonsDirs[] = { "addons",
g_resources.getBaseDir() + "addons",
g_resources.getBaseDir() + "../addons",
g_resources.getBaseDir() + "../share/" + g_app->getName() + "/addons",
"" };
for(const std::string& dir : possibleAddonsDirs) {
// try to add module directory
if(g_resources.addToSearchPath(dir, true)) {
//g_logger.info(stdext::format("Using addons directory '%s'", dir.c_str()));
found = true;
break;
}
}
}
ModulePtr ModuleManager::discoverModule(const std::string& moduleFile)
{
ModulePtr module;

View File

@@ -30,14 +30,12 @@ class ModuleManager
public:
void clear();
void discoverModulesPath();
void discoverModules();
void autoLoadModules(int maxPriority);
ModulePtr discoverModule(const std::string& moduleFile);
void ensureModuleLoaded(const std::string& moduleName);
void unloadModules();
void reloadModules();
std::string getModulesPath() { return m_modulesPath; }
ModulePtr getModule(const std::string& moduleName);
std::deque<ModulePtr> getModules() { return m_modules; }
@@ -48,7 +46,6 @@ protected:
friend class Module;
private:
std::string m_modulesPath;
std::deque<ModulePtr> m_modules;
std::multimap<int, ModulePtr> m_autoLoadModules;
};

View File

@@ -40,22 +40,58 @@ void ResourceManager::terminate()
PHYSFS_deinit();
}
void ResourceManager::discoverWorkDir(const std::string& appName, const std::string& existentFile)
{
// search for modules directory
std::string sep = PHYSFS_getDirSeparator();
std::string possiblePaths[] = { "",
g_resources.getBaseDir(),
g_resources.getBaseDir() + ".." + sep,
g_resources.getBaseDir() + ".." + sep + "share" + sep + appName + sep,
g_resources.getBaseDir() + appName + sep };
bool found = false;
for(const std::string& dir : possiblePaths) {
// try to directory to modules path to see if it exists
std::ifstream fin(dir + existentFile);
if(fin) {
g_logger.debug(stdext::format("Found work dir at '%s'", dir.c_str()));
m_workDir = dir;
found = true;
break;
}
}
if(!found)
g_logger.fatal("Unable to find application work directory.");
}
bool ResourceManager::setupWriteDir(const std::string& appWriteDirName)
{
std::string userDir = PHYSFS_getUserDir();
std::string dirName = stdext::format(".%s", appWriteDirName);
std::string dirName;
#ifndef WIN32
dirName = stdext::format(".%s", appWriteDirName);
#else
dirName = appWriteDirName;
#endif
std::string writeDir = userDir + dirName;
if(!PHYSFS_setWriteDir(writeDir.c_str())) {
if(!PHYSFS_setWriteDir(userDir.c_str()))
return false;
if(!PHYSFS_mkdir(dirName.c_str())) {
PHYSFS_setWriteDir(NULL);
if(!PHYSFS_setWriteDir(userDir.c_str())) {
g_logger.error("User directory not found.");
return false;
}
if(!PHYSFS_setWriteDir(writeDir.c_str()))
if(!PHYSFS_mkdir(dirName.c_str())) {
g_logger.error("Cannot create directory for saving configurations.");
return false;
}
if(!PHYSFS_setWriteDir(writeDir.c_str())) {
g_logger.error("Unable to set write directory.");
return false;
}
}
addToSearchPath(writeDir);
addToSearchPath(writeDir, true);
//g_logger.debug(stdext::format("Setup write dir %s", writeDir));
return true;
}
@@ -63,6 +99,8 @@ bool ResourceManager::addToSearchPath(const std::string& path, bool insertInFron
{
if(!PHYSFS_addToSearchPath(path.c_str(), insertInFront ? 0 : 1))
return false;
//g_logger.debug(stdext::format("Add search path %s", path));
m_hasSearchPath = true;
return true;
}
@@ -70,6 +108,7 @@ bool ResourceManager::removeFromSearchPath(const std::string& path)
{
if(!PHYSFS_removeFromSearchPath(path.c_str()))
return false;
//g_logger.debug(stdext::format("Remove search path %s", path));
return true;
}
@@ -94,22 +133,32 @@ bool ResourceManager::directoryExists(const std::string& directoryName)
void ResourceManager::loadFile(const std::string& fileName, std::iostream& out)
{
std::string fullPath = resolvePath(fileName);
out.clear(std::ios::goodbit);
PHYSFS_file* file = PHYSFS_openRead(fullPath.c_str());
if(!file) {
out.clear(std::ios::failbit);
stdext::throw_exception(stdext::format("failed to load file '%s': %s", fullPath.c_str(), PHYSFS_getLastError()));
if(m_hasSearchPath) {
std::string fullPath = resolvePath(fileName);
PHYSFS_file* file = PHYSFS_openRead(fullPath.c_str());
if(!file) {
out.clear(std::ios::failbit);
stdext::throw_exception(stdext::format("failed to load file '%s': %s", fullPath.c_str(), PHYSFS_getLastError()));
} else {
int fileSize = PHYSFS_fileLength(file);
if(fileSize > 0) {
std::vector<char> buffer(fileSize);
PHYSFS_read(file, (void*)&buffer[0], 1, fileSize);
out.write(&buffer[0], fileSize);
} else
out.clear(std::ios::eofbit);
PHYSFS_close(file);
out.seekg(0, std::ios::beg);
}
} else {
int fileSize = PHYSFS_fileLength(file);
if(fileSize > 0) {
std::vector<char> buffer(fileSize);
PHYSFS_read(file, (void*)&buffer[0], 1, fileSize);
out.write(&buffer[0], fileSize);
} else
out.clear(std::ios::eofbit);
PHYSFS_close(file);
out.seekg(0, std::ios::beg);
std::ifstream fin(fileName);
if(!fin) {
out.clear(std::ios::failbit);
stdext::throw_exception(stdext::format("failed to load file '%s': %s", fileName.c_str(), PHYSFS_getLastError()));
} else {
out << fin.rdbuf();
}
}
}
@@ -223,6 +272,15 @@ std::string ResourceManager::resolvePath(const std::string& path)
return fullPath;
}
std::string ResourceManager::getRealDir(const std::string& path)
{
std::string dir;
const char *cdir = PHYSFS_getRealDir(path.c_str());
if(cdir)
dir = cdir;
return dir;
}
std::string ResourceManager::getBaseDir()
{
return PHYSFS_getBaseDir();

View File

@@ -31,6 +31,7 @@ public:
void init(const char *argv0);
void terminate();
void discoverWorkDir(const std::string& appName, const std::string& existentFile);
bool setupWriteDir(const std::string& appWriteDirName);
bool addToSearchPath(const std::string& path, bool insertInFront = true);
@@ -55,7 +56,13 @@ public:
std::list<std::string> listDirectoryFiles(const std::string& directoryPath = "");
std::string resolvePath(const std::string& path);
std::string getRealDir(const std::string& path);
std::string getBaseDir();
std::string getWorkDir() { return m_workDir; }
private:
std::string m_workDir;
Boolean<false> m_hasSearchPath;
};
extern ResourceManager g_resources;

View File

@@ -47,7 +47,7 @@ void FrameBuffer::internalCreate()
FrameBuffer::~FrameBuffer()
{
assert(!g_app->isTermianted());
assert(!g_app.isTermianted());
if(g_graphics.ok() && m_fbo != 0)
glDeleteFramebuffers(1, &m_fbo);
}

View File

@@ -37,7 +37,7 @@ HardwareBuffer::HardwareBuffer(Type type)
HardwareBuffer::~HardwareBuffer()
{
assert(!g_app->isTermianted());
assert(!g_app.isTermianted());
if(g_graphics.ok())
glDeleteBuffers(1, &m_id);
}

View File

@@ -44,7 +44,7 @@ Shader::Shader(Shader::ShaderType shaderType)
Shader::~Shader()
{
assert(!g_app->isTermianted());
assert(!g_app.isTermianted());
if(g_graphics.ok())
glDeleteShader(m_shaderId);
}

View File

@@ -38,7 +38,7 @@ ShaderProgram::ShaderProgram()
ShaderProgram::~ShaderProgram()
{
assert(!g_app->isTermianted());
assert(!g_app.isTermianted());
if(g_graphics.ok())
glDeleteProgram(m_programId);
}

View File

@@ -79,7 +79,7 @@ Texture::Texture(const ImagePtr& image, bool buildMipmaps)
Texture::~Texture()
{
assert(!g_app->isTermianted());
assert(!g_app.isTermianted());
// free texture from gl memory
if(g_graphics.ok() && m_id != 0)
glDeleteTextures(1, &m_id);

View File

@@ -20,8 +20,8 @@
* THE SOFTWARE.
*/
#include "application.h"
#include <framework/luascript/luainterface.h>
#include <framework/application.h>
#include <framework/graphics/fontmanager.h>
#include <framework/ui/ui.h>
#include <framework/net/protocol.h>
@@ -480,35 +480,41 @@ void Application::registerLuaFunctions()
// Application
g_lua.registerSingletonClass("g_app");
g_lua.bindSingletonFunction("g_app", "exit", &Application::exit, g_app);
g_lua.bindSingletonFunction("g_app", "setForegroundPaneMaxFps", &Application::setForegroundPaneMaxFps, g_app);
g_lua.bindSingletonFunction("g_app", "setBackgroundPaneMaxFps", &Application::setBackgroundPaneMaxFps, g_app);
g_lua.bindSingletonFunction("g_app", "isRunning", &Application::isRunning, g_app);
g_lua.bindSingletonFunction("g_app", "isStopping", &Application::isStopping, g_app);
g_lua.bindSingletonFunction("g_app", "isOnInputEvent", &Application::isOnInputEvent, g_app);
g_lua.bindSingletonFunction("g_app", "getName", &Application::getName, g_app);
g_lua.bindSingletonFunction("g_app", "getVersion", &Application::getVersion, g_app);
g_lua.bindSingletonFunction("g_app", "getForegroundPaneFps", &Application::getForegroundPaneFps, g_app);
g_lua.bindSingletonFunction("g_app", "getBackgroundPaneFps", &Application::getBackgroundPaneFps, g_app);
g_lua.bindSingletonFunction("g_app", "getForegroundPaneMaxFps", &Application::getForegroundPaneMaxFps, g_app);
g_lua.bindSingletonFunction("g_app", "getBackgroundPaneMaxFps", &Application::getBackgroundPaneMaxFps, g_app);
g_lua.bindSingletonFunction("g_app", "getBuildCompiler", &Application::getBuildCompiler, g_app);
g_lua.bindSingletonFunction("g_app", "getBuildDate", &Application::getBuildDate, g_app);
g_lua.bindSingletonFunction("g_app", "getBuildRevision", &Application::getBuildRevision, g_app);
g_lua.bindSingletonFunction("g_app", "getBuildType", &Application::getBuildType, g_app);
g_lua.bindSingletonFunction("g_app", "exit", &Application::exit, g_app);
g_lua.bindSingletonFunction("g_app", "isRunning", &Application::isRunning, g_app);
g_lua.bindSingletonFunction("g_app", "isStopping", &Application::isStopping, g_app);
g_lua.bindSingletonFunction("g_app", "getName", &Application::getName, g_app);
g_lua.bindSingletonFunction("g_app", "getVersion", &Application::getVersion, g_app);
g_lua.bindSingletonFunction("g_app", "getBuildCompiler", &Application::getBuildCompiler, g_app);
g_lua.bindSingletonFunction("g_app", "getBuildDate", &Application::getBuildDate, g_app);
g_lua.bindSingletonFunction("g_app", "getBuildRevision", &Application::getBuildRevision, g_app);
g_lua.bindSingletonFunction("g_app", "getBuildType", &Application::getBuildType, g_app);
g_lua.bindSingletonFunction("g_app", "exit", &Application::exit, &g_app);
g_lua.bindSingletonFunction("g_app", "setForegroundPaneMaxFps", &Application::setForegroundPaneMaxFps, &g_app);
g_lua.bindSingletonFunction("g_app", "setBackgroundPaneMaxFps", &Application::setBackgroundPaneMaxFps, &g_app);
g_lua.bindSingletonFunction("g_app", "setName", &Application::setName, &g_app);
g_lua.bindSingletonFunction("g_app", "setCompactName", &Application::setCompactName, &g_app);
g_lua.bindSingletonFunction("g_app", "setVersion", &Application::setVersion, &g_app);
g_lua.bindSingletonFunction("g_app", "isRunning", &Application::isRunning, &g_app);
g_lua.bindSingletonFunction("g_app", "isStopping", &Application::isStopping, &g_app);
g_lua.bindSingletonFunction("g_app", "isOnInputEvent", &Application::isOnInputEvent, &g_app);
g_lua.bindSingletonFunction("g_app", "getName", &Application::getName, &g_app);
g_lua.bindSingletonFunction("g_app", "getCompactName", &Application::getName, &g_app);
g_lua.bindSingletonFunction("g_app", "getVersion", &Application::getVersion, &g_app);
g_lua.bindSingletonFunction("g_app", "getForegroundPaneFps", &Application::getForegroundPaneFps, &g_app);
g_lua.bindSingletonFunction("g_app", "getBackgroundPaneFps", &Application::getBackgroundPaneFps, &g_app);
g_lua.bindSingletonFunction("g_app", "getForegroundPaneMaxFps", &Application::getForegroundPaneMaxFps, &g_app);
g_lua.bindSingletonFunction("g_app", "getBackgroundPaneMaxFps", &Application::getBackgroundPaneMaxFps, &g_app);
g_lua.bindSingletonFunction("g_app", "getBuildCompiler", &Application::getBuildCompiler, &g_app);
g_lua.bindSingletonFunction("g_app", "getBuildDate", &Application::getBuildDate, &g_app);
g_lua.bindSingletonFunction("g_app", "getBuildRevision", &Application::getBuildRevision, &g_app);
g_lua.bindSingletonFunction("g_app", "getBuildType", &Application::getBuildType, &g_app);
g_lua.bindSingletonFunction("g_app", "exit", &Application::exit, &g_app);
g_lua.bindSingletonFunction("g_app", "isRunning", &Application::isRunning, &g_app);
g_lua.bindSingletonFunction("g_app", "isStopping", &Application::isStopping, &g_app);
g_lua.bindSingletonFunction("g_app", "getName", &Application::getName, &g_app);
g_lua.bindSingletonFunction("g_app", "getCompactName", &Application::getCompactName, &g_app);
g_lua.bindSingletonFunction("g_app", "getVersion", &Application::getVersion, &g_app);
g_lua.bindSingletonFunction("g_app", "getBuildCompiler", &Application::getBuildCompiler, &g_app);
g_lua.bindSingletonFunction("g_app", "getBuildDate", &Application::getBuildDate, &g_app);
g_lua.bindSingletonFunction("g_app", "getBuildRevision", &Application::getBuildRevision, &g_app);
g_lua.bindSingletonFunction("g_app", "getBuildType", &Application::getBuildType, &g_app);
// ConfigManager
g_lua.registerSingletonClass("g_configs");
g_lua.bindSingletonFunction("g_configs", "load", &ConfigManager::load, &g_configs);
g_lua.bindSingletonFunction("g_configs", "save", &ConfigManager::save, &g_configs);
g_lua.bindSingletonFunction("g_configs", "set", &ConfigManager::set, &g_configs);
g_lua.bindSingletonFunction("g_configs", "setList", &ConfigManager::setList, &g_configs);
g_lua.bindSingletonFunction("g_configs", "get", &ConfigManager::get, &g_configs);
@@ -574,7 +580,13 @@ void Application::registerLuaFunctions()
g_lua.registerSingletonClass("g_logger");
g_lua.bindSingletonFunction("g_logger", "log", &Logger::log, &g_logger);
g_lua.bindSingletonFunction("g_logger", "fireOldMessages", &Logger::fireOldMessages, &g_logger);
g_lua.bindSingletonFunction("g_logger", "setLogFile", &Logger::setLogFile, &g_logger);
g_lua.bindSingletonFunction("g_logger", "setOnLog", &Logger::setOnLog, &g_logger);
g_lua.bindSingletonFunction("g_logger", "debug", &Logger::debug, &g_logger);
g_lua.bindSingletonFunction("g_logger", "info", &Logger::info, &g_logger);
g_lua.bindSingletonFunction("g_logger", "warning", &Logger::warning, &g_logger);
g_lua.bindSingletonFunction("g_logger", "error", &Logger::error, &g_logger);
g_lua.bindSingletonFunction("g_logger", "fatal", &Logger::fatal, &g_logger);
// UI
g_lua.registerSingletonClass("g_ui");
@@ -593,7 +605,6 @@ void Application::registerLuaFunctions()
// ModuleManager
g_lua.registerSingletonClass("g_modules");
g_lua.bindSingletonFunction("g_modules", "discoverModulesPath", &ModuleManager::discoverModulesPath, &g_modules);
g_lua.bindSingletonFunction("g_modules", "discoverModules", &ModuleManager::discoverModules, &g_modules);
g_lua.bindSingletonFunction("g_modules", "autoLoadModules", &ModuleManager::autoLoadModules, &g_modules);
g_lua.bindSingletonFunction("g_modules", "discoverModule", &ModuleManager::discoverModule, &g_modules);
@@ -602,7 +613,6 @@ void Application::registerLuaFunctions()
g_lua.bindSingletonFunction("g_modules", "reloadModules", &ModuleManager::reloadModules, &g_modules);
g_lua.bindSingletonFunction("g_modules", "getModule", &ModuleManager::getModule, &g_modules);
g_lua.bindSingletonFunction("g_modules", "getModules", &ModuleManager::getModules, &g_modules);
g_lua.bindSingletonFunction("g_modules", "getModulesPath", &ModuleManager::getModulesPath, &g_modules);
// FontManager
g_lua.registerSingletonClass("g_fonts");
@@ -633,11 +643,9 @@ void Application::registerLuaFunctions()
// ResourceManager
g_lua.registerSingletonClass("g_resources");
g_lua.bindSingletonFunction("g_resources", "addToSearchPath", &ResourceManager::addToSearchPath, &g_resources);
g_lua.bindSingletonFunction("g_resources", "setupWriteDir", &ResourceManager::setupWriteDir, &g_resources);
g_lua.bindSingletonFunction("g_resources", "removeFromSearchPath", &ResourceManager::removeFromSearchPath, &g_resources);
g_lua.bindSingletonFunction("g_resources", "fileExists", &ResourceManager::fileExists, &g_resources);
// LuaInterface
g_lua.registerSingletonClass("g_lua");
g_lua.bindSingletonFunction("g_lua", "getCurrentSourcePath", &LuaInterface::getCurrentSourcePath, &g_lua);
g_lua.bindSingletonFunction("g_resources", "getRealDir", &ResourceManager::getRealDir, &g_resources);
g_lua.bindSingletonFunction("g_resources", "getWorkDir", &ResourceManager::getWorkDir, &g_resources);
}

View File

@@ -292,6 +292,17 @@ int LuaInterface::luaObjectCollectEvent(LuaInterface* lua)
///////////////////////////////////////////////////////////////////////////////
bool LuaInterface::safeRunScript(const std::string& fileName)
{
try {
runScript(fileName);
return true;
} catch(LuaException& e) {
g_logger.error(stdext::format("Failed to load script '%s': %s", fileName, e.what()));
return false;
}
}
void LuaInterface::runScript(const std::string& fileName)
{
loadScript(fileName);
@@ -312,7 +323,7 @@ void LuaInterface::loadScript(const std::string& fileName)
filePath = getCurrentSourcePath() + "/" + filePath;
try {
std::string buffer = g_resources.loadFile(filePath);
std::string buffer = g_resources.loadFile(fileName);
std::string source = "@" + filePath;
loadBuffer(buffer, source);
} catch(stdext::exception& e) {

View File

@@ -132,6 +132,9 @@ private:
static int luaObjectCollectEvent(LuaInterface* lua);
public:
/// Loads and runs a script, any errors are printed to stdout and returns false
bool safeRunScript(const std::string& fileName);
/// Loads and runs a script
/// @exception LuaException is thrown on any lua error
void runScript(const std::string& fileName);

View File

@@ -31,7 +31,7 @@ LuaObject::LuaObject() : m_fieldsTableRef(-1)
LuaObject::~LuaObject()
{
assert(!g_app->isTermianted());
assert(!g_app.isTermianted());
releaseLuaFieldsTable();
}

View File

@@ -41,7 +41,7 @@ Connection::Connection() :
Connection::~Connection()
{
assert(!g_app->isTermianted());
assert(!g_app.isTermianted());
close();
}

View File

@@ -41,8 +41,8 @@ void crashHandler(int signum, siginfo_t* info, void* secret)
g_logger.error("Application crashed");
std::stringstream ss;
ss << stdext::format("app name: %s\n", g_app->getName());
ss << stdext::format("app version: %s\n", g_app->getVersion());
ss << stdext::format("app name: %s\n", g_app.getName());
ss << stdext::format("app version: %s\n", g_app.getVersion());
ss << stdext::format("build compiler: %s\n", BUILD_COMPILER);
ss << stdext::format("build date: %s\n", BUILD_DATE);
ss << stdext::format("build type: %s\n", BUILD_TYPE);

View File

@@ -111,8 +111,8 @@ LONG CALLBACK ExceptionHandler(LPEXCEPTION_POINTERS e)
SymInitialize(GetCurrentProcess(), 0, TRUE);
std::stringstream ss;
ss << "== application crashed\n";
ss << stdext::format("app name: %s\n", g_app->getName().c_str());
ss << stdext::format("app version: %s\n", g_app->getVersion().c_str());
ss << stdext::format("app name: %s\n", g_app.getName().c_str());
ss << stdext::format("app version: %s\n", g_app.getVersion().c_str());
ss << stdext::format("build compiler: %s\n", BUILD_COMPILER);
ss << stdext::format("build date: %s\n", BUILD_DATE);
ss << stdext::format("build type: %s\n", BUILD_TYPE);

View File

@@ -230,7 +230,7 @@ void WIN32Window::terminate()
}
if(m_instance) {
if(!UnregisterClassA(g_app->getName().c_str(), m_instance))
if(!UnregisterClassA(g_app.getName().c_str(), m_instance))
g_logger.error("UnregisterClassA failed");
m_instance = NULL;
}
@@ -256,7 +256,7 @@ void WIN32Window::internalCreateWindow()
wc.hCursor = m_defaultCursor;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_app->getName().c_str();
wc.lpszClassName = g_app.getName().c_str();
if(!RegisterClassA(&wc))
g_logger.fatal("Failed to register the window class.");
@@ -272,7 +272,7 @@ void WIN32Window::internalCreateWindow()
updateUnmaximizedCoords();
m_window = CreateWindowExA(dwExStyle,
g_app->getName().c_str(),
g_app.getName().c_str(),
NULL,
dwStyle,
windowRect.left,

View File

@@ -336,7 +336,7 @@ void UIManager::importStyleFromOTML(const OTMLNodePtr& styleNode)
}
// Warn about redefined styles
if(!g_app->isRunning() && !unique) {
if(!g_app.isRunning() && !unique) {
auto it = m_styles.find(name);
if(it != m_styles.end())
g_logger.warning(stdext::format("style '%s' is being redefined", name));

View File

@@ -253,7 +253,7 @@ void UITextEdit::setCursorPos(int pos)
else
m_cursorPos = pos;
update();
g_app->repaint();
g_app.repaint();
}
}
@@ -516,5 +516,5 @@ bool UITextEdit::onMousePress(const Point& mousePos, Fw::MouseButton button)
void UITextEdit::blinkCursor()
{
m_cursorTicks = g_clock.millis();
g_app->repaint();
g_app.repaint();
}

View File

@@ -46,7 +46,7 @@ UIWidget::UIWidget()
UIWidget::~UIWidget()
{
assert(!g_app->isTermianted());
assert(!g_app.isTermianted());
#ifdef DEBUG
if(!m_destroyed)
g_logger.warning(stdext::format("widget '%s' was not explicitly destroyed", m_id));
@@ -1375,7 +1375,7 @@ void UIWidget::onStyleApply(const std::string& styleName, const OTMLNodePtr& sty
parseImageStyle(styleNode);
parseTextStyle(styleNode);
g_app->repaint();
g_app.repaint();
}
void UIWidget::onGeometryChange(const Rect& oldRect, const Rect& newRect)
@@ -1391,7 +1391,7 @@ void UIWidget::onGeometryChange(const Rect& oldRect, const Rect& newRect)
callLuaField("onGeometryChange", oldRect, newRect);
g_app->repaint();
g_app.repaint();
}
void UIWidget::onLayoutUpdate()

View File

@@ -94,7 +94,7 @@ void UIWidget::drawText(const Rect& screenCoords)
void UIWidget::onTextChange(const std::string& text, const std::string& oldText)
{
g_app->repaint();
g_app.repaint();
callLuaField("onTextChange", text, oldText);
}

View File

@@ -20,15 +20,32 @@
* THE SOFTWARE.
*/
#include <otclient/otclient.h>
#include "framework/application.h"
#include "framework/luascript/luainterface.h"
#include "framework/core/resourcemanager.h"
#include "otclient/otclient.h"
int main(int argc, const char* argv[])
{
std::vector<std::string> args(argv, argv + argc);
OTClient app;
app.init(args);
app.run();
app.deinit();
app.terminate();
// initialize application framework and otclient
g_app.init(args);
g_otclient.init(args);
// find script init.lua and run it
g_resources.discoverWorkDir("otclient", "init.lua");
if(!g_lua.safeRunScript(g_resources.getWorkDir() + "init.lua"))
g_logger.fatal("Unable to run script init.lua!");
// the run application main loop
g_app.run();
// unload modules
g_app.deinit();
// terminate everything and free memory
g_otclient.terminate();
g_app.terminate();
return 0;
}

View File

@@ -25,10 +25,6 @@
namespace Otc
{
constexpr const char* AppName = "OTClient";
constexpr const char* AppCompactName = "otclient";
constexpr const char* AppVersion = "0.4.0_dev";
enum {
TILE_PIXELS = 32,
MAX_ELEVATION = 24,

View File

@@ -1033,7 +1033,7 @@ bool Game::checkBotProtection()
#ifdef BOT_PROTECTION
// accepts calls comming from a stacktrace containing only C++ functions,
// if the stacktrace contains a lua function, then only accept if the engine is processing an input event
if(m_denyBotCall && g_lua.isInCppCallback() && !g_app->isOnInputEvent()) {
if(m_denyBotCall && g_lua.isInCppCallback() && !g_app.isOnInputEvent()) {
g_logger.error(g_lua.traceback("caught a lua call to a bot protected game function, the call was canceled"));
return false;
}

View File

@@ -52,13 +52,15 @@ void Map::notificateTileUpdateToMapViews(const Position& pos)
mapView->onTileUpdate(pos);
}
void Map::load()
bool Map::load(const std::string& fileName)
{
if(!g_resources.fileExists("/map.otcmap"))
return;
if(!g_resources.fileExists(fileName)) {
g_logger.error(stdext::format("Unable to load map '%s'", fileName));
return false;
}
std::stringstream in;
g_resources.loadFile("/map.otcmap", in);
g_resources.loadFile(fileName, in);
while(!in.eof()) {
Position pos;
@@ -77,9 +79,11 @@ void Map::load()
in.read((char*)&id, sizeof(id));
}
}
return true;
}
void Map::save()
void Map::save(const std::string& fileName)
{
std::stringstream out;
@@ -104,7 +108,7 @@ void Map::save()
out.write((char*)&id, sizeof(id));
}
g_resources.saveFile("/map.otcmap", out);
g_resources.saveFile(fileName, out);
}
void Map::clean()

View File

@@ -34,8 +34,8 @@ public:
void removeMapView(const MapViewPtr& mapView);
void notificateTileUpdateToMapViews(const Position& pos);
void load();
void save();
bool load(const std::string& fileName);
void save(const std::string& fileName);
void clean();
void cleanDynamicThings();
void cleanTexts();

View File

@@ -51,7 +51,7 @@ MapView::MapView()
MapView::~MapView()
{
assert(!g_app->isTermianted());
assert(!g_app.isTermianted());
}
void MapView::draw(const Rect& rect)

View File

@@ -47,8 +47,6 @@
void OTClient::registerLuaFunctions()
{
Application::registerLuaFunctions();
g_lua.registerSingletonClass("g_thingsType");
g_lua.bindSingletonFunction("g_thingsType", "load", &ThingsType::load, &g_thingsType);
g_lua.bindSingletonFunction("g_thingsType", "isLoaded", &ThingsType::isLoaded, &g_thingsType);
@@ -78,6 +76,8 @@ void OTClient::registerLuaFunctions()
g_lua.bindSingletonFunction("g_map", "removeCreatureById", &Map::removeCreatureById, &g_map);
g_lua.bindSingletonFunction("g_map", "getSpectators", &Map::getSpectators, &g_map);
g_lua.bindSingletonFunction("g_map", "findPath", &Map::findPath, &g_map);
g_lua.bindSingletonFunction("g_map", "load", &Map::load, &g_map);
g_lua.bindSingletonFunction("g_map", "save", &Map::save, &g_map);
g_lua.registerSingletonClass("g_game");
g_lua.bindSingletonFunction("g_game", "loginWorld", &Game::loginWorld, &g_game);
@@ -327,6 +327,7 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassMemberFunction<Tile>("addThing", &Tile::addThing);
g_lua.bindClassMemberFunction<Tile>("getThing", &Tile::getThing);
g_lua.bindClassMemberFunction<Tile>("getThingStackpos", &Tile::getThingStackpos);
g_lua.bindClassMemberFunction<Tile>("getThingCount", &Tile::getThingCount);
g_lua.bindClassMemberFunction<Tile>("getTopThing", &Tile::getTopThing);
g_lua.bindClassMemberFunction<Tile>("removeThing", &Tile::removeThing);
g_lua.bindClassMemberFunction<Tile>("getTopLookThing", &Tile::getTopLookThing);

View File

@@ -24,94 +24,55 @@
#include <framework/core/modulemanager.h>
#include <framework/core/resourcemanager.h>
#include <framework/graphics/graphics.h>
#include "core/game.h"
#include "core/map.h"
#include "core/shadermanager.h"
#include <otclient/core/game.h>
#include <otclient/core/map.h>
#include <otclient/core/shadermanager.h>
#include <framework/core/configmanager.h>
OTClient::OTClient() : Application(Otc::AppCompactName)
{
m_appVersion = Otc::AppVersion;
}
OTClient g_otclient;
void OTClient::init(const std::vector<std::string>& args)
{
std::string startupOptions;
for(uint i=1;i<args.size();++i) {
const std::string& arg = args[i];
startupOptions += " ";
startupOptions += arg;
if(g_graphics.parseOption(arg))
continue;
if(arg == "-version" || arg == "--version" || arg == "-v") {
stdext::print(
Otc::AppName, " ", Otc::AppVersion, "\n"
"Buitt on: ", BUILD_DATE, "\n",
"Revision: ", BUILD_REVISION, "\n",
"Compiled by: ", BUILD_COMPILER, "\n",
"Build type: ", BUILD_TYPE, "\n");
return;
} else if(arg == "-help" || arg == "--help" || arg == "-h" || arg == "-?" || arg == "/?") {
stdext::print(
"Usage: ", args[0], " [options]\n"
"Options:\n"
" -help Display this information and exit\n"
" -version Display version and exit\n"
" \n"
" -no-fbos Disable usage of opengl framebuffer objects\n"
" -no-mipmaps Disable texture mipmaping\n"
" -no-smooth Disable texture smoothing (bilinear filter)\n"
" -no-non-power-of-two-textures Use only power of two textures\n"
" -no-clamp-to-edge Don't use GL_CLAMP_TO_EDGE\n"
" -no-backbuffer-cache Don't allow backbuffer caching\n"
" -hardware-buffers Cache vertex arrays in hardware\n"
" -opengl1 Use OpenGL 1.x painter\n"
" -opengl2 Use OpenGL 2.0 painter\n");
return;
} else {
stdext::println("Unrecognized option '", arg, "', please see -help for available options list");
return;
}
}
g_logger.info(stdext::format(
"%s %s (rev %s) built on %s",
Otc::AppName,
Otc::AppVersion,
BUILD_REVISION,
BUILD_DATE));
if(startupOptions.length() > 0)
g_logger.info(stdext::format("Startup options: %s", startupOptions));
g_logger.setLogFile(stdext::format("%s.txt", Otc::AppCompactName));
Application::init(args);
// register needed lua functions
registerLuaFunctions();
g_shaders.init();
g_modules.discoverModules();
//TODO: restore options
/*
if(g_graphics.parseOption(arg))
continue;
// core modules 0-99
g_modules.autoLoadModules(99);
g_modules.ensureModuleLoaded("core_lib");
// client modules 100-499
g_modules.autoLoadModules(499);
g_modules.ensureModuleLoaded("client");
// game modules 500-999
g_modules.autoLoadModules(999);
g_modules.ensureModuleLoaded("game");
// addons 1000-9999
g_modules.autoLoadModules(9999);
// load otclientrc.lua
if(g_resources.fileExists("/otclientrc.lua")) {
try {
g_lua.runScript("/otclientrc.lua");
} catch(LuaException& e) {
g_logger.error(stdext::format("failed to load otclientrc.lua: %s", e.what()));
}
if(arg == "-version" || arg == "--version" || arg == "-v") {
stdext::print(
m_appName, " ", m_appVersion, "\n"
"Buitt on: ", BUILD_DATE, "\n",
"Revision: ", BUILD_REVISION, "\n",
"Compiled by: ", BUILD_COMPILER, "\n",
"Build type: ", BUILD_TYPE, "\n");
return;
} else if(arg == "-help" || arg == "--help" || arg == "-h" || arg == "-?" || arg == "/?") {
stdext::print(
"Usage: ", args[0], " [options]\n"
"Options:\n"
" -help Display this information and exit\n"
" -version Display version and exit\n"
" \n"
" -no-fbos Disable usage of opengl framebuffer objects\n"
" -no-mipmaps Disable texture mipmaping\n"
" -no-smooth Disable texture smoothing (bilinear filter)\n"
" -no-non-power-of-two-textures Use only power of two textures\n"
" -no-clamp-to-edge Don't use GL_CLAMP_TO_EDGE\n"
" -no-backbuffer-cache Don't allow backbuffer caching\n"
" -hardware-buffers Cache vertex arrays in hardware\n"
" -opengl1 Use OpenGL 1.x painter\n"
" -opengl2 Use OpenGL 2.0 painter\n");
return;
} else {
stdext::println("Unrecognized option '", arg, "', please see -help for available options list");
return;
}
*/
}
void OTClient::terminate()
@@ -119,5 +80,4 @@ void OTClient::terminate()
g_shaders.terminate();
g_map.clean();
g_thingsType.unload();
Application::terminate();
}

View File

@@ -23,16 +23,16 @@
#ifndef OTCLIENT_H
#define OTCLIENT_H
#include <framework/application.h>
#include <otclient/global.h>
class OTClient : public Application
class OTClient
{
public:
OTClient();
void init(const std::vector<std::string>& args);
void terminate();
void registerLuaFunctions();
};
extern OTClient g_otclient;
#endif