Platform fixes and rework ping

This commit is contained in:
Eduardo Bart 2013-02-24 17:26:19 -03:00
parent a8c175452b
commit 06e2b6eca2
31 changed files with 178 additions and 111 deletions

View File

@ -21,45 +21,3 @@ MenuLabel < Label
GameLabel < UILabel GameLabel < UILabel
font: verdana-11px-antialised font: verdana-11px-antialised
color: #bbbbbb color: #bbbbbb
FrameCounterLabel < Label
font: verdana-11px-rounded
@onSetup: |
self.updateEvent = cycleEvent(function()
local text = 'FPS: ' .. g_app.getBackgroundPaneFps()
self:setText(text)
end, 1000)
@onDestroy: self.updateEvent:cancel()
PingLabel < Label
font: verdana-11px-rounded
@onSetup: |
self.updateEvent = cycleEvent(function()
if g_game.isOnline() and modules.client_options.getOption('showPing') then
local ping = -1
if g_game.getFeature(GameClientPing) or g_game.getFeature(GameExtendedClientPing) then
ping = g_game.getPing()
else
ping = g_game.getLocalPlayer():getWalkPing()
end
local text = 'Ping: '
if ping < 0 then
text = text .. "??"
self:setColor('yellow')
else
text = text .. ping .. ' ms'
if ping >= 500 then
self:setColor('red')
elseif ping >= 250 then
self:setColor('yellow')
else
self:setColor('green')
end
end
self:setText(text)
self:show()
else
self:hide()
end
end, 1000)
@onDestroy: self.updateEvent:cancel()

View File

@ -46,7 +46,11 @@ TopMenuPanel < Panel
image-repeated: true image-repeated: true
focusable: false focusable: false
TopMenuFrameCounterLabel < FrameCounterLabel TopMenuFrameCounterLabel < Label
font: verdana-11px-rounded
color: white color: white
margin-top: 4 margin-top: 4
margin-left: 5 margin-left: 5
TopMenuPingLabel < Label
font: verdana-11px-rounded

View File

@ -145,10 +145,10 @@ function EnterGame.firstShow()
local host = g_settings.get('host') local host = g_settings.get('host')
local autologin = g_settings.getBoolean('autologin') local autologin = g_settings.getBoolean('autologin')
if #host > 0 and #password > 0 and #account > 0 and autologin then if #host > 0 and #password > 0 and #account > 0 and autologin then
connect(g_app, { onRun = function() addEvent(function()
if not g_settings.getBoolean('autologin') then return end if not g_settings.getBoolean('autologin') then return end
EnterGame.doLogin() EnterGame.doLogin()
end}) end)
end end
end end

View File

@ -1,7 +1,7 @@
MainWindow MainWindow
id: waitingWindow id: waitingWindow
!text: tr('Waiting List') !text: tr('Waiting List')
size: 260 160 size: 260 180
@onEscape: CharacterList.cancelWait() @onEscape: CharacterList.cancelWait()
Label Label

View File

@ -179,15 +179,9 @@ function setOption(key, value)
if key == 'vsync' then if key == 'vsync' then
g_window.setVerticalSync(value) g_window.setVerticalSync(value)
elseif key == 'showFps' then elseif key == 'showFps' then
addEvent(function() modules.client_topmenu.setFpsVisible(value)
local frameCounter = rootWidget:recursiveGetChildById('frameCounter')
if frameCounter then frameCounter:setVisible(value) end
end)
elseif key == 'showPing' then elseif key == 'showPing' then
addEvent(function() modules.client_topmenu.setPingVisible(value)
local ping = rootWidget:recursiveGetChildById('pingLabel')
if ping then ping:setVisible(value) end
end)
elseif key == 'fullscreen' then elseif key == 'fullscreen' then
g_window.setFullscreen(value) g_window.setFullscreen(value)
panel = graphicsPanel panel = graphicsPanel

View File

@ -92,3 +92,8 @@ function createDebugUIItem(id)
uiitem:setItemId(id) uiitem:setItemId(id)
uiitem:show() uiitem:show()
end end
function debugPings()
g_game.setPingDelay(0)
connect(g_game, { onPingBack = function(ping) print(g_game.getWorldName() .. ' => ' .. ping .. ' ms') end })
end

