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

@ -9,7 +9,9 @@ SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,-Map=otclient.map")
OPTION(PCH "Use precompiled header (speed up compile)" OFF)
SET(executable_SOURCES src/main.cpp)
SET(executable_SOURCES
src/main.cpp
)
# add executable icon for win32 platforms
IF(WIN32)

48
init.lua Normal file
View File

@ -0,0 +1,48 @@
-- this is the first file executed when the application starts
-- we have to load the first modules form here
-- setup application name and version
g_app.setName('OTClient')
g_app.setCompactName('otclient')
g_app.setVersion('0.4.0_dev')
-- setup logger
g_logger.setLogFile(g_resources.getWorkDir() .. g_app.getCompactName() .. ".log")
-- print first terminal message
g_logger.info(g_app.getName() .. ' ' .. g_app.getVersion() .. ' (rev ' .. g_app.getBuildRevision() .. ') built on ' .. g_app.getBuildDate())
-- add modules directory to the search path
if not g_resources.addToSearchPath(g_resources.getWorkDir() .. "modules", true) then
g_logger.fatal("Unable to add modules directory to the search path.")
end
-- try to add addons path too
g_resources.addToSearchPath(g_resources.getWorkDir() .. "addons", true)
-- setup directory for saving configurations
g_resources.setupWriteDir(g_app.getCompactName())
-- load configurations
g_configs.load("/config.otml")
g_modules.discoverModules()
-- core modules 0-99
g_modules.autoLoadModules(99);
g_modules.ensureModuleLoaded("corelib")
-- 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)
if g_resources.fileExists("/otclientrc.lua") then
dofile("/otclientrc.lua")
end

View File

@ -1,8 +1,8 @@
Client = {}
function Client.reloadScripts()
dofile '/otclientrc'
reloadModules()
dofile '/otclientrc'
local message = tr('All modules and scripts were reloaded.')
TextMessage.displayEventAdvance(message)
print(message)
@ -35,16 +35,13 @@ function Client.init()
g_window.setTitle('OTClient')
g_window.setIcon(resolvepath('clienticon.png'))
-- show the only window after the first frame is rendered
addEvent(function()
scheduleEvent(function()
scheduleEvent(function()
g_window.show()
-- Play startup music (The Silver Tree, by Mattias Westlund)
g_sounds.playMusic("startup.ogg", 3)
connect(g_game, { onGameStart = function() g_sounds.stopMusic(3) end })
connect(g_game, { onGameEnd= function() g_sounds.playMusic("startup.ogg", 3) end })
end, 0)
end, 100)
end, 0)
end

View File

@ -3,8 +3,6 @@ Module
description: Initialize the client and setups its main window
author: edubart
website: www.otclient.info
autoload: true
autoload-priority: 100
reloadable: false
load-later:

View File

@ -47,9 +47,9 @@ function Locales.init()
local userLocaleName = Settings.get('locale')
if userLocaleName and Locales.setLocale(userLocaleName) then
--info('Using configured locale: ' .. userLocaleName)
pdebug('Using configured locale: ' .. userLocaleName)
else
--info('Using default locale: ' .. defaultLocaleName)
pdebug('Using default locale: ' .. defaultLocaleName)
Locales.setLocale(defaultLocaleName)
Settings.set('locale', defaultLocaleName)
end
@ -100,7 +100,7 @@ end
function Locales.setLocale(name)
local locale = installedLocales[name]
if not locale then
warning("Locale " .. name .. ' does not exist.')
pwarning("Locale " .. name .. ' does not exist.')
return false
end
currentLocale = locale
@ -125,7 +125,7 @@ function tr(text, ...)
local translation = currentLocale.translation[text]
if not translation then
if currentLocale.name ~= defaultLocaleName then
warning('Unable to translate: \"' .. text .. '\"')
pwarning('Unable to translate: \"' .. text .. '\"')
end
translation = text
end

View File

@ -15,7 +15,8 @@ local function onSkinComboBoxOptionChange(self, optionText, optionData)
end
local function getSkinPath(name)
return g_modules.getModulesPath() .. g_lua.getCurrentSourcePath(0) .. '/skins/' .. string.lower(name) .. '/'
local current = getfsrcpath()
return g_resources.getRealDir(current) .. current .. '/skins/' .. string.lower(name)
end
-- public functions
@ -30,9 +31,9 @@ function Skins.init()
local userSkinName = Settings.get('skin')
if userSkinName and Skins.setSkin(userSkinName) then
info('Using configured skin: ' .. userSkinName)
pdebug('Using configured skin: ' .. userSkinName)
else
info('Using default skin: ' .. defaultSkinName)
pdebug('Using default skin: ' .. defaultSkinName)
Skins.setSkin(defaultSkinName)
Settings.set('skin', defaultSkinName)
end
@ -65,7 +66,7 @@ function Skins.installSkin(skin)
end
if installedSkins[skin.name] then
warning(skin.name .. ' has been replaced.')
pwarning(skin.name .. ' has been replaced.')
end
installedSkins[skin.name] = skin
@ -79,7 +80,7 @@ end
function Skins.setSkin(name)
local skin = installedSkins[name]
if not skin then
warning("Skin " .. name .. ' does not exist.')
pwarning("Skin " .. name .. ' does not exist.')
return false
end

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 385 B

