mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-03 18:09:40 +00:00
Apply lua handlers for user input in the main thread in order to reduce latency.
This commit is contained in:
parent
47cbdcba15
commit
e56ee2c735
5 changed files with 27 additions and 13 deletions
|
@ -293,6 +293,10 @@ bool OMW::Engine::frame(float frametime)
|
|||
// Main menu opened? Then scripts are also paused.
|
||||
bool paused = mEnvironment.getWindowManager()->containsMode(MWGui::GM_MainMenu);
|
||||
|
||||
// Should be called after input manager update and before any change to the game world.
|
||||
// It applies to the game world queued changes from the previous frame.
|
||||
mLuaManager->synchronizedUpdate(paused, frametime);
|
||||
|
||||
// update game state
|
||||
{
|
||||
ScopedProfile<UserStatsType::State> profile(frameStart, frameNumber, *timer, *stats);
|
||||
|
@ -874,7 +878,6 @@ public:
|
|||
}
|
||||
else
|
||||
update();
|
||||
mEngine->mLuaManager->applyQueuedChanges();
|
||||
};
|
||||
|
||||
void join()
|
||||
|
|
|
@ -132,14 +132,6 @@ namespace MWLua
|
|||
mQueuedCallbacks.clear();
|
||||
|
||||
// Engine handlers in local scripts
|
||||
PlayerScripts* playerScripts = dynamic_cast<PlayerScripts*>(mPlayer.getRefData().getLuaScripts());
|
||||
if (playerScripts && !paused)
|
||||
{
|
||||
for (const auto& event : mInputEvents)
|
||||
playerScripts->processInputEvent(event);
|
||||
}
|
||||
mInputEvents.clear();
|
||||
|
||||
for (const LocalEngineEvent& e : mLocalEngineEvents)
|
||||
{
|
||||
LObject obj(e.mDest, objectRegistry);
|
||||
|
@ -180,8 +172,21 @@ namespace MWLua
|
|||
mGlobalScripts.update(dt);
|
||||
}
|
||||
|
||||
void LuaManager::applyQueuedChanges()
|
||||
void LuaManager::synchronizedUpdate(bool paused, float dt)
|
||||
{
|
||||
if (mPlayer.isEmpty())
|
||||
return; // The game is not started yet.
|
||||
|
||||
// We apply input events in `synchronizedUpdate` rather than in `update` in order to reduce input latency.
|
||||
PlayerScripts* playerScripts = dynamic_cast<PlayerScripts*>(mPlayer.getRefData().getLuaScripts());
|
||||
if (playerScripts && !paused)
|
||||
{
|
||||
for (const auto& event : mInputEvents)
|
||||
playerScripts->processInputEvent(event);
|
||||
playerScripts->inputUpdate(dt);
|
||||
}
|
||||
mInputEvents.clear();
|
||||
|
||||
MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager();
|
||||
for (const std::string& message : mUIMessages)
|
||||
windowManager->messageBox(message);
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace MWLua
|
|||
void update(bool paused, float dt);
|
||||
|
||||
// Called by engine.cpp from the main thread. Can use scene graph.
|
||||
void applyQueuedChanges();
|
||||
void synchronizedUpdate(bool paused, float dt);
|
||||
|
||||
// Available everywhere through the MWBase::LuaManager interface.
|
||||
// LuaManager queues these events and propagates to scripts on the next `update` call.
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace MWLua
|
|||
{
|
||||
registerEngineHandlers({&mKeyPressHandlers, &mKeyReleaseHandlers,
|
||||
&mControllerButtonPressHandlers, &mControllerButtonReleaseHandlers,
|
||||
&mActionHandlers});
|
||||
&mActionHandlers, &mInputUpdateHandlers});
|
||||
}
|
||||
|
||||
void processInputEvent(const MWBase::LuaManager::InputEvent& event)
|
||||
|
@ -43,12 +43,15 @@ namespace MWLua
|
|||
}
|
||||
}
|
||||
|
||||
void inputUpdate(float dt) { callEngineHandlers(mInputUpdateHandlers, dt); }
|
||||
|
||||
private:
|
||||
EngineHandlerList mKeyPressHandlers{"onKeyPress"};
|
||||
EngineHandlerList mKeyReleaseHandlers{"onKeyRelease"};
|
||||
EngineHandlerList mControllerButtonPressHandlers{"onControllerButtonPress"};
|
||||
EngineHandlerList mControllerButtonReleaseHandlers{"onControllerButtonRelease"};
|
||||
EngineHandlerList mActionHandlers{"onInputAction"};
|
||||
EngineHandlerList mInputUpdateHandlers{"onInputUpdate"};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ Engine handler is a function defined by a script, that can be called by the engi
|
|||
| | | `be assigned to a script in openmw-cs (not yet implemented)`. |
|
||||
| | | ``onInterfaceOverride`` can be called before ``onInit``. |
|
||||
+----------------------------------+----------------------------------------------------------------------+
|
||||
| onUpdate(dt) | | Called every frame if game not paused. `dt` is the time |
|
||||
| onUpdate(dt) | | Called every frame if the game is not paused. `dt` is the time |
|
||||
| | | from the last update in seconds. |
|
||||
+----------------------------------+----------------------------------------------------------------------+
|
||||
| onSave() -> savedData | | Called when the game is saving. May be called in inactive |
|
||||
|
@ -44,6 +44,9 @@ Engine handler is a function defined by a script, that can be called by the engi
|
|||
+----------------------------------+----------------------------------------------------------------------+
|
||||
| **Only for local scripts attached to a player** |
|
||||
+----------------------------------+----------------------------------------------------------------------+
|
||||
| onInputUpdate(dt) | | Called every frame (if the game is not paused) right after |
|
||||
| | | processing user input. Use it only for latency-critical stuff. |
|
||||
+----------------------------------+----------------------------------------------------------------------+
|
||||
| onKeyPress(key) | | `Key <openmw_input.html##(KeyboardEvent)>`_ is pressed. |
|
||||
| | | Usage example: ``if key.symbol == 'z' and key.withShift then ...`` |
|
||||
+----------------------------------+----------------------------------------------------------------------+
|
||||
|
|
Loading…
Reference in a new issue