View File

@ -37,8 +37,10 @@ end
-- public functions -- public functions
function init() function init()
connect(g_game, { onGameStart = showGameButtons, connect(g_game, { onGameStart = online,
onGameEnd = hideGameButtons }) onGameEnd = offline,
onPingBack = updatePing })
connect(g_app, { onFps = updateFps })
topMenu = g_ui.displayUI('topmenu') topMenu = g_ui.displayUI('topmenu')
@ -46,20 +48,75 @@ function init()
rightButtonsPanel = topMenu:getChildById('rightButtonsPanel') rightButtonsPanel = topMenu:getChildById('rightButtonsPanel')
leftGameButtonsPanel = topMenu:getChildById('leftGameButtonsPanel') leftGameButtonsPanel = topMenu:getChildById('leftGameButtonsPanel')
rightGameButtonsPanel = topMenu:getChildById('rightGameButtonsPanel') rightGameButtonsPanel = topMenu:getChildById('rightGameButtonsPanel')
pingLabel = topMenu:getChildById('pingLabel')
fpsLabel = topMenu:getChildById('fpsLabel')
if g_game.isOnline() then if g_game.isOnline() then
leftGameButtonsPanel:show() online()
rightGameButtonsPanel:show()
end end
end end
function terminate() function terminate()
disconnect(g_game, { onGameStart = showGameButtons, disconnect(g_game, { onGameStart = online,
onGameEnd = hideGameButtons }) onGameEnd = offline,
onPingBack = updatePing })
disconnect(g_app, { onFps = updateFps })
topMenu:destroy() topMenu:destroy()
end end
function online()
showGameButtons()
if modules.client_options.getOption('showFps') then
pingLabel:show()
end
end
function offline()
hideGameButtons()
pingLabel:hide()
end
function updateFps(fps)
text = 'FPS: ' .. fps
fpsLabel:setText(text)
end
function updatePing(ping)
local ping = -1
if g_game.getFeature(GameClientPing) or g_game.getFeature(GameExtendedClientPing) then
ping = g_game.getPing()
else
ping = g_game.getLocalPlayer():getWalkPing()
end
local text = 'Ping: '
local color
if ping < 0 then
text = text .. "??"
color = 'yellow'
else
text = text .. ping .. ' ms'
if ping >= 500 then
color = 'red'
elseif ping >= 250 then
color = 'yellow'
else
color = 'green'
end
end
pingLabel:setColor(color)
pingLabel:setText(text)
end
function setPingVisible(enable)
pingLabel:setVisible(enable)
end
function setFpsVisible(enable)
fpsLabel:setVisible(enable)
end
function addLeftButton(id, description, icon, callback, front) function addLeftButton(id, description, icon, callback, front)
return addButton(id, description, icon, callback, leftButtonsPanel, false, front) return addButton(id, description, icon, callback, leftButtonsPanel, false, front)
end end
@ -92,16 +149,16 @@ function addRightGameToggleButton(id, description, icon, callback, front)
return addButton(id, description, icon, callback, rightGameButtonsPanel, true, front) return addButton(id, description, icon, callback, rightGameButtonsPanel, true, front)
end end
function hideGameButtons()
leftGameButtonsPanel:hide()
rightGameButtonsPanel:hide()
end
function showGameButtons() function showGameButtons()
leftGameButtonsPanel:show() leftGameButtonsPanel:show()
rightGameButtonsPanel:show() rightGameButtonsPanel:show()
end end
function hideGameButtons()
leftGameButtonsPanel:hide()
rightGameButtonsPanel:hide()
end
function getButton(id) function getButton(id)
return topMenu:recursiveGetChildById(id) return topMenu:recursiveGetChildById(id)
end end

View File

