beyond-all-reason / beyond-all-reason/RecoilEngine
Input system needs a general refactor
- Dominant language
- C++
- Stars
- 679
- Forks
- 290
- Avg merge
- 3d 1h
- Merged PRs (30d)
- 38
Description
The engine input system has a lot of hardcoded actions, some shortcomings, and needs a bit of architecture refactoring.
This probably needs to be fixed in several steps, in a not breaking way, and providing backwards compatible paths when needed.
The idea with this issue is to provide a central place where to give a high level overview of problems and proposed plan. I'll be documenting problems and linking other related issues here, but feel free to comment anything you think is not currently taken into account.
You can check issues relative to input through the [input label](https://github.com/beyond-all-reason/spring/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22area%3A%20Input%22).
### Shortcomings
- Lots of hardcoded engine input processing
- [Mouse can't be bound to actions](https://github.com/beyond-all-reason/spring/issues/2059)
- [Single modifier presses not properly handled](https://github.com/beyond-all-reason/spring/issues/1071)
- Keycode/scancode separation makes some combinations tricky
- Lack of some mechanisms needed for converting engine input behaviors to (re)bindable actions
- [Keychains don't handle mouse release](https://github.com/beyond-all-reason/spring/issues/2169)
- Other input mechanisms not considered (like gamepad)
- Unbinding [needs improving](https://github.com/beyond-all-reason/RecoilEngine/pull/562)
- Limitations on [integrating engine and game action handling](https://github.com/beyond-all-reason/RecoilEngine/issues/2246)
- [A whole category of keycodes are currently unsupported](https://github.com/beyond-all-reason/RecoilEngine/issues/2611) due to SDL1 keycode compat layer.
- [Game and engine action systems should be integrated](https://github.com/beyond-all-reason/RecoilEngine/issues/2246)
### Architecture issues
- Mismatch between key and mouse input organization
- Mouse goes through MouseHandler, but keyboard goes through gameController
- Lack of a central module for press/release processing
- Right now mostly divided between Game.cpp and MouseHandler.cpp
- [Limited press/release locking/owning mechanism](https://github.com/beyond-all-reason/spring/issues/2168).
- LuaInputReceiver just forwards Mouse/Key/Press/Release/IsAbove/GetTooltip/Draw to eventHandler ???
### Engine actions details
- CGameInfo doing it's own KeyPressed handling
- can probably be moved to GameInfoCloseActionExecutor
- CGuiHandler::ProcessBuildActions can go into unsyncedactions
### Input receivers order
General view of current ordering and new ordering
#### After
With https://github.com/beyond-all-reason/spring/pull/2130 already applied:
```
KeyPress (GameInputReceiver):
rmlgui
gametextinput
luainputreceiver (actually eventHandler)
GetReceivers
actions:
lastActionList
luaui->GotChatMsg (also from lastActionList)
luaMenu->GotChatMsg (also from lastActionList)
MousePress (starts in MouseHandler.cpp):
rmlgui
activereceiver
inmapdrawer
luaInputReceiver (actually eventHandler)
GetReceivers <-- (GameInputReceiver)
actions:
lastActionList
luaui->GotChatMsg (also from lastActionList)
luaMenu->GotChatMsg (also from lastActionList)
guihandler->MousePress <-- is this here with the PR? double check
KeyRelease -> to be described here
MouseRelease -> to be described here
```
#### Before
Before starting any new work, like mouse binding etc, as of 2025.03.X
```
KeyPress (all in Game.cpp):
rmlgui
gametextinput
luainputreceiver
GetReceivers
actions:
lastActionList
luaui->GotChatMsg (also from lastActionList)
luaMenu->GotChatMsg (also from lastActionList)
MousePress (starts in MouseHandler.cpp):
rmlgui
activereceiver
inmapdrawer
middle: <-- historic, this 'middlebutton' part just here so minimap has higher priority
luaInputReceiver->MousePress
minimap->MousePress
luaInputReceiver->MousePress
GetReceivers
guihandler->MousePress
KeyRelease
rmlgui
gametextinput
luaInputReceiver
GetReceivers
lastActionList
MouseRelease
inMapDrawer
rmlgui
activeReceiver
hardcoded SDL_BUTTON_MIDDLE ToggleMiddleClickScroll
return if gu->fpsMode
return if no guihandler
hardcoded unchorded SDL_BUTTON_LEFT code
```
Contributor guide
Assessment
This issue has not been assessed yet.