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 s32 getRightPadding() { return 0; }
virtual f32 getNativeScale() const { return 1.0f; } virtual f32 getNativeScale() const { return 1.0f; }
virtual void setWindowMinimumSize(u32 width, u32 height) {} virtual void setWindowMinimumSize(u32 width, u32 height) {}
virtual void resetPaused() {}
virtual void resetUnpaused() {}
virtual bool isResizable() const { return false; } virtual bool isResizable() const { return false; }
//! Check if a driver type is supported by the engine. //! Check if a driver type is supported by the engine.
/** Even if true is returned the driver may not be available /** Even if true is returned the driver may not be available

View File

@ -36,6 +36,7 @@ namespace irr
} // end 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" 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 namespace irr
{ {
@ -121,6 +122,9 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param)
if (VideoDriver) if (VideoDriver)
createGUIAndScene(); 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 hasHardwareKeyboard() const;
virtual bool activateAccelerometer(float updateInterval); virtual bool activateAccelerometer(float updateInterval);
virtual bool deactivateAccelerometer(); virtual bool deactivateAccelerometer();
virtual bool isAccelerometerActive(); virtual bool isAccelerometerActive();
@ -148,6 +149,8 @@ namespace irr
virtual bool isGyroscopeActive(); virtual bool isGyroscopeActive();
virtual bool isGyroscopeAvailable(); virtual bool isGyroscopeAvailable();
virtual void resetPaused() { clearAllTouchIds(); }
//! Implementation of the linux cursor control //! Implementation of the linux cursor control
class CCursorControl : public gui::ICursorControl 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) MainLoop::MainLoop(unsigned parent_pid, bool download_assets)
: m_abort(false), m_request_abort(false), m_ticks_adjustment(0), : m_abort(false), m_request_abort(false), m_paused(false),
m_parent_pid(parent_pid) m_ticks_adjustment(0), m_parent_pid(parent_pid)
{ {
m_curr_time = 0; m_curr_time = 0;
m_prev_time = 0; m_prev_time = 0;
@ -121,45 +121,48 @@ float MainLoop::getLimitedDt()
m_prev_time = m_curr_time; m_prev_time = m_curr_time;
#ifdef IOS_STK #ifdef IOS_STK
IrrlichtDevice* dev = irr_driver->getDevice(); if (m_paused.load())
if (dev)
{ {
// 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 // opengl command from apple document, so we stop here
bool win_active = dev->isWindowActive(); if (music_manager)
bool has_focus = dev->isWindowFocused(); music_manager->pauseMusic();
bool first_out_focus = !has_focus; if (SFXManager::get())
while (!has_focus || !win_active) 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 (quit)
if (music_manager) return 1.0f/60.0f;
music_manager->pauseMusic(); dev->resetUnpaused();
if (SFXManager::get()) break;
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 (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 #endif
float dt = 0; float dt = 0;
@ -724,3 +727,24 @@ void MainLoop::renderGUI(int phase, int loop_index, int loop_size)
#endif #endif
} // renderGUI } // renderGUI
/* EOF */ /* 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_request_abort;
std::atomic_bool m_paused;
/** True if the frame rate should be throttled. */ /** True if the frame rate should be throttled. */
bool m_throttle_fps; bool m_throttle_fps;
@ -73,6 +75,10 @@ public:
m_ticks_adjustment.getData() += ticks; m_ticks_adjustment.getData() += ticks;
m_ticks_adjustment.unlock(); m_ticks_adjustment.unlock();
} }
// ------------------------------------------------------------------------
void setPaused(bool val) { m_paused.store(val); }
// ------------------------------------------------------------------------
bool isPaused() const { return m_paused.load(); }
}; // MainLoop }; // MainLoop
extern MainLoop* main_loop; extern MainLoop* main_loop;