@ -18,17 +18,17 @@ TopMenuPanel
visible: false visible: false
TopMenuFrameCounterLabel TopMenuFrameCounterLabel
id: frameCounter id: fpsLabel
text-auto-resize: true text-auto-resize: true
anchors.top: parent.top anchors.top: parent.top
anchors.left: leftGameButtonsPanel.right anchors.left: leftGameButtonsPanel.right
PingLabel TopMenuPingLabel
color: white color: white
id: pingLabel id: pingLabel
text-auto-resize: true text-auto-resize: true
anchors.top: frameCounter.bottom anchors.top: fpsLabel.bottom
anchors.left: frameCounter.left anchors.left: fpsLabel.left
TopMenuButtonsPanel TopMenuButtonsPanel
id: rightButtonsPanel id: rightButtonsPanel

View File

@ -113,6 +113,7 @@ function UIMinimap:addFlag(pos, icon, description)
flag:setIcon('/images/game/minimap/flag' .. icon) flag:setIcon('/images/game/minimap/flag' .. icon)
flag:setTooltip(description) flag:setTooltip(description)
flag.onMouseRelease = onFlagMouseRelease flag.onMouseRelease = onFlagMouseRelease
flag.onDestroy = function() table.removevalue(self.flags, flag) end
table.insert(self.flags, flag) table.insert(self.flags, flag)
self:centerInPosition(flag, pos) self:centerInPosition(flag, pos)
end end
@ -162,7 +163,6 @@ function UIMinimap:removeFlag(pos, icon, description)
local flag = self:getFlag(pos) local flag = self:getFlag(pos)
if flag then if flag then
flag:destroy() flag:destroy()
table.removevalue(self.flags, flag)
end end
end end

View File

@ -47,6 +47,7 @@ Game::Game()
m_serverBeat = 50; m_serverBeat = 50;
m_seq = 0; m_seq = 0;
m_ping = -1; m_ping = -1;
m_pingDelay = 1000;
m_canReportBugs = false; m_canReportBugs = false;
m_fightMode = Otc::FightBalanced; m_fightMode = Otc::FightBalanced;
m_chaseMode = Otc::DontChase; m_chaseMode = Otc::DontChase;
@ -79,6 +80,8 @@ void Game::resetGameStates()
m_followingCreature = nullptr; m_followingCreature = nullptr;
m_attackingCreature = nullptr; m_attackingCreature = nullptr;
m_localPlayer = nullptr; m_localPlayer = nullptr;
m_pingSent = 0;
m_pingReceived = 0;
for(auto& it : m_containers) { for(auto& it : m_containers) {
const ContainerPtr& container = it.second; const ContainerPtr& container = it.second;
@ -176,14 +179,9 @@ void Game::processGameStart()
disableBotCall(); disableBotCall();
if(g_game.getFeature(Otc::GameClientPing) || g_game.getFeature(Otc::GameExtendedClientPing)) { if(g_game.getFeature(Otc::GameClientPing) || g_game.getFeature(Otc::GameExtendedClientPing)) {
m_protocolGame->sendPing(); m_pingEvent = g_dispatcher.scheduleEvent([this] {
m_pingEvent = g_dispatcher.cycleEvent([this] { g_game.ping();
if(m_protocolGame && m_protocolGame->isConnected()) { }, m_pingDelay);
enableBotCall();
m_protocolGame->sendPing();
disableBotCall();
}
}, 2000);
} }
} }
@ -224,10 +222,20 @@ void Game::processPing()
disableBotCall(); disableBotCall();
} }
void Game::processPingBack(int elapsed) void Game::processPingBack()
{ {
m_ping = elapsed; m_pingReceived++;
g_lua.callGlobalField("g_game", "onPingBack", elapsed);
if(m_pingReceived == m_pingSent)
m_ping = m_pingTimer.elapsed_millis();
else
g_logger.error("got an invalid ping from server");
g_lua.callGlobalField("g_game", "onPingBack", m_ping);
m_pingEvent = g_dispatcher.scheduleEvent([this] {
g_game.ping();
}, m_pingDelay);
} }
void Game::processTextMessage(Otc::MessageMode mode, const std::string& text) void Game::processTextMessage(Otc::MessageMode mode, const std::string& text)
@ -1252,9 +1260,14 @@ void Game::ping()
if(!m_protocolGame || !m_protocolGame->isConnected()) if(!m_protocolGame || !m_protocolGame->isConnected())
return; return;
if(m_pingReceived != m_pingSent)
return;
m_denyBotCall = false; m_denyBotCall = false;
m_protocolGame->sendPing(); m_protocolGame->sendPing();
m_denyBotCall = true; m_denyBotCall = true;
m_pingSent++;
m_pingTimer.restart();
} }
void Game::changeMapAwareRange(int xrange, int yrange) void Game::changeMapAwareRange(int xrange, int yrange)