View File

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 763 B

After

Width:  |  Height:  |  Size: 763 B

View File

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -1,10 +1,8 @@
Module
name: core_lib
name: corelib
description: Contains core lua classes, functions and constants used by other modules
author: OTClient team
website: www.otclient.info
autoload: true
autoload-priority: 10
reloadable: false
@onLoad: |

View File

@ -15,7 +15,9 @@ function translateKeyCombo(keyCombo)
end
local function retranslateKeyComboDesc(keyComboDesc)
if keyComboDesc == nil then return nil end
if keyComboDesc == nil then
error('Unable to translate key combo \'' .. keyComboDesc .. '\'')
end
local keyCombo = {}
for i,currentKeyDesc in ipairs(keyComboDesc:split('+')) do
for keyCode, keyDesc in pairs(KeyCodeDescs) do
@ -97,11 +99,7 @@ function Keyboard.bindKeyDown(keyComboDesc, callback, widget)
widget = widget or rootWidget
connectKeyDownEvent(widget)
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
if keyComboDesc then
widget.boundKeyDownCombos[keyComboDesc] = callback
else
error('key combo \'' .. keyComboDesc .. '\' is failed')
end
end
function Keyboard.bindKeyPress(keyComboDesc, callback, widget, autoRepeatDelay)
@ -109,12 +107,8 @@ function Keyboard.bindKeyPress(keyComboDesc, callback, widget, autoRepeatDelay)
widget = widget or rootWidget
connectKeyPressEvent(widget)
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
if keyComboDesc then
widget.boundKeyPressCombos[keyComboDesc] = { callback = callback, autoRepeatDelay = autoRepeatDelay }
widget:setAutoRepeatDelay(math.min(autoRepeatDelay, widget:getAutoRepeatDelay()))
else
error('key combo \'' .. keyComboDesc .. '\' is failed')
end
end
function Keyboard.unbindKeyDown(keyComboDesc, widget)

View File

