Redo of D2805 (both the initial diff & the reac-ted version).
This makes it possible for JS to create & delete GUI Objects, instead of having to rely entirely on XML definitions.
Advantages:
- It's easier to do dynamic controls, e.g. the gamesetup XML currently contains N buttons, M dropdowns, P sliders, but with this code the relevant controls could just set up their own elements instead of having to hope it's there.
- Likewise, makes things like including a whole 'JS component' doable by just creating a class & letting it init its own XML (see map browser for a likely use case).
This diff in particular has one trick up its sleeve: it changes the GUI to parse not XML but ParamNode. This makes it possible, with some changes, to create components from JS objects instead of inline XML, which is much nicer to work with in javascript and was the biggest drawback of D2805.
The main drawback is performance - we need to setup the ParamNode and then read that instead of reading XML directly, but I suspect that's irrelevant.allows the JS code to use objects to create components instead of inline XML, The advantages are that we could also define GUI objects in other formats if/once paramNode is extendedwhich is much nicer to work with in javascript and was the biggest drawback of D2805.
As a side effect, this makes it possible to load scripts from JS.
However, this implies a few changes aside from the GUI changes that will likely go in separate diffs once I've cleaned stuff out:
- Making ParamNode handle multiple objects with the same name.
- Currently done by storing an indexTo implement this, but this doesn't quite replicate XML fully since order isn't quite the sama JS->XMB function is implemented (somewhat WIP for now).
- Making ParamNode use interned string (possibly as an option) so that string-comparisons are reduced.
- Allowing creation of ParamNode from JS::HandleValue (and therefore JSON)To make `deleteChild` nice, `ScriptInterface::FromJSVal<IGUIObject*>` is implemented. To make that safe, it checks that the argument being passed is indeed a proxy object. This changes the GUI proxy objects to all have the same class definition which seemed fine for now.
TODO:
- Ideally, cleaning out the IGUIObject proxies so we can pass them as arguments instead of having to find the name, which is un-necessarily slow and cumbersomeWould be rather nice to be able to duplicate child objects.
- Finish the transition entirely in the GUI- Would be thrifty to parse XMB to JS, to have both-ways conversion.