View File

@ -54,7 +54,7 @@ protected:
void processConnectionError(const boost::system::error_code& error); void processConnectionError(const boost::system::error_code& error);
void processDisconnect(); void processDisconnect();
void processPing(); void processPing();
void processPingBack(int elapsed); void processPingBack();
void processUpdateNeeded(const std::string& signature); void processUpdateNeeded(const std::string& signature);
void processLoginError(const std::string& error); void processLoginError(const std::string& error);
@ -252,6 +252,7 @@ public:
//void reportRuleViolation2(); //void reportRuleViolation2();
void ping(); void ping();
void setPingDelay(int delay) { m_pingDelay = delay; }
// otclient only // otclient only
void changeMapAwareRange(int xrange, int yrange); void changeMapAwareRange(int xrange, int yrange);
@ -280,7 +281,7 @@ public:
bool isAttacking() { return !!m_attackingCreature; } bool isAttacking() { return !!m_attackingCreature; }
bool isFollowing() { return !!m_followingCreature; } bool isFollowing() { return !!m_followingCreature; }
int getPing() { return m_ping; } int getPing() { return m_ping >= 0 ? std::max(m_ping, m_pingTimer.elapsed_millis()) : -1; }
ContainerPtr getContainer(int index) { return m_containers[index]; } ContainerPtr getContainer(int index) { return m_containers[index]; }
std::map<int, ContainerPtr> getContainers() { return m_containers; } std::map<int, ContainerPtr> getContainers() { return m_containers; }
std::map<int, Vip> getVips() { return m_vips; } std::map<int, Vip> getVips() { return m_vips; }
@ -320,8 +321,12 @@ private:
bool m_denyBotCall; bool m_denyBotCall;
bool m_dead; bool m_dead;
int m_serverBeat; int m_serverBeat;
int m_ping; ticks_t m_ping;
uint m_pingSent;
uint m_pingReceived;
stdext::timer m_pingTimer;
uint m_seq; uint m_seq;
int m_pingDelay;
Otc::FightModes m_fightMode; Otc::FightModes m_fightMode;
Otc::ChaseModes m_chaseMode; Otc::ChaseModes m_chaseMode;
Otc::Direction m_lastWalkDir; Otc::Direction m_lastWalkDir;

View File

@ -77,7 +77,7 @@ bool LocalPlayer::canWalk(Otc::Direction direction)
return false; return false;
// prewalk has a timeout, because for some reason that I don't know yet the server sometimes doesn't answer the prewalk // prewalk has a timeout, because for some reason that I don't know yet the server sometimes doesn't answer the prewalk
bool prewalkTimeouted = m_walking && m_preWalking && m_walkTimer.ticksElapsed() >= getStepDuration() + PREWALK_TIMEOUT; bool prewalkTimeouted = m_walking && m_preWalking && m_walkTimer.ticksElapsed() >= getStepDuration() + 5*PREWALK_TIMEOUT;
// avoid doing more walks than wanted when receiving a lot of walks from server // avoid doing more walks than wanted when receiving a lot of walks from server
if(!m_lastPrewalkDone && m_preWalking && !prewalkTimeouted) if(!m_lastPrewalkDone && m_preWalking && !prewalkTimeouted)
@ -127,8 +127,9 @@ void LocalPlayer::preWalk(Otc::Direction direction)
Position newPos = m_position.translatedToDirection(direction); Position newPos = m_position.translatedToDirection(direction);
// avoid reanimating prewalks // avoid reanimating prewalks
if(m_preWalking && m_lastPrewalkDestination == newPos) if(m_preWalking && m_lastPrewalkDestination == newPos) {
return; return;
}
m_waitingWalkPong = false; m_waitingWalkPong = false;
if(m_walkPingTimer.ticksElapsed() > getStepDuration() && m_idleTimer.ticksElapsed() > getStepDuration()*2) { if(m_walkPingTimer.ticksElapsed() > getStepDuration() && m_idleTimer.ticksElapsed() > getStepDuration()*2) {
@ -157,6 +158,7 @@ void LocalPlayer::cancelWalk(Otc::Direction direction)
m_waitingWalkPong = false; m_waitingWalkPong = false;
m_walkPingTimer.restart(); m_walkPingTimer.restart();
m_idleTimer.restart(); m_idleTimer.restart();
lockWalk();
if(m_autoWalkDestination.isValid()) { if(m_autoWalkDestination.isValid()) {
g_game.stop(); g_game.stop();

View File

@ -219,6 +219,7 @@ void Client::registerLuaFunctions()
g_lua.bindSingletonFunction("g_game", "mount", &Game::mount, &g_game); g_lua.bindSingletonFunction("g_game", "mount", &Game::mount, &g_game);
g_lua.bindSingletonFunction("g_game", "requestItemInfo", &Game::requestItemInfo, &g_game); g_lua.bindSingletonFunction("g_game", "requestItemInfo", &Game::requestItemInfo, &g_game);
g_lua.bindSingletonFunction("g_game", "ping", &Game::ping, &g_game); g_lua.bindSingletonFunction("g_game", "ping", &Game::ping, &g_game);
g_lua.bindSingletonFunction("g_game", "setPingDelay", &Game::setPingDelay, &g_game);
g_lua.bindSingletonFunction("g_game", "changeMapAwareRange", &Game::changeMapAwareRange, &g_game); g_lua.bindSingletonFunction("g_game", "changeMapAwareRange", &Game::changeMapAwareRange, &g_game);
g_lua.bindSingletonFunction("g_game", "canPerformGameAction", &Game::canPerformGameAction, &g_game); g_lua.bindSingletonFunction("g_game", "canPerformGameAction", &Game::canPerformGameAction, &g_game);
g_lua.bindSingletonFunction("g_game", "canReportBugs", &Game::canReportBugs, &g_game); g_lua.bindSingletonFunction("g_game", "canReportBugs", &Game::canReportBugs, &g_game);

View File

@ -37,7 +37,6 @@
#include <framework/core/eventdispatcher.h> #include <framework/core/eventdispatcher.h>
#include <framework/core/application.h> #include <framework/core/application.h>
#include <framework/core/resourcemanager.h> #include <framework/core/resourcemanager.h>
#include <boost/concept_check.hpp>
enum { enum {

View File

@ -235,7 +235,6 @@ private:
std::string m_accountName; std::string m_accountName;
std::string m_accountPassword; std::string m_accountPassword;
std::string m_characterName; std::string m_characterName;
stdext::timer m_pingTimer;
LocalPlayerPtr m_localPlayer; LocalPlayerPtr m_localPlayer;
}; };

View File

@ -430,7 +430,7 @@ void ProtocolGame::parsePing(const InputMessagePtr& msg)
void ProtocolGame::parsePingBack(const InputMessagePtr& msg) void ProtocolGame::parsePingBack(const InputMessagePtr& msg)
{ {
g_game.processPingBack(m_pingTimer.elapsed_millis()); g_game.processPingBack();
} }
void ProtocolGame::parseChallenge(const InputMessagePtr& msg) void ProtocolGame::parseChallenge(const InputMessagePtr& msg)

View File

@ -129,7 +129,6 @@ void ProtocolGame::sendPing()
msg->addU8(Proto::ClientPing); msg->addU8(Proto::ClientPing);
Protocol::send(msg); Protocol::send(msg);
} }
m_pingTimer.restart();
} }
void ProtocolGame::sendPingBack() void ProtocolGame::sendPingBack()

View File

