mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-26 14:56:39 +00:00 
			
		
		
		
	Reuse input engine handlers in menu scripts
This commit is contained in:
		
							parent
							
								
									d1d430b431
								
							
						
					
					
						commit
						2107bbc01d
					
				
					 7 changed files with 114 additions and 56 deletions
				
			
		|  | @ -64,7 +64,7 @@ add_openmw_dir (mwlua | |||
|     context menuscripts globalscripts localscripts playerscripts luabindings objectbindings cellbindings | ||||
|     mwscriptbindings camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings | ||||
|     postprocessingbindings stats debugbindings corebindings worldbindings worker magicbindings factionbindings | ||||
|     classbindings itemdata | ||||
|     classbindings itemdata inputprocessor | ||||
|     types/types types/door types/item types/actor types/container types/lockable types/weapon types/npc | ||||
|     types/creature types/player types/activator types/book types/lockpick types/probe types/apparatus | ||||
|     types/potion types/ingredient types/misc types/repair types/armor types/light types/static | ||||
|  |  | |||
							
								
								
									
										73
									
								
								apps/openmw/mwlua/inputprocessor.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								apps/openmw/mwlua/inputprocessor.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,73 @@ | |||
| #ifndef MWLUA_INPUTPROCESSOR_H | ||||
| #define MWLUA_INPUTPROCESSOR_H | ||||
| 
 | ||||
| #include <SDL_events.h> | ||||
| 
 | ||||
| #include <components/lua/luastate.hpp> | ||||
| #include <components/lua/scriptscontainer.hpp> | ||||
| #include <components/sdlutil/events.hpp> | ||||
| 
 | ||||
| #include "../mwbase/luamanager.hpp" | ||||
| 
 | ||||
| namespace MWLua | ||||
| { | ||||
|     class InputProcessor | ||||
|     { | ||||
|     public: | ||||
|         InputProcessor(LuaUtil::ScriptsContainer* scriptsContainer) | ||||
|             : mScriptsContainer(scriptsContainer) | ||||
|         { | ||||
|             mScriptsContainer->registerEngineHandlers({ &mKeyPressHandlers, &mKeyReleaseHandlers, | ||||
|                 &mControllerButtonPressHandlers, &mControllerButtonReleaseHandlers, &mActionHandlers, &mTouchpadPressed, | ||||
|                 &mTouchpadReleased, &mTouchpadMoved }); | ||||
|         } | ||||
| 
 | ||||
|         void processInputEvent(const MWBase::LuaManager::InputEvent& event) | ||||
|         { | ||||
|             using InputEvent = MWBase::LuaManager::InputEvent; | ||||
|             switch (event.mType) | ||||
|             { | ||||
|                 case InputEvent::KeyPressed: | ||||
|                     mScriptsContainer->callEngineHandlers(mKeyPressHandlers, std::get<SDL_Keysym>(event.mValue)); | ||||
|                     break; | ||||
|                 case InputEvent::KeyReleased: | ||||
|                     mScriptsContainer->callEngineHandlers(mKeyReleaseHandlers, std::get<SDL_Keysym>(event.mValue)); | ||||
|                     break; | ||||
|                 case InputEvent::ControllerPressed: | ||||
|                     mScriptsContainer->callEngineHandlers(mControllerButtonPressHandlers, std::get<int>(event.mValue)); | ||||
|                     break; | ||||
|                 case InputEvent::ControllerReleased: | ||||
|                     mScriptsContainer->callEngineHandlers( | ||||
|                         mControllerButtonReleaseHandlers, std::get<int>(event.mValue)); | ||||
|                     break; | ||||
|                 case InputEvent::Action: | ||||
|                     mScriptsContainer->callEngineHandlers(mActionHandlers, std::get<int>(event.mValue)); | ||||
|                     break; | ||||
|                 case InputEvent::TouchPressed: | ||||
|                     mScriptsContainer->callEngineHandlers( | ||||
|                         mTouchpadPressed, std::get<SDLUtil::TouchEvent>(event.mValue)); | ||||
|                     break; | ||||
|                 case InputEvent::TouchReleased: | ||||
|                     mScriptsContainer->callEngineHandlers( | ||||
|                         mTouchpadReleased, std::get<SDLUtil::TouchEvent>(event.mValue)); | ||||
|                     break; | ||||
|                 case InputEvent::TouchMoved: | ||||
|                     mScriptsContainer->callEngineHandlers(mTouchpadMoved, std::get<SDLUtil::TouchEvent>(event.mValue)); | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|     private: | ||||
|         LuaUtil::ScriptsContainer* mScriptsContainer; | ||||
|         LuaUtil::ScriptsContainer::EngineHandlerList mKeyPressHandlers{ "onKeyPress" }; | ||||
|         LuaUtil::ScriptsContainer::EngineHandlerList mKeyReleaseHandlers{ "onKeyRelease" }; | ||||
|         LuaUtil::ScriptsContainer::EngineHandlerList mControllerButtonPressHandlers{ "onControllerButtonPress" }; | ||||
|         LuaUtil::ScriptsContainer::EngineHandlerList mControllerButtonReleaseHandlers{ "onControllerButtonRelease" }; | ||||
|         LuaUtil::ScriptsContainer::EngineHandlerList mActionHandlers{ "onInputAction" }; | ||||
|         LuaUtil::ScriptsContainer::EngineHandlerList mTouchpadPressed{ "onTouchPress" }; | ||||
|         LuaUtil::ScriptsContainer::EngineHandlerList mTouchpadReleased{ "onTouchRelease" }; | ||||
|         LuaUtil::ScriptsContainer::EngineHandlerList mTouchpadMoved{ "onTouchMove" }; | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| #endif // MWLUA_INPUTPROCESSOR_H
 | ||||
|  | @ -229,7 +229,9 @@ namespace MWLua | |||
|         PlayerScripts* playerScripts | ||||
|             = mPlayer.isEmpty() ? nullptr : dynamic_cast<PlayerScripts*>(mPlayer.getRefData().getLuaScripts()); | ||||
|         MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager(); | ||||
|         // TODO: handle main menu input events
 | ||||
| 
 | ||||
|         for (const auto& event : mInputEvents) | ||||
|             mMenuScripts.processInputEvent(event); | ||||
|         if (playerScripts && !windowManager->containsMode(MWGui::GM_MainMenu)) | ||||
|         { | ||||
|             for (const auto& event : mInputEvents) | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ | |||
| #include "../mwbase/luamanager.hpp" | ||||
| 
 | ||||
| #include "context.hpp" | ||||
| #include "inputprocessor.hpp" | ||||
| 
 | ||||
| namespace MWLua | ||||
| { | ||||
|  | @ -21,10 +22,16 @@ namespace MWLua | |||
|     public: | ||||
|         MenuScripts(LuaUtil::LuaState* lua) | ||||
|             : LuaUtil::ScriptsContainer(lua, "Menu") | ||||
|             , mInputProcessor(this) | ||||
|         { | ||||
|             registerEngineHandlers({ &mStateChanged, &mConsoleCommandHandlers, &mUiModeChanged }); | ||||
|         } | ||||
| 
 | ||||
|         void processInputEvent(const MWBase::LuaManager::InputEvent& event) | ||||
|         { | ||||
|             mInputProcessor.processInputEvent(event); | ||||
|         } | ||||
| 
 | ||||
|         void stateChanged() { callEngineHandlers(mStateChanged); } | ||||
| 
 | ||||
|         bool consoleCommand(const std::string& consoleMode, const std::string& command) | ||||
|  | @ -36,6 +43,7 @@ namespace MWLua | |||
|         void uiModeChanged() { callEngineHandlers(mUiModeChanged); } | ||||
| 
 | ||||
|     private: | ||||
|         MWLua::InputProcessor mInputProcessor; | ||||
|         EngineHandlerList mStateChanged{ "onStateChanged" }; | ||||
|         EngineHandlerList mConsoleCommandHandlers{ "onConsoleCommand" }; | ||||
|         EngineHandlerList mUiModeChanged{ "_onUiModeChanged" }; | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ | |||
| 
 | ||||
| #include "../mwbase/luamanager.hpp" | ||||
| 
 | ||||
| #include "inputprocessor.hpp" | ||||
| #include "localscripts.hpp" | ||||
| 
 | ||||
| namespace MWLua | ||||
|  | @ -17,42 +18,14 @@ namespace MWLua | |||
|     public: | ||||
|         PlayerScripts(LuaUtil::LuaState* lua, const LObject& obj) | ||||
|             : LocalScripts(lua, obj) | ||||
|             , mInputProcessor(this) | ||||
|         { | ||||
|             registerEngineHandlers({ &mConsoleCommandHandlers, &mKeyPressHandlers, &mKeyReleaseHandlers, | ||||
|                 &mControllerButtonPressHandlers, &mControllerButtonReleaseHandlers, &mActionHandlers, &mOnFrameHandlers, | ||||
|                 &mTouchpadPressed, &mTouchpadReleased, &mTouchpadMoved, &mQuestUpdate, &mUiModeChanged }); | ||||
|             registerEngineHandlers({ &mConsoleCommandHandlers, &mOnFrameHandlers, &mQuestUpdate, &mUiModeChanged }); | ||||
|         } | ||||
| 
 | ||||
|         void processInputEvent(const MWBase::LuaManager::InputEvent& event) | ||||
|         { | ||||
|             using InputEvent = MWBase::LuaManager::InputEvent; | ||||
|             switch (event.mType) | ||||
|             { | ||||
|                 case InputEvent::KeyPressed: | ||||
|                     callEngineHandlers(mKeyPressHandlers, std::get<SDL_Keysym>(event.mValue)); | ||||
|                     break; | ||||
|                 case InputEvent::KeyReleased: | ||||
|                     callEngineHandlers(mKeyReleaseHandlers, std::get<SDL_Keysym>(event.mValue)); | ||||
|                     break; | ||||
|                 case InputEvent::ControllerPressed: | ||||
|                     callEngineHandlers(mControllerButtonPressHandlers, std::get<int>(event.mValue)); | ||||
|                     break; | ||||
|                 case InputEvent::ControllerReleased: | ||||
|                     callEngineHandlers(mControllerButtonReleaseHandlers, std::get<int>(event.mValue)); | ||||
|                     break; | ||||
|                 case InputEvent::Action: | ||||
|                     callEngineHandlers(mActionHandlers, std::get<int>(event.mValue)); | ||||
|                     break; | ||||
|                 case InputEvent::TouchPressed: | ||||
|                     callEngineHandlers(mTouchpadPressed, std::get<SDLUtil::TouchEvent>(event.mValue)); | ||||
|                     break; | ||||
|                 case InputEvent::TouchReleased: | ||||
|                     callEngineHandlers(mTouchpadReleased, std::get<SDLUtil::TouchEvent>(event.mValue)); | ||||
|                     break; | ||||
|                 case InputEvent::TouchMoved: | ||||
|                     callEngineHandlers(mTouchpadMoved, std::get<SDLUtil::TouchEvent>(event.mValue)); | ||||
|                     break; | ||||
|             } | ||||
|             mInputProcessor.processInputEvent(event); | ||||
|         } | ||||
| 
 | ||||
|         void onFrame(float dt) { callEngineHandlers(mOnFrameHandlers, dt); } | ||||
|  | @ -75,16 +48,9 @@ namespace MWLua | |||
|         } | ||||
| 
 | ||||
|     private: | ||||
|         InputProcessor mInputProcessor; | ||||
|         EngineHandlerList mConsoleCommandHandlers{ "onConsoleCommand" }; | ||||
|         EngineHandlerList mKeyPressHandlers{ "onKeyPress" }; | ||||
|         EngineHandlerList mKeyReleaseHandlers{ "onKeyRelease" }; | ||||
|         EngineHandlerList mControllerButtonPressHandlers{ "onControllerButtonPress" }; | ||||
|         EngineHandlerList mControllerButtonReleaseHandlers{ "onControllerButtonRelease" }; | ||||
|         EngineHandlerList mActionHandlers{ "onInputAction" }; | ||||
|         EngineHandlerList mOnFrameHandlers{ "onFrame" }; | ||||
|         EngineHandlerList mTouchpadPressed{ "onTouchPress" }; | ||||
|         EngineHandlerList mTouchpadReleased{ "onTouchRelease" }; | ||||
|         EngineHandlerList mTouchpadMoved{ "onTouchMove" }; | ||||
|         EngineHandlerList mQuestUpdate{ "onQuestUpdate" }; | ||||
|         EngineHandlerList mUiModeChanged{ "_onUiModeChanged" }; | ||||
|     }; | ||||
|  |  | |||
|  | @ -157,7 +157,8 @@ namespace LuaUtil | |||
|         void collectStats(std::vector<ScriptStats>& stats) const; | ||||
|         static int64_t getInstanceCount() { return sInstanceCount; } | ||||
| 
 | ||||
|     protected: | ||||
|     public: // TODO: public to be available to MWLua::InputProcessor. Consider other ways of reusing engine handlers
 | ||||
|             // between containers
 | ||||
|         struct Handler | ||||
|         { | ||||
|             int mScriptId; | ||||
|  | @ -198,6 +199,7 @@ namespace LuaUtil | |||
|         // a public function (see how ScriptsContainer::update is implemented) that calls `callEngineHandlers`.
 | ||||
|         void registerEngineHandlers(std::initializer_list<EngineHandlerList*> handlers); | ||||
| 
 | ||||
|     protected: | ||||
|         const std::string mNamePrefix; | ||||
|         LuaUtil::LuaState& mLua; | ||||
| 
 | ||||
|  |  | |||
|  | @ -80,23 +80,16 @@ Engine handler is a function defined by a script, that can be called by the engi | |||
|       | Similarly to onActivated, the item has already been removed | ||||
|       | from the actor's inventory, and the count was set to zero. | ||||
| 
 | ||||
| **Only for local scripts attached to a player** | ||||
| **Only menu scripts and local scripts attached to a player** | ||||
| 
 | ||||
| .. list-table:: | ||||
|   :widths: 20 80 | ||||
| 
 | ||||
|   * - onFrame(dt) | ||||
|     - | Called every frame (even if the game is paused) right after | ||||
|       | processing user input. Use it only for latency-critical stuff | ||||
|       | and for UI that should work on pause. | ||||
|       | `dt` is simulation time delta (0 when on pause). | ||||
|   * - onKeyPress(key) | ||||
| * - onKeyPress(key) | ||||
|     - | `Key <openmw_input.html##(KeyboardEvent)>`_ is pressed. | ||||
|       | Usage example: | ||||
|       | ``if key.symbol == 'z' and key.withShift then ...`` | ||||
|   * - onQuestUpdate(questId, stage) | ||||
|     - | Called when a quest is updated. | ||||
|   * - onKeyRelease(key) | ||||
|  * - onKeyRelease(key) | ||||
|     - | `Key <openmw_input.html##(KeyboardEvent)>`_ is released. | ||||
|       | Usage example: | ||||
|       | ``if key.symbol == 'z' and key.withShift then ...`` | ||||
|  | @ -127,6 +120,24 @@ Engine handler is a function defined by a script, that can be called by the engi | |||
|     - | User entered `command` in in-game console. Called if either | ||||
|       | `mode` is not default or `command` starts with prefix `lua`. | ||||
| 
 | ||||
| **Only for local scripts attached to a player** | ||||
| 
 | ||||
| .. list-table:: | ||||
|   :widths: 20 80 | ||||
|   * - onFrame(dt) | ||||
|     - | Called every frame (even if the game is paused) right after | ||||
|       | processing user input. Use it only for latency-critical stuff | ||||
|       | and for UI that should work on pause. | ||||
|       | `dt` is simulation time delta (0 when on pause). | ||||
|   * - onKeyPress(key) | ||||
|     - | `Key <openmw_input.html##(KeyboardEvent)>`_ is pressed. | ||||
|       | Usage example: | ||||
|       | ``if key.symbol == 'z' and key.withShift then ...`` | ||||
|   * - onQuestUpdate(questId, stage) | ||||
|     - | Called when a quest is updated. | ||||
|   | ||||
|   | ||||
| 
 | ||||
| **Only for menu scripts** | ||||
| 
 | ||||
| .. list-table:: | ||||
|  | @ -134,7 +145,3 @@ Engine handler is a function defined by a script, that can be called by the engi | |||
|   * - onStateChanged() | ||||
|     - | Called whenever the current game changes | ||||
|       | (i. e. the result of `getState <openmw_menu.html##(getState)>`_ changes) | ||||
|   * - | onConsoleCommand( | ||||
|       |     mode, command, selectedObject) | ||||
|     - | User entered `command` in in-game console. Called if either | ||||
|       | `mode` is not default or `command` starts with prefix `lua`. | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue