Add pause main loop for mobile STK

This commit is contained in:
Benau 2020-06-13 15:38:22 +08:00
parent ae3497a31d
commit 84cf6b1ea0
5 changed files with 73 additions and 34 deletions

View File

@ -320,6 +320,8 @@ namespace irr
virtual s32 getRightPadding() { return 0; }
virtual f32 getNativeScale() const { return 1.0f; }
virtual void setWindowMinimumSize(u32 width, u32 height) {}
virtual void resetPaused() {}
virtual void resetUnpaused() {}
virtual bool isResizable() const { return false; }
//! Check if a driver type is supported by the engine.
/** Even if true is returned the driver may not be available

View File

@ -36,6 +36,7 @@ namespace irr
} // end namespace irr
extern "C" void init_objc(SDL_SysWMinfo* info, float* ns, float* top, float* bottom, float* left, float* right);
extern "C" int handle_app_event(void* userdata, SDL_Event* event);
namespace irr
{
@ -121,6 +122,9 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param)
if (VideoDriver)
createGUIAndScene();
#ifdef MOBILE_STK
SDL_SetEventFilter(handle_app_event, NULL);
#endif
}

View File

@ -139,6 +139,7 @@ namespace irr
virtual bool hasHardwareKeyboard() const;
virtual bool activateAccelerometer(float updateInterval);
virtual bool deactivateAccelerometer();
virtual bool isAccelerometerActive();
@ -148,6 +149,8 @@ namespace irr
virtual bool isGyroscopeActive();
virtual bool isGyroscopeAvailable();
virtual void resetPaused() { clearAllTouchIds(); }
//! Implementation of the linux cursor control
class CCursorControl : public gui::ICursorControl
{

View File

@ -78,8 +78,8 @@ LRESULT CALLBACK separateProcessProc(_In_ HWND hwnd, _In_ UINT uMsg,
// ----------------------------------------------------------------------------
MainLoop::MainLoop(unsigned parent_pid, bool download_assets)
: m_abort(false), m_request_abort(false), m_ticks_adjustment(0),
m_parent_pid(parent_pid)
: m_abort(false), m_request_abort(false), m_paused(false),
m_ticks_adjustment(0), m_parent_pid(parent_pid)
{
m_curr_time = 0;
m_prev_time = 0;
@ -121,45 +121,48 @@ float MainLoop::getLimitedDt()
m_prev_time = m_curr_time;
#ifdef IOS_STK
IrrlichtDevice* dev = irr_driver->getDevice();
if (dev)
if (m_paused.load())
{
// When ios apps entering background it should not run any
// When iOS apps entering background it should not run any
// opengl command from apple document, so we stop here
bool win_active = dev->isWindowActive();
bool has_focus = dev->isWindowFocused();
bool first_out_focus = !has_focus;
while (!has_focus || !win_active)
if (music_manager)
music_manager->pauseMusic();
if (SFXManager::get())
SFXManager::get()->pauseAll();
PlayerManager::get()->save();
if (addons_manager->hasDownloadedIcons())
addons_manager->saveInstalled();
Online::RequestManager::get()->setPaused(true);
IrrlichtDevice* dev = irr_driver->getDevice();
if (dev)
dev->resetPaused();
while (true)
{
if (first_out_focus)
// iOS will pause this thread completely when fully in background
IrrlichtDevice* dev = irr_driver->getDevice();
bool quit = false;
if (dev)
quit = !dev->run();
if (quit || !m_paused.load())
{
first_out_focus = false;
if (music_manager)
music_manager->pauseMusic();
if (SFXManager::get())
SFXManager::get()->pauseAll();
PlayerManager::get()->save();
if (addons_manager->hasDownloadedIcons())
addons_manager->saveInstalled();
Online::RequestManager::get()->setPaused(true);
}
dev->run();
win_active = dev->isWindowActive();
has_focus = dev->isWindowFocused();
if (has_focus && win_active)
{
if (music_manager)
music_manager->resumeMusic();
if (SFXManager::get())
SFXManager::get()->resumeAll();
// Improve rubber banding effects of rewinders when going
// back to phone, because the smooth timer is paused
if (World::getWorld() && RewindManager::isEnabled())
RewindManager::get()->resetSmoothNetworkBody();
Online::RequestManager::get()->setPaused(false);
if (quit)
return 1.0f/60.0f;
dev->resetUnpaused();
break;
}
}
if (music_manager)
music_manager->resumeMusic();
if (SFXManager::get())
SFXManager::get()->resumeAll();
// Improve rubber banding effects of rewinders when going
// back to phone, because the smooth timer is paused
if (World::getWorld() && RewindManager::isEnabled())
RewindManager::get()->resetSmoothNetworkBody();
Online::RequestManager::get()->setPaused(false);
}
#endif
float dt = 0;
@ -724,3 +727,24 @@ void MainLoop::renderGUI(int phase, int loop_index, int loop_size)
#endif
} // renderGUI
/* EOF */
#if !defined(SERVER_ONLY) && defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
#include "SDL_events.h"
extern "C" int handle_app_event(void* userdata, SDL_Event* event)
{
if (!main_loop)
return 1;
switch (event->type)
{
case SDL_APP_WILLENTERBACKGROUND:
main_loop->setPaused(true);
break;
case SDL_APP_DIDENTERFOREGROUND:
main_loop->setPaused(false);
break;
default:
break;
}
return 1;
}
#endif

View File

@ -34,6 +34,8 @@ private:
std::atomic_bool m_request_abort;
std::atomic_bool m_paused;
/** True if the frame rate should be throttled. */
bool m_throttle_fps;
@ -73,6 +75,10 @@ public:
m_ticks_adjustment.getData() += ticks;
m_ticks_adjustment.unlock();
}
// ------------------------------------------------------------------------
void setPaused(bool val) { m_paused.store(val); }
// ------------------------------------------------------------------------
bool isPaused() const { return m_paused.load(); }
}; // MainLoop
extern MainLoop* main_loop;