@ -137,6 +137,7 @@ if(NOT APPLE)
option(CRASH_HANDLER "Generate crash reports" ON) option(CRASH_HANDLER "Generate crash reports" ON)
option(USE_STATIC_LIBS "Don't use shared libraries (dlls)" ON) option(USE_STATIC_LIBS "Don't use shared libraries (dlls)" ON)
option(USE_LIBCPP "Use the new libc++ library instead of stdc++" OFF) option(USE_LIBCPP "Use the new libc++ library instead of stdc++" OFF)
option(USE_LTO "Use link time optimizations" OFF)
else() else()
set(CRASH_HANDLER OFF) set(CRASH_HANDLER OFF)
set(USE_STATIC_LIBS OFF) set(USE_STATIC_LIBS OFF)
@ -162,10 +163,18 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNS_FLAGS} ${ARCH_
set(CMAKE_CXX_FLAGS_COMPILESPEED "-O0") set(CMAKE_CXX_FLAGS_COMPILESPEED "-O0")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g") set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O1 -g -fno-omit-frame-pointer") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O1 -g -fno-omit-frame-pointer")
set(CMAKE_CXX_FLAGS_RELEASE "-O2") set(CMAKE_CXX_FLAGS_RELEASE "-Os")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
set(CMAKE_CXX_FLAGS_PERFORMANCE "-Ofast -mmmx -msse -msse2") set(CMAKE_CXX_FLAGS_PERFORMANCE "-Ofast -mmmx -msse -msse2")
if(USE_LTO)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fwhole-program -flto")
if(WIN32)
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,-O1,--gc-sections,--sort-common,--relax")
else()
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,-O1,--gc-sections,--sort-common,--relax,-z,relro")
endif()
endif()
# process options # process options
if(USE_STATIC_LIBS) if(USE_STATIC_LIBS)
if(NOT APPLE) if(NOT APPLE)
@ -231,8 +240,8 @@ else()
if(NOT CMAKE_BUILD_TYPE STREQUAL "CompileSpeed") if(NOT CMAKE_BUILD_TYPE STREQUAL "CompileSpeed")
set(framework_DEFINITIONS ${framework_DEFINITIONS} -DNDEBUG) # NDEBUG disable asserts set(framework_DEFINITIONS ${framework_DEFINITIONS} -DNDEBUG) # NDEBUG disable asserts
endif() endif()
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,-s") # strip all debug information
if(NOT APPLE) if(NOT APPLE)
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,-s") # strip all debug information
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,--as-needed") # only link needed libraries set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,--as-needed") # only link needed libraries
endif() endif()
endif() endif()

View File

@ -60,7 +60,7 @@ void AdaptativeFrameCounter::processNextFrame()
m_lastFrame = now ; m_lastFrame = now ;
} }
void AdaptativeFrameCounter::update() bool AdaptativeFrameCounter::update()
{ {
ticks_t now = g_clock.micros(); ticks_t now = g_clock.micros();
ticks_t delta = now - m_lastPartialFpsUpdate; ticks_t delta = now - m_lastPartialFpsUpdate;
@ -82,7 +82,9 @@ void AdaptativeFrameCounter::update()
m_frameDelaySum = 0; m_frameDelaySum = 0;
//dump << stdext::format("FPS => %d Partial FPS => %d Frame Delay Hit => %.2f%%", m_lastFps, (int)m_partialFps, getFrameDelayHit()); //dump << stdext::format("FPS => %d Partial FPS => %d Frame Delay Hit => %.2f%%", m_lastFps, (int)m_partialFps, getFrameDelayHit());
return true;
} }
return false;
} }
void AdaptativeFrameCounter::setMaxFps(int maxFps) void AdaptativeFrameCounter::setMaxFps(int maxFps)

View File

@ -43,7 +43,7 @@ public:
bool shouldProcessNextFrame(); bool shouldProcessNextFrame();
void processNextFrame(); void processNextFrame();
void update(); bool update();
void setMaxFps(int maxFps); void setMaxFps(int maxFps);
bool isFpsLimitActive() { return m_maxFps != 0; } bool isFpsLimitActive() { return m_maxFps != 0; }

View File