@ -45,7 +45,7 @@ function ToolTip.init()
onHoverChange = onWidgetHoverChange})
addEvent(function()
toolTipLabel = createWidget('Label', rootWidget)
toolTipLabel = createWidget('UILabel', rootWidget)
toolTipLabel:setId('toolTip')
toolTipLabel:setBackgroundColor('#111111cc')
toolTipLabel:setTextAlign(AlignCenter)

View File

@ -6,18 +6,27 @@ function print(...)
g_logger.log(LogInfo, msg)
end
function info(msg)
function pinfo(msg)
g_logger.log(LogInfo, msg)
end
function warning(msg)
function perror(msg)
g_logger.log(LogError, msg)
end
function pwarning(msg)
g_logger.log(LogWarning, msg)
end
function pdebug(msg)
g_logger.log(LogDebug, msg)
end
function fatal(msg)
g_logger.log(LogFatal, msg)
end
exit = g_app.exit
quit = g_app.exit
@ -161,3 +170,7 @@ function signalcall(param, ...)
end
return false
end
function tr(s)
return s
end

View File

@ -1,15 +1,16 @@
Module
name: game
description: Create the game interface, where the ingame stuff starts
description: Contains game related classes
author: OTClient team
website: www.otclient.info
dependencies:
- client_extended
- game_tibiafiles
- client_background
- game_tibiafiles
load-later:
- game_interface
- game_textmessage
- game_console
- game_outfit
@ -31,26 +32,9 @@ Module
- game_shaders
@onLoad: |
importStyle 'styles/items.otui'
importStyle 'styles/creatures.otui'
importStyle 'styles/miniwindow.otui'
importStyle 'styles/countwindow.otui'
dofile 'const'
dofile 'protocollogin'
dofile 'widgets/uigamemap'
dofile 'widgets/uiitem'
dofile 'widgets/uiminiwindow'
dofile 'widgets/uiminiwindowcontainer'
dofile 'creature'
dofile 'player'
dofile 'gameinterface'
GameInterface.init()
@onUnload: |
GameInterface.terminate()

View File

@ -6,7 +6,7 @@ Module
icon: battle.png
dependencies:
- game
- game_interface
@onLoad: |
dofile 'battle'

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'bugreport'

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'combatcontrols'

View File

@ -106,7 +106,7 @@ local function onCreatureSpeak(name, level, speaktype, message, channelId, creat
Console.addText(composedMessage, speaktype, channel, name)
elseif channelId ~= 0 then
-- server sent a message on a channel that is not open
warning('message in channel id ' .. channelId .. ' which is unknown, this is a server bug, relogin if you want to see messages in this channel')
pwarning('message in channel id ' .. channelId .. ' which is unknown, this is a server bug, relogin if you want to see messages in this channel')
end
end
end

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'console'

View File

@ -17,7 +17,7 @@ ContainerWindow < MiniWindow
anchors.right: minimizeButton.left
margin-right: 3
size: 14 14
image-source: /game/images/miniwindowbuttons.png
image-source: /images/miniwindowbuttons.png
image-clip: 42 0 14 14
$hover:

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'containers'

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'healthbar'

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'hotkeys_manager'

View File

@ -25,7 +25,7 @@ function GameInterface.init()
gameLeftPanel = gameRootPanel:getChildById('gameLeftPanel')
gameBottomPanel = gameRootPanel:getChildById('gameBottomPanel')
logoutButton = TopMenu.addRightButton('logoutButton', 'Logout', 'images/logout.png', GameInterface.tryLogout)
logoutButton = TopMenu.addRightButton('logoutButton', 'Logout', '/images/logout.png', GameInterface.tryLogout)
logoutButton:hide()
Keyboard.bindKeyPress('Up', function() g_game.walk(North) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)

View File

@ -1,15 +1,15 @@
GameSidePanel < UIMiniWindowContainer
image-source: images/sidepanel.png
image-source: /images/sidepanel.png
image-border: 4
padding: 4
GameBottomPanel < Panel
image-source: images/bottompanel.png
image-source: /images/bottompanel.png
image-border: 4
GameMapPanel < UIGameMap
padding: 4
image-source: images/mappanel.png
image-source: /images/mappanel.png
image-border: 4
UIWidget

View File

@ -0,0 +1,21 @@
Module
name: game_interface
description: Create the game interface, where the ingame stuff starts
author: OTClient team
website: www.otclient.info
@onLoad: |
importStyle 'styles/items.otui'
importStyle 'styles/creatures.otui'
importStyle 'styles/miniwindow.otui'
importStyle 'styles/countwindow.otui'
dofile 'widgets/uigamemap'
dofile 'widgets/uiitem'
dofile 'gameinterface'
GameInterface.init()
@onUnload: |
GameInterface.terminate()

View File

@ -1,6 +1,6 @@
Item < UIItem
size: 34 34
padding: 1
image-source: /game/images/item.png
image-source: /images/item.png
font: verdana-11px-rounded
border-color: white

View File

@ -5,7 +5,7 @@ MiniWindow < UIMiniWindow
height: 200
text-offset: 24 5
text-align: topLeft
image-source: /game/images/miniwindow.png
image-source: /images/miniwindow.png
image-border: 4
image-border-top: 23
image-border-bottom: 4
@ -22,7 +22,7 @@ MiniWindow < UIMiniWindow
margin-top: 5
margin-right: 5
size: 14 14
image-source: /game/images/miniwindowbuttons.png
image-source: /images/miniwindowbuttons.png
image-clip: 28 0 14 14
$hover:
@ -37,7 +37,7 @@ MiniWindow < UIMiniWindow
anchors.right: closeButton.left
margin-right: 3
size: 14 14
image-source: /game/images/miniwindowbuttons.png
image-source: /images/miniwindowbuttons.png
image-clip: 0 0 14 14
$hover:

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'inventory'

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'minimap'

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'npctrade'

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'outfit'

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'playertrade'

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'questlog'

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'ruleviolation'

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'shaders'

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'skills'

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'textbooks'

View File

@ -5,7 +5,7 @@ Module
website: www.otclient.info
dependencies:
- game
- game_interface
@onLoad: |
dofile 'textmessage'

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()))
if(!PHYSFS_setWriteDir(userDir.c_str())) {
g_logger.error("User directory not found.");
return false;
}
if(!PHYSFS_mkdir(dirName.c_str())) {
PHYSFS_setWriteDir(NULL);
g_logger.error("Cannot create directory for saving configurations.");
return false;
}
if(!PHYSFS_setWriteDir(writeDir.c_str()))
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,8 +133,9 @@ 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);
if(m_hasSearchPath) {
std::string fullPath = resolvePath(fileName);
PHYSFS_file* file = PHYSFS_openRead(fullPath.c_str());
if(!file) {
out.clear(std::ios::failbit);
@ -111,6 +151,15 @@ void ResourceManager::loadFile(const std::string& fileName, std::iostream& out)
PHYSFS_close(file);
out.seekg(0, std::ios::beg);
}
} else {
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();
}
}
}
std::string ResourceManager::loadFile(const std::string& fileName)
@ -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);

Some files were not shown because too many files have changed in this diff Show More