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.

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.

Edited by Cole Green

Merge request reports

Loading
Loading