add clock, change exceptions, add network exceptions, fix some crashes
This commit is contained in:
parent
4afbe43e6f
commit
d5e15d1f06
|
@ -33,7 +33,7 @@ FIND_PACKAGE(PCHSupport REQUIRED)
|
|||
|
||||
# choose a default build type if not specified
|
||||
IF(NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE ReleaseWithDebInfo)
|
||||
SET(CMAKE_BUILD_TYPE Debug)
|
||||
ENDIF(NOT CMAKE_BUILD_TYPE)
|
||||
MESSAGE(STATUS "BUILD TYPE: " ${CMAKE_BUILD_TYPE})
|
||||
|
||||
|
@ -43,7 +43,7 @@ IF(CMAKE_COMPILER_IS_GNUCXX)
|
|||
SET(CMAKE_CXX_FLAGS "-std=gnu++0x -pipe ${CXX_WARNS}")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3 -ggdb3 -fno-inline")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O1 -g -fno-inline")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O1 -g -ggdb -fno-inline")
|
||||
SET(CMAKE_CXX_LINK_FLAGS "-static-libgcc -static-libstdc++ -Wl,--as-needed")
|
||||
ENDIF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
|
@ -112,12 +112,14 @@ SET(SOURCES
|
|||
|
||||
# framework core
|
||||
src/framework/core/logger.cpp
|
||||
src/framework/core/configs.cpp
|
||||
src/framework/core/clock.cpp
|
||||
src/framework/core/configmanager.cpp
|
||||
src/framework/core/resourcemanager.cpp
|
||||
src/framework/core/eventdispatcher.cpp
|
||||
src/framework/core/modulemanager.cpp
|
||||
src/framework/core/module.cpp
|
||||
src/framework/core/engine.cpp
|
||||
src/framework/core/clock.cpp
|
||||
|
||||
# framework graphics
|
||||
src/framework/graphics/font.cpp
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
# Try to find the OpenGLES librairy
|
||||
# OPENGLES_FOUND - system has OpenGLES
|
||||
# OPENGLES_INCLUDE_DIR - the OpenGLES include directory
|
||||
# OPENGLES_LIBRARY - the OpenGLES library
|
||||
|
||||
FIND_PATH(OPENGLES_INCLUDE_DIR gl2.h PATH_SUFFIXES GLES2)
|
||||
FIND_LIBRARY(OPENGLES_LIBRARY NAMES GLESv2)
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenGLES DEFAULT_MSG OPENGLES_LIBRARY OPENGLES_INCLUDE_DIR)
|
||||
MARK_AS_ADVANCED(OPENGLES_LIBRARY OPENGLES_INCLUDE_DIR)
|
|
@ -47,7 +47,7 @@ local function tryLogin(charInfo, tries)
|
|||
end
|
||||
|
||||
-- save last used character
|
||||
Configs.set('lastUsedCharacter', charInfo.characterName)
|
||||
ConfigManager.set('lastUsedCharacter', charInfo.characterName)
|
||||
end
|
||||
|
||||
-- public functions
|
||||
|
@ -75,7 +75,7 @@ function CharacterList.create(characters, premDays)
|
|||
label.worldHost = worldHost
|
||||
label.worldPort = worldIp
|
||||
|
||||
if i == 1 or Configs.get('lastUsedCharacter') == characterName then
|
||||
if i == 1 or ConfigManager.get('lastUsedCharacter') == characterName then
|
||||
characterList:focusChild(label, ActiveFocusReason)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,8 +11,8 @@ local function clearAccountFields()
|
|||
enterGame:getChildById('accountNameLineEdit'):clearText()
|
||||
enterGame:getChildById('accountPasswordLineEdit'):clearText()
|
||||
enterGame:getChildById('accountNameLineEdit'):focus()
|
||||
Configs.set('account', nil)
|
||||
Configs.set('password', nil)
|
||||
ConfigManager.set('account', nil)
|
||||
ConfigManager.set('password', nil)
|
||||
end
|
||||
|
||||
local function onError(protocol, error)
|
||||
|
@ -30,9 +30,9 @@ end
|
|||
|
||||
local function onCharacterList(protocol, characters, premDays)
|
||||
if enterGame:getChildById('rememberPasswordBox'):isChecked() then
|
||||
Configs.set('account', EnterGame.account)
|
||||
Configs.set('password', EnterGame.password)
|
||||
Configs.set('autologin', tostring(enterGame:getChildById('autoLoginBox'):isChecked()))
|
||||
ConfigManager.set('account', EnterGame.account)
|
||||
ConfigManager.set('password', EnterGame.password)
|
||||
ConfigManager.set('autologin', tostring(enterGame:getChildById('autoLoginBox'):isChecked()))
|
||||
else
|
||||
clearAccountFields()
|
||||
end
|
||||
|
@ -40,9 +40,9 @@ local function onCharacterList(protocol, characters, premDays)
|
|||
loadBox:destroy()
|
||||
CharacterList.create(characters, premDays)
|
||||
|
||||
local lastMotdNumber = tonumber(Configs.get("motd"))
|
||||
local lastMotdNumber = tonumber(ConfigManager.get("motd"))
|
||||
if motdNumber and motdNumber ~= lastMotdNumber then
|
||||
Configs.set("motd", motdNumber)
|
||||
ConfigManager.set("motd", motdNumber)
|
||||
local motdBox = displayInfoBox("Message of the day", motdMessage)
|
||||
motdBox.onOk = CharacterList.show
|
||||
CharacterList.hide()
|
||||
|
@ -53,11 +53,11 @@ end
|
|||
function EnterGame.create()
|
||||
enterGame = UI.display('entergame.otui')
|
||||
|
||||
local account = Configs.get('account')
|
||||
local password = Configs.get('password')
|
||||
local host = Configs.get('host')
|
||||
local port = tonumber(Configs.get('port'))
|
||||
local autologin = toboolean(Configs.get('autologin'))
|
||||
local account = ConfigManager.get('account')
|
||||
local password = ConfigManager.get('password')
|
||||
local host = ConfigManager.get('host')
|
||||
local port = tonumber(ConfigManager.get('port'))
|
||||
local autologin = toboolean(ConfigManager.get('autologin'))
|
||||
|
||||
enterGame:getChildById('accountNameLineEdit'):setText(account)
|
||||
enterGame:getChildById('accountPasswordLineEdit'):setText(password)
|
||||
|
@ -93,8 +93,8 @@ function EnterGame.doLogin()
|
|||
EnterGame.port = enterGame:getChildById('serverPortLineEdit'):getText()
|
||||
EnterGame.hide()
|
||||
|
||||
Configs.set('host', EnterGame.host)
|
||||
Configs.set('port', EnterGame.port)
|
||||
ConfigManager.set('host', EnterGame.host)
|
||||
ConfigManager.set('port', EnterGame.port)
|
||||
|
||||
local protocolLogin = ProtocolLogin.create()
|
||||
protocolLogin.onError = onError
|
||||
|
|
|
@ -6,8 +6,8 @@ local fpsEnabled = false
|
|||
local vsyncEnabled = false
|
||||
|
||||
function getConfig(name, default)
|
||||
if Configs.exists(name) then
|
||||
local val = string.trim(Configs.get(name))
|
||||
if ConfigManager.exists(name) then
|
||||
local val = string.trim(ConfigManager.get(name))
|
||||
if val == 'true' or val == 'false' then
|
||||
return toboolean(val)
|
||||
else
|
||||
|
@ -15,7 +15,7 @@ function getConfig(name, default)
|
|||
end
|
||||
else
|
||||
if default ~= nil then
|
||||
Configs.set(name, default)
|
||||
ConfigManager.set(name, default)
|
||||
return default
|
||||
else
|
||||
return nil
|
||||
|
@ -24,7 +24,7 @@ function getConfig(name, default)
|
|||
end
|
||||
|
||||
function setConfig(name, value)
|
||||
Configs.set(name, tostring(value))
|
||||
ConfigManager.set(name, tostring(value))
|
||||
end
|
||||
|
||||
-- private functions
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "clock.h"
|
||||
|
||||
Clock g_clock;
|
||||
|
||||
Clock::Clock()
|
||||
{
|
||||
m_startupTime = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
int Clock::updateTicks()
|
||||
{
|
||||
auto timeNow = std::chrono::high_resolution_clock::now();
|
||||
m_currentTicks = std::chrono::duration_cast<std::chrono::milliseconds>(timeNow - m_startupTime).count();
|
||||
return m_currentTicks;
|
||||
}
|
||||
|
||||
void Clock::sleep(int ms)
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CLOCK_H
|
||||
#define CLOCK_H
|
||||
|
||||
#include "declarations.h"
|
||||
|
||||
class Clock
|
||||
{
|
||||
public:
|
||||
Clock();
|
||||
|
||||
int updateTicks();
|
||||
void sleep(int ms);
|
||||
|
||||
int ticks() { return m_currentTicks; }
|
||||
int ticksElapsed(int prevTicks) { return ticks() - prevTicks; }
|
||||
int ticksFor(int delay) { return ticks() + delay; }
|
||||
|
||||
private:
|
||||
int m_currentTicks;
|
||||
std::chrono::system_clock::time_point m_startupTime;
|
||||
};
|
||||
|
||||
extern Clock g_clock;
|
||||
|
||||
#endif
|
||||
|
|
@ -20,14 +20,14 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "configs.h"
|
||||
#include "configmanager.h"
|
||||
#include "resourcemanager.h"
|
||||
|
||||
#include <framework/otml/otml.h>
|
||||
|
||||
Configs g_configs;
|
||||
ConfigManager g_configs;
|
||||
|
||||
bool Configs::load(const std::string& file)
|
||||
bool ConfigManager::load(const std::string& file)
|
||||
{
|
||||
m_fileName = file;
|
||||
|
||||
|
@ -39,13 +39,13 @@ bool Configs::load(const std::string& file)
|
|||
for(const OTMLNodePtr& child : doc->children())
|
||||
m_confsMap[child->tag()] = child->value();
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
} catch(Exception& e) {
|
||||
logError("could not load configurations: ", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Configs::save()
|
||||
bool ConfigManager::save()
|
||||
{
|
||||
OTMLDocumentPtr doc = OTMLDocument::create();
|
||||
for(auto it : m_confsMap) {
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include "declarations.h"
|
||||
|
||||
class Configs
|
||||
class ConfigManager
|
||||
{
|
||||
public:
|
||||
bool load(const std::string& file);
|
||||
|
@ -40,6 +40,6 @@ private:
|
|||
std::map<std::string, std::string> m_confsMap;
|
||||
};
|
||||
|
||||
extern Configs g_configs;
|
||||
extern ConfigManager g_configs;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "engine.h"
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ENGINE_H
|
||||
#define ENGINE_H
|
||||
|
||||
#include "declarations.h"
|
||||
|
||||
class Engine
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -22,44 +22,42 @@
|
|||
|
||||
#include "eventdispatcher.h"
|
||||
|
||||
#include <framework/platform/platform.h>
|
||||
#include <framework/core/clock.h>
|
||||
|
||||
EventDispatcher g_dispatcher;
|
||||
|
||||
void EventDispatcher::init()
|
||||
void EventDispatcher::flush()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
poll();
|
||||
|
||||
void EventDispatcher::terminate()
|
||||
{
|
||||
// clean scheduled events
|
||||
m_eventList.clear();
|
||||
while(!m_scheduledEventList.empty())
|
||||
m_scheduledEventList.pop();
|
||||
}
|
||||
|
||||
void EventDispatcher::poll()
|
||||
{
|
||||
while(!m_eventList.empty()) {
|
||||
m_eventList.front()();
|
||||
m_eventList.pop_front();
|
||||
}
|
||||
|
||||
while(!m_scheduledEventList.empty()) {
|
||||
if(g_platform.getTicks() < m_scheduledEventList.top().ticks)
|
||||
if(g_clock.ticks() < m_scheduledEventList.top().ticks)
|
||||
break;
|
||||
SimpleCallback callback = std::move(m_scheduledEventList.top().callback);
|
||||
m_scheduledEventList.pop();
|
||||
callback();
|
||||
}
|
||||
|
||||
while(!m_eventList.empty()) {
|
||||
m_eventList.front()();
|
||||
m_eventList.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::scheduleEvent(const SimpleCallback& callback, int delay)
|
||||
{
|
||||
m_scheduledEventList.push(ScheduledEvent(g_platform.getTicks() + delay, callback));
|
||||
assert(delay >= 0);
|
||||
m_scheduledEventList.push(ScheduledEvent(g_clock.ticksFor(delay), callback));
|
||||
}
|
||||
|
||||
void EventDispatcher::addEvent(const SimpleCallback& callback, bool pushFront /* = false */)
|
||||
void EventDispatcher::addEvent(const SimpleCallback& callback, bool pushFront)
|
||||
{
|
||||
if(pushFront)
|
||||
m_eventList.push_front(callback);
|
||||
|
|
|
@ -35,19 +35,10 @@ struct ScheduledEvent {
|
|||
class EventDispatcher
|
||||
{
|
||||
public:
|
||||
/// Initialize dispatcher
|
||||
void init();
|
||||
|
||||
/// Cleanup scheduled events
|
||||
void terminate();
|
||||
|
||||
/// Execute scheduled events
|
||||
void flush();
|
||||
void poll();
|
||||
|
||||
/// Add an event
|
||||
void addEvent(const SimpleCallback& callback, bool pushFront = false);
|
||||
|
||||
/// Schedule an event
|
||||
void scheduleEvent(const SimpleCallback& callback, int delay);
|
||||
|
||||
private:
|
||||
|
|
|
@ -57,28 +57,29 @@ void Module::discover(const OTMLNodePtr& moduleNode)
|
|||
|
||||
bool Module::load()
|
||||
{
|
||||
try {
|
||||
for(const std::string& depName : m_dependencies) {
|
||||
ModulePtr dep = g_modules.getModule(depName);
|
||||
if(!dep)
|
||||
throw std::runtime_error(Fw::mkstr("could not find module dependency '", depName ,"'"));
|
||||
if(!dep) {
|
||||
logError("Unable to load module '", m_name, "' because dependency '", depName, "' was not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!dep->isLoaded() && !dep->load())
|
||||
throw std::runtime_error(Fw::mkstr("dependency '", depName, "' has failed to load"));
|
||||
if(!dep->isLoaded() && !dep->load()) {
|
||||
logError("Unable to load module '", m_name, "' because dependency '", depName, "' has failed to laod");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_loadCallback) {
|
||||
m_loaded = m_loadCallback();
|
||||
if(!m_loaded)
|
||||
throw std::runtime_error("module onLoad event returned false");
|
||||
if(!m_loaded) {
|
||||
logError("Unable to load module '", m_name, "' because its onLoad event returned false");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
logInfo("Loaded module '", m_name, "'");
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
logError("failed to load module '", m_name, "': ", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Module::unload()
|
||||
|
|
|
@ -36,14 +36,14 @@ public:
|
|||
bool load();
|
||||
void unload();
|
||||
|
||||
bool isLoaded() const { return m_loaded; }
|
||||
bool isLoaded() { return m_loaded; }
|
||||
|
||||
std::string getDescription() const { return m_description; }
|
||||
std::string getName() const { return m_name; }
|
||||
std::string getAuthor() const { return m_author; }
|
||||
std::string getWebsite() const { return m_website; }
|
||||
std::string getVersion() const { return m_version; }
|
||||
bool autoLoad() const { return m_autoLoad; }
|
||||
std::string getDescription() { return m_description; }
|
||||
std::string getName() { return m_name; }
|
||||
std::string getAuthor() { return m_author; }
|
||||
std::string getWebsite() { return m_website; }
|
||||
std::string getVersion() { return m_version; }
|
||||
bool autoLoad() { return m_autoLoad; }
|
||||
|
||||
private:
|
||||
bool m_loaded;
|
||||
|
|
|
@ -56,13 +56,13 @@ bool ModuleManager::discoverModule(const std::string& file)
|
|||
|
||||
std::string name = moduleNode->valueAt("name");
|
||||
if(getModule(name))
|
||||
throw OTMLException(moduleNode, "a module with the same name is already discovered, did you duplicate module names?");
|
||||
Fw::throwException("module '", name, "' already exists, cannot have duplicate module names");
|
||||
|
||||
module = ModulePtr(new Module(name));
|
||||
module->discover(moduleNode);
|
||||
m_modules.push_back(module);
|
||||
} catch(std::exception& e) {
|
||||
logError("failed to load module from '", file, "': ", e.what());
|
||||
} catch(Exception& e) {
|
||||
logError("Unable to discover module from file '", file, "': ", e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -107,7 +107,7 @@ void ResourceManager::loadFile(const std::string& fileName, std::iostream& out)
|
|||
PHYSFS_file* file = PHYSFS_openRead(fullPath.c_str());
|
||||
if(!file) {
|
||||
out.clear(std::ios::failbit);
|
||||
throw std::runtime_error(Fw::mkstr("failed to load file '", fullPath.c_str(), "': ", PHYSFS_getLastError()));
|
||||
Fw::throwException("failed to load file '", fullPath.c_str(), "': ", PHYSFS_getLastError());
|
||||
} else {
|
||||
int fileSize = PHYSFS_fileLength(file);
|
||||
if(fileSize > 0) {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <cassert>
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
#include <unistd.h>
|
||||
|
||||
// common STL headers
|
||||
#include <iostream>
|
||||
|
@ -53,6 +54,7 @@
|
|||
#include <iomanip>
|
||||
#include <unordered_map>
|
||||
#include <random>
|
||||
#include <chrono>
|
||||
|
||||
// boost utilities
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
|
|
@ -79,8 +79,6 @@ BorderImagePtr BorderImage::loadFromOTML(const OTMLNodePtr& borderImageNode)
|
|||
// load texture
|
||||
std::string source = borderImageNode->at("source")->value();
|
||||
TexturePtr texture = g_textures.getTexture(source);
|
||||
if(!texture)
|
||||
throw OTMLException(borderImageNode, "could not load border-image texture");
|
||||
|
||||
// load basic border confs
|
||||
size = texture->getSize();
|
||||
|
|
|
@ -37,8 +37,6 @@ void Font::load(const OTMLNodePtr& fontNode)
|
|||
|
||||
// load font texture
|
||||
m_texture = g_textures.getTexture(textureName);
|
||||
if(!m_texture)
|
||||
throw std::runtime_error("failed to load texture for font");
|
||||
|
||||
if(OTMLNodePtr node = fontNode->get("fixed-glyph-width")) {
|
||||
for(int glyph = m_firstGlyph; glyph < 256; ++glyph)
|
||||
|
|
|
@ -44,7 +44,7 @@ bool FontManager::importFont(std::string fontFile)
|
|||
|
||||
std::string name = fontNode->valueAt("name");
|
||||
if(fontExists(name))
|
||||
throw std::runtime_error("a font with the same name is already imported, did you duplicate font names?");
|
||||
Fw::throwException("font '", name, "' already exists, cannot have duplicate font names");
|
||||
|
||||
FontPtr font(new Font(name));
|
||||
font->load(fontNode);
|
||||
|
@ -55,8 +55,8 @@ bool FontManager::importFont(std::string fontFile)
|
|||
m_defaultFont = font;
|
||||
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
logError("could not load font from '", fontFile, "': ", e.what());
|
||||
} catch(Exception& e) {
|
||||
logError("Unable to load font from file '", fontFile, "': ", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,8 +43,6 @@ void Image::loadFromOTML(const OTMLNodePtr& imageNode)
|
|||
|
||||
// load texture
|
||||
m_texture = g_textures.getTexture(source);
|
||||
if(!m_texture)
|
||||
throw OTMLException(imageNode, "could not load image texture");
|
||||
m_textureCoords = imageNode->valueAt("coords", Rect(Point(0,0),m_texture->getSize()));
|
||||
|
||||
// enable texture bilinear filter
|
||||
|
|
|
@ -46,14 +46,14 @@ TexturePtr TextureManager::getTexture(const std::string& textureFile)
|
|||
try {
|
||||
// currently only png textures are supported
|
||||
if(!boost::ends_with(textureFile, ".png"))
|
||||
throw std::runtime_error("texture file format no supported");
|
||||
Fw::throwException("texture file format no supported");
|
||||
|
||||
// load texture file data
|
||||
std::stringstream fin;
|
||||
g_resources.loadFile(textureFile, fin);
|
||||
texture = loadPNG(fin);
|
||||
} catch(std::exception& e) {
|
||||
logError("unable to load texture '",textureFile,"': ", e.what());
|
||||
} catch(Exception& e) {
|
||||
Fw::throwException("unable to load texture '", textureFile, "': ", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <framework/ui/ui.h>
|
||||
#include <framework/net/protocol.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
#include <framework/core/configs.h>
|
||||
#include <framework/core/configmanager.h>
|
||||
#include <framework/platform/platform.h>
|
||||
#include <framework/otml/otml.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
|
@ -152,10 +152,10 @@ void LuaInterface::registerFunctions()
|
|||
g_lua.registerClass<Protocol>();
|
||||
|
||||
// ConfigManager
|
||||
g_lua.registerClass<Configs>();
|
||||
g_lua.bindClassStaticFunction<Configs>("set", std::bind(&Configs::set, &g_configs, _1, _2));
|
||||
g_lua.bindClassStaticFunction<Configs>("get", std::bind(&Configs::get, &g_configs, _1));
|
||||
g_lua.bindClassStaticFunction<Configs>("exists", std::bind(&Configs::exists, &g_configs, _1));
|
||||
g_lua.registerClass<ConfigManager>();
|
||||
g_lua.bindClassStaticFunction<ConfigManager>("set", std::bind(&ConfigManager::set, &g_configs, _1, _2));
|
||||
g_lua.bindClassStaticFunction<ConfigManager>("get", std::bind(&ConfigManager::get, &g_configs, _1));
|
||||
g_lua.bindClassStaticFunction<ConfigManager>("exists", std::bind(&ConfigManager::exists, &g_configs, _1));
|
||||
|
||||
// Logger
|
||||
g_lua.registerClass<Logger>();
|
||||
|
|
|
@ -545,7 +545,7 @@ void LuaInterface::createLuaState()
|
|||
// creates lua state
|
||||
L = luaL_newstate();
|
||||
if(!L)
|
||||
throw std::runtime_error("failed to create lua state");
|
||||
logFatal("Unable to create lua state");
|
||||
|
||||
// load lua standard libraries
|
||||
luaL_openlibs(L);
|
||||
|
|
|
@ -168,7 +168,7 @@ bool luavalue_cast(int index, std::function<void(Args...)>& func) {
|
|||
throw LuaException("attempt to call an expired lua function from C++,"
|
||||
"did you forget to hold a reference for that function?", 0);
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
} catch(LuaException& e) {
|
||||
logError("lua function callback failed: ", e.what());
|
||||
}
|
||||
};
|
||||
|
@ -202,7 +202,7 @@ luavalue_cast(int index, std::function<Ret(Args...)>& func) {
|
|||
throw LuaException("attempt to call an expired lua function from C++,"
|
||||
"did you forget to hold a reference for that function?", 0);
|
||||
}
|
||||
} catch(std::exception& e) {
|
||||
} catch(LuaException& e) {
|
||||
logError("lua function callback failed: ", e.what());
|
||||
}
|
||||
return Ret();
|
||||
|
|
|
@ -35,7 +35,7 @@ void InputMessage::reset()
|
|||
|
||||
uint8 InputMessage::getU8(bool peek)
|
||||
{
|
||||
assert(canRead(1));
|
||||
checkRead(1);
|
||||
uint8 v = m_buffer[m_readPos];
|
||||
|
||||
if(!peek)
|
||||
|
@ -46,7 +46,7 @@ uint8 InputMessage::getU8(bool peek)
|
|||
|
||||
uint16 InputMessage::getU16(bool peek)
|
||||
{
|
||||
assert(canRead(2));
|
||||
checkRead(2);
|
||||
uint16 v = *(uint16_t*)(m_buffer + m_readPos);
|
||||
|
||||
if(!peek)
|
||||
|
@ -57,7 +57,7 @@ uint16 InputMessage::getU16(bool peek)
|
|||
|
||||
uint32 InputMessage::getU32(bool peek)
|
||||
{
|
||||
assert(canRead(4));
|
||||
checkRead(4);
|
||||
uint32 v = *(uint32*)(m_buffer + m_readPos);
|
||||
|
||||
if(!peek)
|
||||
|
@ -68,7 +68,7 @@ uint32 InputMessage::getU32(bool peek)
|
|||
|
||||
uint64 InputMessage::getU64(bool peek)
|
||||
{
|
||||
assert(canRead(8));
|
||||
checkRead(8);
|
||||
uint64 v = *(uint64*)(m_buffer + m_readPos);
|
||||
|
||||
if(!peek)
|
||||
|
@ -80,7 +80,7 @@ uint64 InputMessage::getU64(bool peek)
|
|||
std::string InputMessage::getString()
|
||||
{
|
||||
uint16 stringLength = getU16();
|
||||
assert(canRead(stringLength));
|
||||
checkRead(stringLength);
|
||||
char* v = (char*)(m_buffer + m_readPos);
|
||||
m_readPos += stringLength;
|
||||
return std::string(v, stringLength);
|
||||
|
@ -92,3 +92,10 @@ bool InputMessage::canRead(int bytes)
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void InputMessage::checkRead(int bytes)
|
||||
{
|
||||
if(!canRead(bytes))
|
||||
throw NetworkException("InputMessage eof reached");
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define INPUTMESSAGE_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include "networkexception.h"
|
||||
|
||||
class InputMessage
|
||||
{
|
||||
|
@ -56,6 +57,7 @@ public:
|
|||
|
||||
private:
|
||||
bool canRead(int bytes);
|
||||
void checkRead(int bytes);
|
||||
|
||||
uint16 m_readPos;
|
||||
uint16 m_messageSize;
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef NETWORKEXCEPTION_H
|
||||
#define NETWORKEXCEPTION_H
|
||||
|
||||
#include "declarations.h"
|
||||
|
||||
class NetworkException : public Exception
|
||||
{
|
||||
public:
|
||||
NetworkException(const std::string& what) : Exception(what) { }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -35,7 +35,7 @@ void OutputMessage::reset()
|
|||
|
||||
void OutputMessage::addU8(uint8 value)
|
||||
{
|
||||
assert(canWrite(1));
|
||||
checkWrite(1);
|
||||
m_buffer[m_writePos] = value;
|
||||
m_writePos += 1;
|
||||
m_messageSize += 1;
|
||||
|
@ -43,7 +43,7 @@ void OutputMessage::addU8(uint8 value)
|
|||
|
||||
void OutputMessage::addU16(uint16 value)
|
||||
{
|
||||
assert(canWrite(2));
|
||||
checkWrite(2);
|
||||
*(uint16_t*)(m_buffer + m_writePos) = value;
|
||||
m_writePos += 2;
|
||||
m_messageSize += 2;
|
||||
|
@ -51,7 +51,7 @@ void OutputMessage::addU16(uint16 value)
|
|||
|
||||
void OutputMessage::addU32(uint32 value)
|
||||
{
|
||||
assert(canWrite(4));
|
||||
checkWrite(4);
|
||||
*(uint32*)(m_buffer + m_writePos) = value;
|
||||
m_writePos += 4;
|
||||
m_messageSize += 4;
|
||||
|
@ -59,7 +59,7 @@ void OutputMessage::addU32(uint32 value)
|
|||
|
||||
void OutputMessage::addU64(uint64 value)
|
||||
{
|
||||
assert(canWrite(8));
|
||||
checkWrite(8);
|
||||
*(uint64*)(m_buffer + m_writePos) = value;
|
||||
m_writePos += 8;
|
||||
m_messageSize += 8;
|
||||
|
@ -68,7 +68,9 @@ void OutputMessage::addU64(uint64 value)
|
|||
void OutputMessage::addString(const char* value)
|
||||
{
|
||||
size_t stringLength = strlen(value);
|
||||
assert(stringLength < 0xFFFF && canWrite(stringLength + 2));
|
||||
if(stringLength > 65535)
|
||||
throw NetworkException("[OutputMessage::addString] string length > 65535");
|
||||
checkWrite(stringLength + 2);
|
||||
addU16(stringLength);
|
||||
strcpy((char*)(m_buffer + m_writePos), value);
|
||||
m_writePos += stringLength;
|
||||
|
@ -82,7 +84,9 @@ void OutputMessage::addString(const std::string &value)
|
|||
|
||||
void OutputMessage::addPaddingBytes(int bytes, uint8 byte)
|
||||
{
|
||||
assert(canWrite(bytes) && bytes >= 0);
|
||||
if(bytes <= 0)
|
||||
return;
|
||||
checkWrite(bytes);
|
||||
memset((void*)&m_buffer[m_writePos], byte, bytes);
|
||||
m_writePos += bytes;
|
||||
m_messageSize += bytes;
|
||||
|
@ -94,3 +98,9 @@ bool OutputMessage::canWrite(int bytes)
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void OutputMessage::checkWrite(int bytes)
|
||||
{
|
||||
if(!canWrite(bytes))
|
||||
throw NetworkException("OutputMessage max buffer size reached");
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define OUTPUTMESSAGE_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include "networkexception.h"
|
||||
|
||||
class OutputMessage
|
||||
{
|
||||
|
@ -56,6 +57,7 @@ public:
|
|||
|
||||
private:
|
||||
bool canWrite(int bytes);
|
||||
void checkWrite(int bytes);
|
||||
|
||||
uint16 m_writePos;
|
||||
uint16 m_messageSize;
|
||||
|
|
|
@ -107,14 +107,15 @@ void Protocol::internalRecvData(uint8* buffer, uint16 size)
|
|||
if(m_checksumEnabled) {
|
||||
uint32 checksum = getAdlerChecksum(m_inputMessage.getBuffer() + InputMessage::DATA_POS, m_inputMessage.getMessageSize() - InputMessage::CHECKSUM_LENGTH);
|
||||
if(m_inputMessage.getU32() != checksum) {
|
||||
// error
|
||||
logError("got a network message with invalid checksum");
|
||||
logTraceError("got a network message with invalid checksum");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_xteaEncryptionEnabled)
|
||||
xteaDecrypt(m_inputMessage);
|
||||
if(m_xteaEncryptionEnabled) {
|
||||
if(!xteaDecrypt(m_inputMessage))
|
||||
return;
|
||||
}
|
||||
|
||||
onRecv(m_inputMessage);
|
||||
}
|
||||
|
@ -133,7 +134,7 @@ bool Protocol::xteaDecrypt(InputMessage& inputMessage)
|
|||
{
|
||||
uint16 messageSize = inputMessage.getMessageSize() - InputMessage::CHECKSUM_LENGTH;
|
||||
if(messageSize % 8 != 0) {
|
||||
logError("invalid encrypted network message");
|
||||
logTraceError("invalid encrypted network message");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -156,7 +157,7 @@ bool Protocol::xteaDecrypt(InputMessage& inputMessage)
|
|||
|
||||
int tmp = inputMessage.getU16();
|
||||
if(tmp > inputMessage.getMessageSize() - 4) {
|
||||
logError("invalid decrypted a network message");
|
||||
logTraceError("invalid decrypted a network message");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,9 +65,11 @@ void Rsa::setKey(const char* p, const char* q, const char* d)
|
|||
|
||||
mpz_clear(pm1);
|
||||
mpz_clear(qm1);
|
||||
|
||||
m_keySet = true;
|
||||
}
|
||||
|
||||
bool Rsa::encrypt(char* msg, int32_t size, const char* key)
|
||||
void Rsa::encrypt(char* msg, int32_t size, const char* key)
|
||||
{
|
||||
mpz_t plain, c;
|
||||
mpz_init2(plain, 1024);
|
||||
|
@ -92,11 +94,13 @@ bool Rsa::encrypt(char* msg, int32_t size, const char* key)
|
|||
mpz_clear(plain);
|
||||
mpz_clear(e);
|
||||
mpz_clear(mod);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Rsa::decrypt(char* msg, int32_t size)
|
||||
{
|
||||
if(!m_keySet)
|
||||
return false;
|
||||
|
||||
mpz_t c,v1,v2,u2,tmp;
|
||||
mpz_init2(c, 1024);
|
||||
mpz_init2(v1, 1024);
|
||||
|
@ -130,6 +134,5 @@ bool Rsa::decrypt(char* msg, int32_t size)
|
|||
mpz_clear(v2);
|
||||
mpz_clear(u2);
|
||||
mpz_clear(tmp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
|
||||
void setKey(const char* p, const char* q, const char* d);
|
||||
bool decrypt(char* msg, int32_t size);
|
||||
static bool encrypt(char* msg, int32_t size, const char* key);
|
||||
static void encrypt(char* msg, int32_t size, const char* key);
|
||||
|
||||
protected:
|
||||
bool m_keySet;
|
||||
|
|
|
@ -36,11 +36,6 @@ public:
|
|||
/// Poll platform input/window events
|
||||
void poll();
|
||||
|
||||
void updateTicks();
|
||||
|
||||
/// Get current time in milliseconds since last application init
|
||||
int getTicks() { return m_lastTicks; }
|
||||
|
||||
/// Sleep in current thread
|
||||
void sleep(ulong ms);
|
||||
|
||||
|
@ -84,9 +79,6 @@ public:
|
|||
std::string getAppUserDir();
|
||||
|
||||
void displayFatalError(const std::string& message);
|
||||
|
||||
private:
|
||||
int m_lastTicks;
|
||||
};
|
||||
|
||||
extern Platform g_platform;
|
||||
|
|
|
@ -370,9 +370,6 @@ void Platform::init(PlatformListener* platformListener, const char *appName)
|
|||
x11.atomWindowState = XInternAtom(x11.display, "_NET_WM_STATE", False);
|
||||
x11.atomWindowMaximizedVert = XInternAtom(x11.display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
|
||||
x11.atomWindowMaximizedHorz = XInternAtom(x11.display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
|
||||
|
||||
// force first tick
|
||||
updateTicks();
|
||||
}
|
||||
|
||||
void Platform::terminate()
|
||||
|
@ -585,26 +582,6 @@ void Platform::poll()
|
|||
}
|
||||
}
|
||||
|
||||
void Platform::updateTicks()
|
||||
{
|
||||
static timeval tv;
|
||||
static ulong firstTick = 0;
|
||||
|
||||
gettimeofday(&tv, 0);
|
||||
if(!firstTick)
|
||||
firstTick = tv.tv_sec;
|
||||
|
||||
m_lastTicks = ((tv.tv_sec - firstTick) * 1000) + (tv.tv_usec / 1000);
|
||||
}
|
||||
|
||||
void Platform::sleep(ulong miliseconds)
|
||||
{
|
||||
timespec tv;
|
||||
tv.tv_sec = miliseconds / 1000;
|
||||
tv.tv_nsec = (miliseconds % 1000) * 1000000;
|
||||
nanosleep(&tv, NULL);
|
||||
}
|
||||
|
||||
bool Platform::createWindow(int x, int y, int width, int height, int minWidth, int minHeight, bool maximized)
|
||||
{
|
||||
static int attrList[] = {
|
||||
|
@ -729,11 +706,11 @@ void Platform::setWindowIcon(const std::string& pngIcon)
|
|||
|
||||
Atom property = XInternAtom(x11.display, "_NET_WM_ICON", 0);
|
||||
if(!XChangeProperty(x11.display, x11.window, property, XA_CARDINAL, 32, PropModeReplace, (const unsigned char*)&iconData[0], iconData.size()))
|
||||
logError("could not set app icon");
|
||||
logError("Couldn't set app icon");
|
||||
|
||||
free_apng(&apng);
|
||||
} else
|
||||
logError("could not load app icon");
|
||||
logError("Couldn't load app icon");
|
||||
}
|
||||
|
||||
void Platform::destroyWindow()
|
||||
|
@ -835,7 +812,7 @@ const char *Platform::getClipboardText()
|
|||
XFlush(x11.display);
|
||||
|
||||
// hack to wait SelectioNotify event, otherwise we will get wrong clipboard pastes
|
||||
sleep(100);
|
||||
usleep(100 * 1000);
|
||||
|
||||
// check for data
|
||||
Atom type;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "uitranslator.h"
|
||||
#include <framework/graphics/font.h>
|
||||
#include <framework/otml/otmlnode.h>
|
||||
#include <framework/platform/platform.h>
|
||||
#include <framework/core/clock.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
|
||||
UIFrameCounter::UIFrameCounter()
|
||||
|
@ -32,7 +32,7 @@ UIFrameCounter::UIFrameCounter()
|
|||
m_focusable = false;
|
||||
m_phantom = true;
|
||||
m_align = Fw::AlignLeft;
|
||||
m_lastFrameTicks = g_platform.getTicks();
|
||||
m_lastFrameTicks = g_clock.ticks();
|
||||
m_frameCount = 0;
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ void UIFrameCounter::render()
|
|||
{
|
||||
UIWidget::render();
|
||||
|
||||
int now = g_platform.getTicks();
|
||||
int now = g_clock.ticks();
|
||||
if(now - m_lastFrameTicks >= 1000) {
|
||||
m_fpsText = Fw::mkstr("FPS: ", m_frameCount);
|
||||
m_lastFrameTicks = now;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <framework/graphics/font.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/platform/platform.h>
|
||||
#include <framework/core/clock.h>
|
||||
#include <framework/otml/otmlnode.h>
|
||||
|
||||
UILineEdit::UILineEdit()
|
||||
|
@ -55,7 +56,7 @@ void UILineEdit::render()
|
|||
assert(m_cursorPos <= textLength);
|
||||
// draw every 333ms
|
||||
const int delay = 333;
|
||||
int ticks = g_platform.getTicks();
|
||||
int ticks = g_clock.ticks();
|
||||
if(ticks - m_cursorTicks <= delay) {
|
||||
Rect cursorRect;
|
||||
// when cursor is at 0 or is the first visible element
|
||||
|
@ -447,5 +448,5 @@ bool UILineEdit::onMousePress(const Point& mousePos, Fw::MouseButton button)
|
|||
|
||||
void UILineEdit::blinkCursor()
|
||||
{
|
||||
m_cursorTicks = g_platform.getTicks();
|
||||
m_cursorTicks = g_clock.ticks();
|
||||
}
|
||||
|
|
|
@ -110,8 +110,8 @@ bool UIManager::importStyles(const std::string& file)
|
|||
for(const OTMLNodePtr& styleNode : doc->children())
|
||||
importStyleFromOTML(styleNode);
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
logError("failed to import ui styles from '", file, "':\n", e.what());
|
||||
} catch(Exception& e) {
|
||||
logError("Failed to import UI styles from '", file, "': ", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -153,8 +153,11 @@ OTMLNodePtr UIManager::getStyle(const std::string& styleName)
|
|||
}
|
||||
|
||||
auto it = m_styles.find(styleName);
|
||||
if(it == m_styles.end())
|
||||
throw std::runtime_error(Fw::mkstr("style '", styleName, "' is not a defined style"));
|
||||
if(it == m_styles.end()) {
|
||||
logError("Unable to retrive style '", styleName, "': not a defined style");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_styles[styleName];
|
||||
}
|
||||
|
||||
|
@ -171,14 +174,14 @@ UIWidgetPtr UIManager::loadUI(const std::string& file, const UIWidgetPtr& parent
|
|||
importStyleFromOTML(node);
|
||||
else {
|
||||
if(widget)
|
||||
throw std::runtime_error("cannot have multiple main widgets in .otui files");
|
||||
Fw::throwException("cannot have multiple main widgets in otui files");
|
||||
widget = loadWidgetFromOTML(node, parent);
|
||||
}
|
||||
}
|
||||
|
||||
return widget;
|
||||
} catch(std::exception& e) {
|
||||
logError("failed to load ui from '", file, "':\n", e.what());
|
||||
} catch(Exception& e) {
|
||||
logError("Failed to load UI from '", file, "': ", e.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,6 +142,8 @@ void UIWidget::setFocusable(bool focusable)
|
|||
void UIWidget::setStyle(const std::string& styleName)
|
||||
{
|
||||
OTMLNodePtr styleNode = g_ui.getStyle(styleName);
|
||||
if(!styleNode)
|
||||
return;
|
||||
applyStyle(styleNode);
|
||||
m_style = styleNode;
|
||||
updateStyle();
|
||||
|
@ -331,7 +333,7 @@ UIWidgetPtr UIWidget::backwardsGetWidgetById(const std::string& id)
|
|||
void UIWidget::focusChild(const UIWidgetPtr& child, Fw::FocusReason reason)
|
||||
{
|
||||
if(child && !hasChild(child)) {
|
||||
logError("attempt to focus an unknown child in a UIWidget");
|
||||
logError("Attempt to focus an unknown child in a UIWidget");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -440,7 +442,7 @@ void UIWidget::removeChild(const UIWidgetPtr& child)
|
|||
if(focusAnother && !m_focusedChild)
|
||||
focusPreviousChild(Fw::ActiveFocusReason);
|
||||
} else
|
||||
logError("attempt to remove an unknown child from a UIWidget");
|
||||
logError("Attempt to remove an unknown child from a UIWidget");
|
||||
}
|
||||
|
||||
void UIWidget::focusNextChild(Fw::FocusReason reason)
|
||||
|
@ -774,8 +776,8 @@ void UIWidget::applyStyle(const OTMLNodePtr& styleNode)
|
|||
try {
|
||||
onStyleApply(styleNode);
|
||||
callLuaField("onStyleApply", styleNode);
|
||||
} catch(std::exception& e) {
|
||||
logError("failed to apply widget '", m_id, "' style: ", e.what());
|
||||
} catch(Exception& e) {
|
||||
logError("Failed to apply style to widget '", m_id, "' style: ", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef EXCEPTION_H
|
||||
#define EXCEPTION_H
|
||||
|
||||
#include <exception>
|
||||
|
||||
class Exception : public std::exception
|
||||
{
|
||||
public:
|
||||
Exception() { }
|
||||
Exception(const std::string& what) : m_what(what) { }
|
||||
virtual ~Exception() throw() { };
|
||||
|
||||
virtual const char* what() const throw() { return m_what.c_str(); }
|
||||
|
||||
protected:
|
||||
std::string m_what;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -29,22 +29,11 @@
|
|||
#include <sstream>
|
||||
#include <exception>
|
||||
#include <cxxabi.h>
|
||||
#include <chrono>
|
||||
#include <unistd.h>
|
||||
#include "types.h"
|
||||
#include "exception.h"
|
||||
|
||||
namespace Fw {
|
||||
|
||||
inline int getTicks() {
|
||||
static auto firstTick = std::chrono::high_resolution_clock::now();
|
||||
auto tickNow = std::chrono::high_resolution_clock::now();
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(tickNow - firstTick).count();
|
||||
}
|
||||
|
||||
inline void sleep(int ms) {
|
||||
usleep(ms);
|
||||
}
|
||||
|
||||
// read utilities for istream
|
||||
inline uint8 getU8(std::istream& in) {
|
||||
uint8 tmp;
|
||||
|
@ -197,9 +186,9 @@ inline bool cast(const bool& in, std::string& out) {
|
|||
}
|
||||
|
||||
// used by safe_cast
|
||||
class BadCast : public std::bad_cast {
|
||||
class CastException : public Exception {
|
||||
public:
|
||||
virtual ~BadCast() throw() { }
|
||||
virtual ~CastException() throw() { }
|
||||
template<class T, class R>
|
||||
void setWhat() {
|
||||
m_what = mkstr("failed to cast value of type '", demangleType<T>(),
|
||||
|
@ -217,7 +206,7 @@ template<typename R, typename T>
|
|||
R safeCast(const T& t) {
|
||||
R r;
|
||||
if(!cast(t, r)) {
|
||||
BadCast e;
|
||||
CastException e;
|
||||
e.setWhat<T,R>();
|
||||
throw e;
|
||||
}
|
||||
|
@ -231,7 +220,7 @@ template<typename R, typename T>
|
|||
R unsafeCast(const T& t, R def = R()) {
|
||||
try {
|
||||
return safeCast<R,T>(t);
|
||||
} catch(BadCast& e) {
|
||||
} catch(CastException& e) {
|
||||
println("CAST ERROR: ", e.what());
|
||||
return def;
|
||||
}
|
||||
|
@ -268,6 +257,11 @@ inline std::string ip2str(uint32 ip) {
|
|||
return std::string(host);
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
void throwException(const T&... args) {
|
||||
throw Exception(Fw::mkstr(args...));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// shortcut for Fw::dump
|
||||
|
|
|
@ -27,16 +27,16 @@
|
|||
#include "tile.h"
|
||||
#include "item.h"
|
||||
|
||||
#include <framework/platform/platform.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
|
||||
#include <framework/core/clock.h>
|
||||
|
||||
Creature::Creature() : Thing()
|
||||
{
|
||||
m_healthPercent = 0;
|
||||
m_showSquareColor = false;
|
||||
m_direction = Otc::South;
|
||||
m_walkTimePerPixel = 1000.0/32.0;
|
||||
|
||||
m_walking = false;
|
||||
|
||||
|
@ -201,7 +201,7 @@ void Creature::walk(const Position& position, bool inverse)
|
|||
|
||||
m_walkTimePerPixel = walkTime / 32.0;
|
||||
if(!sameWalk)
|
||||
m_walkStartTicks = g_platform.getTicks();
|
||||
m_walkStartTicks = g_clock.ticks();
|
||||
updateWalk();
|
||||
}
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ void Creature::updateWalk()
|
|||
{
|
||||
const ThingType& type = getType();
|
||||
if(m_walking) {
|
||||
int elapsedTicks = g_platform.getTicks() - m_walkStartTicks;
|
||||
int elapsedTicks = g_clock.ticks() - m_walkStartTicks;
|
||||
int totalPixelsWalked = std::min((int)round(elapsedTicks / m_walkTimePerPixel), 32);
|
||||
|
||||
if(m_inverseWalking) {
|
||||
|
@ -240,7 +240,10 @@ void Creature::updateWalk()
|
|||
}
|
||||
|
||||
int totalWalkTileTicks = (int)m_walkTimePerPixel*32 * 0.5;
|
||||
m_animation = (g_platform.getTicks() % totalWalkTileTicks) / (totalWalkTileTicks / (type.dimensions[ThingType::AnimationPhases] - 1)) + 1;
|
||||
if(type.dimensions[ThingType::AnimationPhases] > 0)
|
||||
m_animation = (g_clock.ticks() % totalWalkTileTicks) / (totalWalkTileTicks / (type.dimensions[ThingType::AnimationPhases] - 1)) + 1;
|
||||
else
|
||||
m_animation = 0;
|
||||
g_dispatcher.scheduleEvent(std::bind(&Creature::updateWalk, asCreature()), m_walkTimePerPixel);
|
||||
|
||||
if(totalPixelsWalked == 32)
|
||||
|
@ -250,12 +253,7 @@ void Creature::updateWalk()
|
|||
|
||||
void Creature::cancelWalk(Otc::Direction direction)
|
||||
{
|
||||
m_walking = false;
|
||||
m_walkStartTicks = 0;
|
||||
m_walkOffset.x = 0;
|
||||
m_walkOffset.y = 0;
|
||||
m_direction = direction;
|
||||
|
||||
if(m_walking) {
|
||||
auto self = asCreature();
|
||||
g_dispatcher.scheduleEvent([=]() {
|
||||
if(!self->m_walking)
|
||||
|
@ -263,6 +261,13 @@ void Creature::cancelWalk(Otc::Direction direction)
|
|||
}, m_walkTimePerPixel * 2);
|
||||
}
|
||||
|
||||
m_walking = false;
|
||||
m_walkStartTicks = 0;
|
||||
m_walkOffset.x = 0;
|
||||
m_walkOffset.y = 0;
|
||||
m_direction = direction;
|
||||
}
|
||||
|
||||
void Creature::setName(const std::string& name)
|
||||
{
|
||||
m_nameSize = m_informationFont->calculateTextRectSize(name);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "thingstype.h"
|
||||
#include "map.h"
|
||||
#include "tile.h"
|
||||
#include <framework/platform/platform.h>
|
||||
#include <framework/core/clock.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
|
||||
Effect::Effect() : Thing()
|
||||
|
@ -34,7 +34,7 @@ Effect::Effect() : Thing()
|
|||
|
||||
void Effect::draw(const Point& p)
|
||||
{
|
||||
int animationPhase = (g_platform.getTicks() - m_animationStartTicks) / TICKS_PER_FRAME;
|
||||
int animationPhase = (g_clock.ticks() - m_animationStartTicks) / TICKS_PER_FRAME;
|
||||
|
||||
if(animationPhase < getAnimationPhases()) {
|
||||
m_animation = animationPhase;
|
||||
|
@ -44,7 +44,7 @@ void Effect::draw(const Point& p)
|
|||
|
||||
void Effect::startAnimation()
|
||||
{
|
||||
m_animationStartTicks = g_platform.getTicks();
|
||||
m_animationStartTicks = g_clock.ticks();
|
||||
|
||||
// schedule removal
|
||||
auto self = asEffect();
|
||||
|
|
|
@ -24,12 +24,12 @@
|
|||
#include "thingstype.h"
|
||||
#include "spritemanager.h"
|
||||
#include "thing.h"
|
||||
#include <framework/platform/platform.h>
|
||||
#include <framework/core/clock.h>
|
||||
|
||||
Item::Item() : Thing()
|
||||
{
|
||||
m_data = 0;
|
||||
m_lastTicks = g_platform.getTicks();
|
||||
m_lastTicks = g_clock.ticks();
|
||||
}
|
||||
|
||||
void Item::draw(const Point& p)
|
||||
|
@ -37,7 +37,7 @@ void Item::draw(const Point& p)
|
|||
const ThingType& type = getType();
|
||||
|
||||
if(type.dimensions[ThingType::AnimationPhases] > 1)
|
||||
m_animation = (g_platform.getTicks() % (TICKS_PER_FRAME * type.dimensions[ThingType::AnimationPhases])) / TICKS_PER_FRAME;
|
||||
m_animation = (g_clock.ticks() % (TICKS_PER_FRAME * type.dimensions[ThingType::AnimationPhases])) / TICKS_PER_FRAME;
|
||||
|
||||
for(int b = 0; b < type.dimensions[ThingType::Layers]; b++)
|
||||
internalDraw(p, b);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "thingstype.h"
|
||||
#include "map.h"
|
||||
#include "tile.h"
|
||||
#include <framework/platform/platform.h>
|
||||
#include <framework/core/clock.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
|
||||
Missile::Missile() : Thing()
|
||||
|
@ -34,7 +34,7 @@ Missile::Missile() : Thing()
|
|||
|
||||
void Missile::draw(const Point& p)
|
||||
{
|
||||
float time = (g_platform.getTicks() - m_startTicks) / m_duration;
|
||||
float time = (g_clock.ticks() - m_startTicks) / m_duration;
|
||||
internalDraw(p + Point(m_positionDelta.x * time, m_positionDelta.y * time), 0);
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ void Missile::setPath(const Position& fromPosition, const Position& toPosition)
|
|||
m_positionDelta.x *= 32;
|
||||
m_positionDelta.y *= 32;
|
||||
|
||||
m_startTicks = g_platform.getTicks();
|
||||
m_startTicks = g_clock.ticks();
|
||||
|
||||
// schedule removal
|
||||
auto self = asMissile();
|
||||
|
|
|
@ -40,8 +40,8 @@ bool SpriteManager::load(const std::string& file)
|
|||
m_spritesCount = Fw::getU16(m_fin);
|
||||
m_sprites.resize(m_spritesCount);
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
logError("faile to load sprites from '", file, "': ", e.what());
|
||||
} catch(Exception& e) {
|
||||
logError("Failed to load sprites from '", file, "': ", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,8 +48,8 @@ bool ThingsType::load(const std::string& file)
|
|||
}
|
||||
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
logError("failed to load dat from '", file, "': ", e.what());
|
||||
} catch(Exception& e) {
|
||||
logError("Failed to load dat from '", file, "': ", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,14 @@ ThingType& ThingsType::getThingType(uint16 id, Categories category)
|
|||
if(category == Item)
|
||||
id -= 100;
|
||||
|
||||
assert(id < m_things[category].size());
|
||||
//assert(id < m_things[category].size());
|
||||
|
||||
// assert wrokground
|
||||
if(id >= m_things[category].size()) {
|
||||
//logTraceErrorOnce("got an invalid type");
|
||||
static ThingType emptyType;
|
||||
return emptyType;
|
||||
}
|
||||
|
||||
return m_things[category][id];
|
||||
}
|
||||
|
|
|
@ -27,6 +27,13 @@
|
|||
|
||||
struct ThingType
|
||||
{
|
||||
ThingType() {
|
||||
// fill default values
|
||||
dimensions.fill(0);
|
||||
properties.fill(false);
|
||||
parameters.fill(0);
|
||||
}
|
||||
|
||||
enum Dimensions {
|
||||
Width = 0,
|
||||
Height,
|
||||
|
|
|
@ -43,8 +43,6 @@
|
|||
|
||||
void OTClient::registerLuaFunctions()
|
||||
{
|
||||
using namespace std::placeholders;
|
||||
|
||||
g_lua.bindGlobalFunction("exit", std::bind(&OTClient::exit, &g_client));
|
||||
g_lua.bindGlobalFunction("setOnClose", std::bind(&OTClient::setOnClose, &g_client, _1));
|
||||
g_lua.bindGlobalFunction("importDat", std::bind(&ThingsType::load, &g_thingsType, _1));
|
||||
|
|
|
@ -35,9 +35,9 @@
|
|||
|
||||
void ProtocolGame::parseMessage(InputMessage& msg)
|
||||
{
|
||||
try {
|
||||
while(!msg.eof()) {
|
||||
uint8 opt = msg.getU8();
|
||||
//dump << "protocol id:" << (int)opt;
|
||||
|
||||
switch(opt) {
|
||||
case Otc::GameServerInitGame:
|
||||
|
@ -251,10 +251,13 @@ void ProtocolGame::parseMessage(InputMessage& msg)
|
|||
//case Otc::GameServerObjectInfo:
|
||||
//case Otc::GameServerPlayerInventory:
|
||||
default:
|
||||
logError("UNKNOWN PACKET OPT BYTE: 0x", std::hex, opt);
|
||||
Fw::throwException("unknown opt byte ", opt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch(Exception& e) {
|
||||
logTraceError(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolGame::parsePlayerLogin(InputMessage& msg)
|
||||
|
@ -738,7 +741,7 @@ void ProtocolGame::parseCreatureSpeak(InputMessage& msg)
|
|||
case Otc::SpeakPrivateRed:
|
||||
break;
|
||||
default:
|
||||
logTraceDebug("Unknown speak type.", (int)type);
|
||||
logTraceError("unknown speak type ", type);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -811,7 +814,7 @@ void ProtocolGame::parseCancelWalk(InputMessage& msg)
|
|||
|
||||
void ProtocolGame::parseFloorChangeUp(InputMessage& msg)
|
||||
{
|
||||
logDebug("[ProtocolGame::parseFloorChangeUp]: This function has never been tested.");
|
||||
logTraceDebug("this function has never been tested.");
|
||||
|
||||
Position pos = g_map.getCentralPosition();
|
||||
pos.z--;
|
||||
|
@ -830,7 +833,7 @@ void ProtocolGame::parseFloorChangeUp(InputMessage& msg)
|
|||
|
||||
void ProtocolGame::parseFloorChangeDown(InputMessage& msg)
|
||||
{
|
||||
logDebug("[ProtocolGame::parseFloorChangeDown]: This function has never been tested.");
|
||||
logTraceDebug("this function has never been tested.");
|
||||
|
||||
Position pos = g_map.getCentralPosition();
|
||||
pos.z++;
|
||||
|
@ -982,13 +985,13 @@ void ProtocolGame::setTileDescription(InputMessage& msg, Position position)
|
|||
g_map.cleanTile(position);
|
||||
|
||||
int stackPos = 0;
|
||||
while(1){
|
||||
while(true) {
|
||||
uint16 inspectTileId = msg.getU16(true);
|
||||
if(inspectTileId >= 0xFF00)
|
||||
return;
|
||||
else {
|
||||
if(stackPos >= 10)
|
||||
logWarning("Too many things!");
|
||||
logTraceWarning("too many things");
|
||||
|
||||
ThingPtr thing = internalGetThing(msg);
|
||||
g_map.addThing(thing, position, 255);
|
||||
|
|
|
@ -52,8 +52,7 @@ void ProtocolGame::sendLoginPacket(uint32 timestamp, uint8 unknown)
|
|||
oMsg.addPaddingBytes(128 - (29 + m_accountName.length() + m_characterName.length() + m_accountPassword.length()));
|
||||
|
||||
// encrypt with RSA
|
||||
if(!Rsa::encrypt((char*)oMsg.getBuffer() + 6 + oMsg.getMessageSize() - 128, 128, Otc::OtservPublicRSA))
|
||||
return;
|
||||
Rsa::encrypt((char*)oMsg.getBuffer() + 6 + oMsg.getMessageSize() - 128, 128, Otc::OtservPublicRSA);
|
||||
|
||||
send(oMsg);
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ void ProtocolLogin::onConnect()
|
|||
|
||||
void ProtocolLogin::onRecv(InputMessage& inputMessage)
|
||||
{
|
||||
try {
|
||||
while(!inputMessage.eof()) {
|
||||
uint8 opt = inputMessage.getU8();
|
||||
switch(opt) {
|
||||
|
@ -68,8 +69,14 @@ void ProtocolLogin::onRecv(InputMessage& inputMessage)
|
|||
case Otc::LoginServerCharacterList:
|
||||
parseCharacterList(inputMessage);
|
||||
break;
|
||||
default:
|
||||
Fw::throwException("unknown opt byte ", opt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch(Exception& e) {
|
||||
logTraceError(e.what());
|
||||
}
|
||||
disconnect();
|
||||
}
|
||||
|
||||
|
@ -104,14 +111,10 @@ void ProtocolLogin::sendLoginPacket()
|
|||
|
||||
// complete the 128 bytes for rsa encryption with zeros
|
||||
oMsg.addPaddingBytes(128 - (21 + m_accountName.length() + m_accountPassword.length()));
|
||||
|
||||
if(!Rsa::encrypt((char*)oMsg.getBuffer() + InputMessage::DATA_POS + oMsg.getMessageSize() - 128, 128, Otc::OtservPublicRSA))
|
||||
return;
|
||||
Rsa::encrypt((char*)oMsg.getBuffer() + InputMessage::DATA_POS + oMsg.getMessageSize() - 128, 128, Otc::OtservPublicRSA);
|
||||
|
||||
send(oMsg);
|
||||
|
||||
enableXteaEncryption();
|
||||
|
||||
recv();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,17 +23,17 @@
|
|||
#include "otclient.h"
|
||||
|
||||
#include <framework/core/modulemanager.h>
|
||||
#include <framework/core/configs.h>
|
||||
#include <framework/core/configmanager.h>
|
||||
#include <framework/core/resourcemanager.h>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
#include <framework/core/clock.h>
|
||||
#include <framework/luascript/luainterface.h>
|
||||
#include <framework/platform/platform.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/graphics/fontmanager.h>
|
||||
#include <framework/ui/uimanager.h>
|
||||
#include <framework/ui/uiwidget.h>
|
||||
#include <framework/net/connection.h>
|
||||
|
||||
#include <framework/platform/platform.h>
|
||||
#include <otclient/net/protocolgame.h>
|
||||
#include <otclient/core/game.h>
|
||||
#include <otclient/core/map.h>
|
||||
|
@ -79,9 +79,6 @@ void OTClient::init(std::vector<std::string> args)
|
|||
// initialize graphics
|
||||
g_graphics.init();
|
||||
|
||||
// initialize event dispatcher
|
||||
g_dispatcher.init();
|
||||
|
||||
// initialize the ui
|
||||
g_ui.init();
|
||||
|
||||
|
@ -105,7 +102,7 @@ void OTClient::init(std::vector<std::string> args)
|
|||
|
||||
void OTClient::run()
|
||||
{
|
||||
int frameTicks = g_platform.getTicks();
|
||||
int frameTicks = g_clock.ticks();
|
||||
int lastPollTicks = frameTicks;
|
||||
int frameCount = 0;
|
||||
|
||||
|
@ -113,7 +110,7 @@ void OTClient::run()
|
|||
m_running = true;
|
||||
|
||||
if(g_ui.getRootWidget()->getChildCount() == 0) {
|
||||
logError("there is no root widgets to display, the app will close");
|
||||
logError("There is no root widgets to display, the app will close");
|
||||
m_stopping = true;
|
||||
}
|
||||
|
||||
|
@ -122,8 +119,7 @@ void OTClient::run()
|
|||
|
||||
while(!m_stopping) {
|
||||
//g_platform.sleep(150);
|
||||
g_platform.updateTicks();
|
||||
frameTicks = g_platform.getTicks();
|
||||
frameTicks = g_clock.updateTicks();
|
||||
|
||||
// poll events every POLL_CYCLE_DELAY
|
||||
// this delay exists to avoid massive polling thus increasing framerate
|
||||
|
@ -147,7 +143,7 @@ void OTClient::run()
|
|||
g_platform.swapBuffers();
|
||||
} else {
|
||||
// sleeps until next poll to avoid massive cpu usage
|
||||
Fw::sleep(POLL_CYCLE_DELAY+1);
|
||||
g_clock.sleep(POLL_CYCLE_DELAY+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,8 +173,8 @@ void OTClient::terminate()
|
|||
// terminate network
|
||||
Connection::terminate();
|
||||
|
||||
// terminate dispatcher
|
||||
g_dispatcher.terminate();
|
||||
// flush remaining dispatcher events
|
||||
g_dispatcher.flush();
|
||||
|
||||
// terminate graphics
|
||||
g_graphics.terminate();
|
||||
|
@ -257,7 +253,7 @@ void OTClient::saveConfigurations()
|
|||
|
||||
// saves user configuration
|
||||
if(!g_configs.save())
|
||||
logError("configurations are lost because it couldn't be saved");
|
||||
logError("Configurations are lost because it couldn't be saved");
|
||||
}
|
||||
|
||||
void OTClient::onClose()
|
||||
|
|
Loading…
Reference in New Issue