AceConfig3 Implementation Details
From WowAce Wiki
AceConfig3 » AceConfig3 Implementation Details
General AceConfig implementation guidelines
- Don't worry about CPU at all. We are taking about user-initiated actions. Anything faster than a 10th of a second is faster than anyone can really notice.
- Don't worry overly much about garbage. Again, users can only click so many times per second. And they don't configure stuff often.
- Conclusion: Prefer smaller and/or more understandable code over speed & garbage efficiency
Handling 'hidden', 'inline' and their variants
The hidden (et al) argument has several variants: 'cmdHidden', 'guiHidden', 'dialogHidden', 'dropdownHidden'. Do not simply combine values with an "or" - more specific values should override less specific ones.
Use a function like this:
-- picks the first non-nil value and returns it
local function pickfirstset(...)
for i=1,select("#",...) do
if select(i,...)~=nil then
return select(i,...)
end
end
end
And then do:
pickfirstset(v.dialogHidden, v.guiHidden, v.hidden, false) pickfirstset(v.dropdownHidden, v.guiHidden, v.hidden, false) pickfirstset(v.cmdHidden, v.hidden, false)
Descend into inlines before checking their name
Consider the following options table:
{
type="group", args = {
myCommand = {
type="group", inline=true,
args = {
myCommand = {
type="execute", func=...
} } } } }
Now, "/someslash myCommand" should trigger the execute, not list the contents of the myCommand group.
Check patterns before calling validate
For input types, check the pattern member before calling validate. Also, keep in mind that for the return value from validate, both nil and false are considered false.
Do not check member function names immediately
Do not check if member function names, e.g. get="someMember", are valid immediately when found in the table. They may be intended for a handler object set further out in the tree. Only check if they are valid when called.
Selects
- For selects, one argument is required. (AceConfigCmd accepts the rest of the string as the argument, regardless of spaces)
get/set logic for Toggles / Multiselects
For a toggling action, the library should do a get() on the current value, change it to the new value, and pass that to set(). However, remember that it is up to the receiving addon to decide what value actually gets saved. So do not assume that the new value became what you gave to the set(). Do a new get() call to find out what actually got saved.
This is doubly true for tristates, where some options might not want the "maybe" state in combination with other settings.
Avoid interactivity in commandline
The primary purpose of the commandline interface is to make things scriptable. Popping up dialogs or other interactive interfaces foils that plan.
Specifically, AceConfigCmd-3.0 ignores the "confirm" directive.
Make sure that "disabled" is recursive and overridable
Consider this command: "/myaddon myModule toggleEnable".
We want to be able to disable the whole "myModule" group with this command. But we still want the "toggleEnable" command to be reachable.
So, we want "disabled=true" on "myModule" to affect all commands underneath it. But when we reach the "toggleEnable" command, which has a hardcoded "disabled=false" on it, we still want to be able to use it - otherwise there's no way of re-enabling the module!
Scan .plugins before .args
We assume that .plugins provide extended functionality over the base functionality, so in case of conflicts (same name), we want items in .plugins used over the base ones.
In case of conflicts in .plugins, the functionality is undefined. We simply use whatever pairs() gives us first.
For an example iterator that implements this, see iterateargs in AceConfigCmd.lua, it's simply used as for k,v in iterateargs(optionsgroup)

