patternMinor
Form for choosing settings
Viewed 0 times
formchoosingforsettings
Problem
I've created a form to choose the settings: These settings are automatically saved in a file from the game client in this form:
To save the settings in this form I used this function:
Where
Could you help me to make the code less repetitive and more elegant?
["Setting"] = {
["track"] = "Spell Reflect",
["duration"] = {
["minimum"] = {
["enabled"] = 1,
["value"] = 3,
},
["maximum"] = {
},
},
["stack"] = {
["minimum"] = {
},
["maximum"] = {
["enabled"] = 1,
["value"] = 4,
},
},
}To save the settings in this form I used this function:
function UnitScan_onAdvancedOptionClose()
if not (db["duration"]) then
db["duration"] = {}
db["duration"]["minimum"] = {}
db["duration"]["maximum"] = {}
end
db["duration"]["minimum"].enabled = minduration.cbutton:GetChecked()
db["duration"]["minimum"].value = tonumber(minduration.ebox:GetText())
db["duration"]["maximum"].enabled = maxduration.cbutton:GetChecked()
db["duration"]["maximum"].value = tonumber(maxduration.ebox:GetText())
if not (db["stack"]) then
db["stack"] = {}
db["stack"]["minimum"] = {}
db["stack"]["maximum"] = {}
end
db["stack"]["minimum"].enabled = minstack.cbutton:GetChecked()
db["stack"]["minimum"].value = tonumber(minstack.ebox:GetText())
db["stack"]["maximum"].enabled = maxstack.cbutton:GetChecked()
db["stack"]["maximum"].value = tonumber(maxstack.ebox:GetText())
endWhere
db= The "Setting" table
GetChecked()= Returns whether the check button is checked
GetText()= Returns the edit box's text contents
Could you help me to make the code less repetitive and more elegant?
Solution
One big thing we need to do is to sort everything into arrays
I should point out that
is the same as
Firstly, shift
Stuff that needs to be called during min should be given the
Sort everything else out...
Lets take a break for a second, and create the important array
This creates
Now first, we iterate over the stack and duration keys
Then we iterate over the min max values
Then we iterate over enabled and value
To recap, for both the stack and duration, we are checking min and max, and for both min and max, we are checking enabled and value. So your function looks something like this:
Finally, we iterate over all the min entries to tonumber them
Let's consolidate everything:
Sorry for the long answer. Hopefully it works, because with such a complicated program my poor brain had to work it out slowly and methodically. The different steps should help you understand my train of thought and help you flush out any bugs (if there are any)
I cannot guarantee this solution will work (I may have messed up somewhere), and it looks really repetitive in itself but here you go.
EDIT: I noticed some of the code is missing. I'll fill in the rest when I have time
EDIT 2: I changed some of the code after reviewing it again.
EDIT 3: Thank you Etan Reisner for pointing out the mistakes I made. I've edited the code.
EDIT 4: You can actually combine the array creation loop and the main body loop if you want:
I should point out that
db.stackis the same as
db["stack"]Firstly, shift
GetChecked() and GetText() (sidenote functions names usually start with lowercase) into an arraylocal get = { maximum = GetChecked, minimum = GetText }Stuff that needs to be called during min should be given the
"minimum" key. Same with "maximum".Sort everything else out...
local func = { minimum = "cbutton", maximum = "ebox"}
local keys = {"enabled", "value"}
local minmax = {"minimum", "maximum"}
local db = {}
local stuff = {"stack", "duration"}
local minormax = { minimum = "min", maximum = "max" }Lets take a break for a second, and create the important array
for _, each in ipairs(stuff) do
db[each] = {}
for _, it in ipairs(minmax) do
db[each][it] = {}
end
endThis creates
db["stack"]["minimum"]
db["stack"]["maximum"]
db["duration"]["minimum"]
db["duration"]["maximum"]Now first, we iterate over the stack and duration keys
for _, param in ipairs(stuff) do
endThen we iterate over the min max values
for _, param in ipairs(stuff) do
for _, min_max in ipairs(minmax) do
end
endThen we iterate over enabled and value
for _, param in ipairs(stuff) do
for _, min_max in ipairs(minmax) do
for _, key in ipairs(keys) do
end
end
endTo recap, for both the stack and duration, we are checking min and max, and for both min and max, we are checking enabled and value. So your function looks something like this:
db[param][min_max][key] = _G[minormax[min_max]..param][func[min_max]]:get[min_max]()Finally, we iterate over all the min entries to tonumber them
for _, each in ipairs(db) do
for _, it in ipairs(db[each]["minimum"]) do
db[each]["minimum"] = tonumber[each]["minimum"]
end
endLet's consolidate everything:
local func = { minimum = "cbutton", maximum = "ebox"}
local get = { maximum = GetChecked, minimum = GetText }
local keys = {"enabled", "value"}
local minmax = {"minimum", "maximum"}
local db = {}
local stuff = {"stack", "duration"}
local minormax = { minimum = "min", maximum = "max" }
for _, each in ipairs(stuff) do --Create the multidimensional array
db[each] = {}
for _, it in ipairs(minmax) do
db[each][it] = {}
end
end
for _, param in ipairs(stuff) do --The important function
for _, min_max in ipairs(minmax) do
for _, key in ipairs(keys) do
db[param][min_max][key] = _G[minormax[min_max]..param][func[min_max]]:get[min_max]()
end
end
end
for _, each in ipairs(db) do --Tonumber all the min entries
for _, it in ipairs(db[each]["minimum"]) do
db[each]["minimum"] = tonumber([each]["minimum"])
end
endSorry for the long answer. Hopefully it works, because with such a complicated program my poor brain had to work it out slowly and methodically. The different steps should help you understand my train of thought and help you flush out any bugs (if there are any)
I cannot guarantee this solution will work (I may have messed up somewhere), and it looks really repetitive in itself but here you go.
EDIT: I noticed some of the code is missing. I'll fill in the rest when I have time
EDIT 2: I changed some of the code after reviewing it again.
EDIT 3: Thank you Etan Reisner for pointing out the mistakes I made. I've edited the code.
EDIT 4: You can actually combine the array creation loop and the main body loop if you want:
for _, param in ipairs(stuff) do --The important function
db[param] = {}
for _, min_max in ipairs(minmax) do
db[param][min_max] = {}
for _, key in ipairs(keys) do
db[param][min_max][key] = _G[minormax[min_max]..param][func[min_max]]:get[min_max]()
end
end
endCode Snippets
db["stack"]local get = { maximum = GetChecked, minimum = GetText }local func = { minimum = "cbutton", maximum = "ebox"}
local keys = {"enabled", "value"}
local minmax = {"minimum", "maximum"}
local db = {}
local stuff = {"stack", "duration"}
local minormax = { minimum = "min", maximum = "max" }for _, each in ipairs(stuff) do
db[each] = {}
for _, it in ipairs(minmax) do
db[each][it] = {}
end
enddb["stack"]["minimum"]
db["stack"]["maximum"]
db["duration"]["minimum"]
db["duration"]["maximum"]Context
StackExchange Code Review Q#82196, answer score: 5
Revisions (0)
No revisions yet.