Map config values (or just map option groups)
sisby-folk opened this issue ยท 7 comments
I'm working on McQoy, which automatically generates config GUIs for mods that use an existing pure-java config library.
Primitives, sections, and lists all work, but I noticed there's nothing in YACL's API that can handle Map<String, T>, which I use very often in my mods for configuration over arbitrary items/tags/screens/biomes/etc.
To work around this, I'm planning to attempt to create something custom, but it'll end up using a lot of internal yacl API and might realistically be quite brittle.
With the exceedingly nice way that list groups are already designed, I reckon you'd know exactly what you're doing here - first-class support for map groups would be greatly helpful!
Thank you very much for your effort with this; one question, is there a reason you have enforced string keys? I recall you saying something in Discord, was it about your specific serialisation? To save myself time discovering why this doesn't work?
Many serialised formats only support string keys, or at least stringified keys - now that I think of it, you could definitely get away with non-string keys: just assume your non-you consumers will stringify them if they need to - "true" = "banana"
Also we didn't generify those option wrappers nearly as much as we could by extracting the key/value getting/setting.
I made an ugly attempt at this - it looks okay, but it sadly doesn't work (no value sticks). Plus because i'm not implementing ListOption i'm locked out of having a + new entry icon.
Code for that is here. Wrapping options into options of different types is very complicated and i'm almost certainly doing it wrong. Might see if i can make something that's more listlike and turn it into a map much closer to the api boundary instead (ListOptionImpl is final, which makes this a pain)
I'm glad you got it working, I'll look at merging that into the main mod at some point, if that's okay with you?
Okay, i've cleaned up the unnecessary code, here's the breakdown:
- EntryController accepts
Option<Map.Entry<String, T>>and delegates it to an arbitraryController<String>andController<T> - MapKeyOption is a
Option<String>that wraps aOption<Map.Entry<String, T>>for this purpose. This is done sloppily - the binding and state manager probably don't work, but we only really work with requestset and pendingvalue so we skipped it. - MapValueOption is a
Option<T>that wraps aOption<Map.Entry<String, T>>for this purpose. Same warnings apply. - EntryControllerElement is a widget that combines the two controller widgets. It delegates the important methods to calling both widgets methods. This is definitely incomplete, and should override more methods for delegation.
Then you just make a ListOption for Map.Entry<String, T>, pass in a binding that pulls the entries from a map and puts them back in, and pass in a string controller and a value controller. Simple.
Good luck!
Consider it yours free of license, co-author me in the commits sisby-folk <sleepingdragoninn(at)gmail.com> (it'd help me a lot if it was in YACL instead of in my translator) - It's quite likely that both 1) there's redundant code in my implementation and 2) there's incorrect non-critical code in my implementation. You know the architecture better, you'll know what's what.


