Draft: Lua UI - New layout engine, algorithm, and clean subtree skipping performance improvement
Closes #9178, Closes #9288, Closes #9291, Closes #9286, Closes #9287, Closes #9250
This supersedes !5387 (closed). Additionally, this resolves a large number of issues (Work items) that plague the current Lua UI and modders' experiences in some regard. It is also the large blocker to other Lua UI improvements and further UI dehardcoding.
First, the Lua UI code has been notoriously difficult for reviewers that aren't overly familiar with it to follow the logical flow without having to dive into it. Instead, this MR addresses this by separating layout code into a single layout engine file that does all arranging of widgets and complex layouts (Flex and Container for now until Grid comes about).
A README.md has been added to the components/lua_ui directory to give a brief, top-down explanation as to how the Lua UI algorithm works.
All widget classes have had any logic about their size and arrangement removed.
The separation logic started with @uramer, but I have since refactored the work. I have taken @OursCodeur's work on improving the UI efficiency and copy-pasted it in here with some slight modifications for the new layout engine - but his work has made this MR very quick (in performance and putting it together).
- Layouts are now done in two passes
- Children can no longer cause entire subtree re-traversals
- Children that need size distributions (grow/stretch) now have re-traversals restricted to their local node tree
Finally, unit tests have been added so that the Lua UI can be protected against regressions. The lack of such has plagued many past merges with possible mod regressions or unintended side effects from having the layout algorithm modified but no automated regression testing.
This is accomplished by separating the MyGUI geometry application from the actual layout arrangement finalization (as in, MyGUI doesn't have anything applied until the actual commit step in the algorithm is performed). This allows unit tests to inspect geometry without MyGUI ever being a part of it.
(I suppose it also opens the door to replacing MyGUI if that was ever desired, since it's somewhat decoupled now)
New Addition - ui.props(), ui.events(), ui.external()
These are important additions and are an opt-in performance improvement. With these, the engine can track dirty vs. clean layout subtrees and skip doing work entirely on clean trees or subtrees. This ultimately is what can bring this system to almost per-frame no-frame efficiency.
- I have read the CONTRIBUTING guidelines
- My code runs locally
- My code passes CI on my fork
What has been tested
- Inventory Extender (works, no regressions, and huge performance improvement on FPS)
- Stats Window Extender
To come
- Videos of cycling through UI layout test script
- Videos of UI mods that have been verified to work
Both of these things should add peace-of-mind that this is a necessary and positive MR - even if it's a beast
Videos
Better efficiency in high-update, per-frame scenarios. More information to come when this isn't a draft.
- I have read the CONTRIBUTING guidelines
- My code runs locally
- My code passes CI on my fork