@ -184,7 +184,8 @@ void GraphicalApplication::run()
// only update the current time once per frame to gain performance // only update the current time once per frame to gain performance
g_clock.update(); g_clock.update();
m_backgroundFrameCounter.update(); if(m_backgroundFrameCounter.update())
g_lua.callGlobalField("g_app", "onFps", m_backgroundFrameCounter.getLastFps());
m_foregroundFrameCounter.update(); m_foregroundFrameCounter.update();
int sleepMicros = m_backgroundFrameCounter.getMaximumSleepMicros(); int sleepMicros = m_backgroundFrameCounter.getMaximumSleepMicros();

View File

@ -45,10 +45,11 @@ void ResourceManager::terminate()
bool ResourceManager::discoverWorkDir(const std::string& existentFile) bool ResourceManager::discoverWorkDir(const std::string& existentFile)
{ {
// search for modules directory // search for modules directory
std::string possiblePaths[] = { g_resources.getCurrentDir(), std::string possiblePaths[] = { g_platform.getCurrentDir(),
g_resources.getBaseDir(), g_resources.getBaseDir(),
g_resources.getBaseDir() + "../", g_resources.getBaseDir() + "../",
g_resources.getBaseDir() + "../share/" + g_app.getCompactName() + "/" }; g_resources.getBaseDir() + "../share/" + g_app.getCompactName() + "/" };
bool found = false; bool found = false;
for(const std::string& dir : possiblePaths) { for(const std::string& dir : possiblePaths) {
if(!PHYSFS_addToSearchPath(dir.c_str(), 0)) if(!PHYSFS_addToSearchPath(dir.c_str(), 0))
@ -296,11 +297,6 @@ std::string ResourceManager::getRealDir(const std::string& path)
return dir; return dir;
} }
std::string ResourceManager::getCurrentDir()
{
return g_platform.getCurrentDir();
}
std::string ResourceManager::getBaseDir() std::string ResourceManager::getBaseDir()
{ {
return PHYSFS_getBaseDir(); return PHYSFS_getBaseDir();

View File

@ -64,7 +64,6 @@ public:
std::string resolvePath(const std::string& path); std::string resolvePath(const std::string& path);
std::string getRealDir(const std::string& path); std::string getRealDir(const std::string& path);
std::string getCurrentDir();
std::string getBaseDir(); std::string getBaseDir();
std::string getUserDir(); std::string getUserDir();
std::string getWriteDir() { return m_writeDir; } std::string getWriteDir() { return m_writeDir; }

View File

@ -84,6 +84,7 @@ void Application::registerLuaFunctions()
g_lua.bindSingletonFunction("g_platform", "isProcessRunning", &Platform::isProcessRunning, &g_platform); g_lua.bindSingletonFunction("g_platform", "isProcessRunning", &Platform::isProcessRunning, &g_platform);
g_lua.bindSingletonFunction("g_platform", "copyFile", &Platform::copyFile, &g_platform); g_lua.bindSingletonFunction("g_platform", "copyFile", &Platform::copyFile, &g_platform);
g_lua.bindSingletonFunction("g_platform", "fileExists", &Platform::fileExists, &g_platform); g_lua.bindSingletonFunction("g_platform", "fileExists", &Platform::fileExists, &g_platform);
g_lua.bindSingletonFunction("g_platform", "removeFile", &Platform::removeFile, &g_platform);
g_lua.bindSingletonFunction("g_platform", "killProcess", &Platform::killProcess, &g_platform); g_lua.bindSingletonFunction("g_platform", "killProcess", &Platform::killProcess, &g_platform);
g_lua.bindSingletonFunction("g_platform", "getTempPath", &Platform::getTempPath, &g_platform); g_lua.bindSingletonFunction("g_platform", "getTempPath", &Platform::getTempPath, &g_platform);
g_lua.bindSingletonFunction("g_platform", "openUrl", &Platform::openUrl, &g_platform); g_lua.bindSingletonFunction("g_platform", "openUrl", &Platform::openUrl, &g_platform);

View File

@ -24,7 +24,6 @@
#define CONNECTION_H #define CONNECTION_H
#include "declarations.h" #include "declarations.h"
#include <boost/asio.hpp>
#include <framework/luaengine/luaobject.h> #include <framework/luaengine/luaobject.h>
#include <framework/core/timer.h> #include <framework/core/timer.h>
#include <framework/core/declarations.h> #include <framework/core/declarations.h>

View File

@ -25,6 +25,7 @@
#include <framework/global.h> #include <framework/global.h>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/system/error_code.hpp>
namespace asio = boost::asio; namespace asio = boost::asio;

View File

@ -37,7 +37,8 @@ public:
std::string getTempPath(); std::string getTempPath();
std::string getCurrentDir(); std::string getCurrentDir();
bool copyFile(std::string from, std::string to); bool copyFile(std::string from, std::string to);
bool fileExists(const std::string& file); bool fileExists(std::string file);
bool removeFile(std::string file);
void openUrl(std::string url); void openUrl(std::string url);
std::string getCPUName(); std::string getCPUName();
double getTotalSystemMemory(); double getTotalSystemMemory();

View File

@ -83,8 +83,10 @@ std::string Platform::getCurrentDir()
{ {
std::string res; std::string res;
char cwd[2048]; char cwd[2048];
if(getcwd(cwd, sizeof(cwd)) != NULL) if(getcwd(cwd, sizeof(cwd)) != NULL) {
res = cwd; res = cwd;
res += "/";
}
return res; return res;
} }
@ -93,12 +95,19 @@ bool Platform::copyFile(std::string from, std::string to)
return system(stdext::format("/bin/cp '%s' '%s'", from, to).c_str()) == 0; return system(stdext::format("/bin/cp '%s' '%s'", from, to).c_str()) == 0;
} }
bool Platform::fileExists(const std::string& file) bool Platform::fileExists(std::string file)
{ {
struct stat buffer; struct stat buffer;
return (stat(file.c_str(), &buffer) == 0); return (stat(file.c_str(), &buffer) == 0);
} }
bool Platform::removeFile(std::string file)
{
if(unlink(file.c_str()) == 0)
return true;
return false;
}
void Platform::openUrl(std::string url) void Platform::openUrl(std::string url)
{ {
if(url.find("http://") == std::string::npos) if(url.find("http://") == std::string::npos)

View File

@ -95,11 +95,13 @@ std::string Platform::getCurrentDir()
GetCurrentDirectoryW(MAX_PATH, path); GetCurrentDirectoryW(MAX_PATH, path);
ret = stdext::utf16_to_utf8(path); ret = stdext::utf16_to_utf8(path);
boost::replace_all(ret, "\\", "/"); boost::replace_all(ret, "\\", "/");
ret += "/";
return ret; return ret;
} }
bool Platform::fileExists(const std::string& file) bool Platform::fileExists(std::string file)
{ {
boost::replace_all(file, "/", "\\");
std::wstring wfile = stdext::utf8_to_utf16(file); std::wstring wfile = stdext::utf8_to_utf16(file);
DWORD dwAttrib = GetFileAttributesW(wfile.c_str()); DWORD dwAttrib = GetFileAttributesW(wfile.c_str());
return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
@ -114,6 +116,14 @@ bool Platform::copyFile(std::string from, std::string to)
return true; return true;
} }
bool Platform::removeFile(std::string file)
{
boost::replace_all(file, "/", "\\");
if(DeleteFileW(stdext::utf8_to_utf16(file).c_str()) == 0)
return false;
return true;
}
void Platform::openUrl(std::string url) void Platform::openUrl(std::string url)
{ {
if(url.find("http://") == std::string::npos) if(url.find("http://") == std::string::npos)

View File

@ -590,7 +590,11 @@ LRESULT WIN32Window::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
} }
case WM_ACTIVATE: { case WM_ACTIVATE: {
m_focused = !(wParam == WA_INACTIVE); m_focused = !(wParam == WA_INACTIVE);
if(!m_focused) releaseAllKeys();
break;
}
case WM_SETFOCUS:
case WM_KILLFOCUS: {
releaseAllKeys(); releaseAllKeys();
break; break;
} }

View File

@ -24,7 +24,6 @@
#define UITEXTEDIT_H #define UITEXTEDIT_H
#include "uiwidget.h" #include "uiwidget.h"
#include <boost/concept_check.hpp>
// @bindclass // @bindclass
class UITextEdit : public UIWidget class UITextEdit : public UIWidget