WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   [Classic] programatically adding data via a loop (https://www.wowinterface.com/forums/showthread.php?t=57513)

myrroddin 09-17-19 12:10 PM

[Classic] programatically adding data via a loop
 
I am trying to add, via a loop, color settings to my options table. I'll post the error first, then my Core.lua, which has my defaults table, then my Options.lua which calls the loop.

The call to add to options is in Options.lua, line 252, which in turn should add to the table starting on line 10 of the same file. The base table is defined in Core.lua line 24.

For reference, I am using the "magic key" method in AceDB-3.0, example posted here.

My question is: how is this nil, when I define it in Core.lua?
Code:

Date: 2019-09-17 12:00:02
ID: 1
Error occured in: Global
Count: 1
Message: ..\AddOns\ElvUI_PDBC\Options.lua line 26:
  attempt to index field '**' (a nil value)
Debug:
  [C]: ?
  ElvUI_PDBC\Options.lua:26:
      ElvUI_PDBC\Options.lua:10
  ElvUI_PDBC\Options.lua:252: GetOptions()
  ElvUI_PDBC\Core.lua:62: callback()
  ...\Libraries\LibElvUIPlugin-1.0\LibElvUIPlugin-1.0.lua:165:
      ...\Libraries\LibElvUIPlugin-1.0\LibElvUIPlugin-1.0.lua:159
  [C]: ?
  ElvUI\init.lua:315:
      ElvUI\init.lua:303
  [C]: ?()
  ...vUI\Libraries\Ace3\AceConsole-3.0\AceConsole-3.0.lua:94: ?()
  ..\FrameXML\ChatFrame.lua:4609: ChatEdit_ParseText()
  ..\FrameXML\ChatFrame.lua:4270: ChatEdit_SendText()
  ..\FrameXML\ChatFrame.lua:4306:
      ..\FrameXML\ChatFrame.lua:4302
  [C]: ChatEdit_OnEnterPressed()
  [string "*:OnEnterPressed"]:1:
      [string "*:OnEnterPressed"]:1
Locals:

AddOns:
  Swatter, v8.2.6377 (SwimmingSeadragon)
  WowheadLooter, v11302
  ACP, v3.5.6
  AddOnSkins, v4.30
  AdiBags, vDEV
  AdvancedInterfaceOptions, v1.3.2
  AtlasLootClassic, vv1.1.11
  AucAdvanced, v8.2.6420 (SwimmingSeadragon)
  AucFilterBasic, v8.2.6364 (SwimmingSeadragon)
  AucScanData, v8.2.6365 (SwimmingSeadragon)
  AucStatHistogram, v8.2.6366 (SwimmingSeadragon)
  AucStatiLevel, v8.2.6370 (SwimmingSeadragon)
  AucStatPurchased, v8.2.6367 (SwimmingSeadragon)
  AucStatSimple, v8.2.6399 (SwimmingSeadragon)
  AucStatStdDev, v8.2.6369 (SwimmingSeadragon)
  AucUtilFixAH, v8.2.6371 (SwimmingSeadragon)
  BeanCounter, v8.2.6422 (SwimmingSeadragon)
  BetterVendorPrice, vv1.08.00-classic
  CTCore, v8.2.0.9
  CTLibrary, v8.2.0.5
  CTMailMod, v8.2.0.8
  CTViewport, v8.2.0.4
  DBMCore, v1.13.9
  DBMDefaultSkin, v
  DBMSoundEventsPack, v1.6.2
  DBMStatusBarTimers, v
  DejaClassicStats, v1302r024
  Details, v
  DetailsTinyThreat, v
  ElvUI, v1.08
  ElvUIMerathilisUIClassic, v0.4
  ElvUIOptionsUI, v1.06
  ElvUIPDBC, [email protected]@
  ElvUIQuestXPClassic, v1.0.0
  ElvUIRealMobHealthTags, v1.0.5
  Enchantrix, v8.2.6411 (SwimmingSeadragon)
  FishingBuddy, v0.4
  GatherMate2, v1.45
  GTFO, v4.49.2
  HandyNotes, vv1.5.6
  HandyNotesDungeonLocationsClassic, v1.03
  HandyNotesNPCsClassic, v1.12
  HandyNotesTravelGuideClassic, vv2.1.2
  InFlightLoad, v1.13.002
  Informant, v8.2.6374 (SwimmingSeadragon)
  Mapster, v1.8.4
  Masque, v8.2.7
  MasqueArcaneStone, v1.0
  MaxCam, vv2.4.2
  oRA3, vv2-classic
  Questie, v4.1.0 BETA
  RealMobHealth, v2.11
  SilverDragon, vv11302.0
  SilverDragonClassic, vv11302.0
  SortBags, v0.1.2
  Stubby, v8.2.6376 (SwimmingSeadragon)
  TitanClassic, v1.0.7.11302
  TitanClassicAmmo, v1.0.7.11302
  TitanClassicBag, v1.0.7.11302
  TitanClassicClock, v1.0.7.11302
  TitanClassicGold, v1.0.7.11302
  TitanClassicLocation, v1.0.7.11302
  TitanClassicLootType, v1.0.7.11302
  TitanClassicPerformance, v1.0.7.11302
  TitanClassicRepair, v1.0.7.11302
  TitanClassicVolume, v1.0.7.11302
  TitanClassicXP, v1.0.7.11302
  TomTom, vv11302-1.0.7
  TradeSkillMaster, vv4.8.8
  TradeSkillMasterAppHelper, vv4.0.4
  WeakAuras, v2.14.6
  WIM, v3.7.33
  ZygorGuidesViewerClassic, v1.0
  BlizRuntimeLib_enUS v1.13.2.11302 <none>
  (ck=8c7)

Core.lua starts here:
Code:

-- import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local E, L, V, P, G = unpack(ElvUI)

-- create the plugin for ElvUI
local EPDBC = E:NewModule("EPDBC", "AceEvent-3.0", "AceHook-3.0")
-- we can use this to automatically insert our GUI tables when ElvUI_Config is loaded
local LEP = LibStub("LibElvUIPlugin-1.0")
-- the vaarg statement
local addonName, addon = ...

-- default options
P["EPDBC"] = {
    enabled = true,
    experienceBar = {
        capped = true,
        progress = true,
        xpColor = {r = 0, g = 0.4, b = 1, a = 0.8},
        restColor = {r = 1, g = 0, b = 1, a = 0.2}
    },
    reputationBar = {
        capped = true,
        progress = true,
        color = "ascii",
        ["**"] = {
            [1] = {r = 1, g = 0, b = 0, a = 1},            -- hated
            [2] = {r = 1, g = 0.55, b = 0, a = 1},          -- hostile
            [3] = {r = 1, g = 1, b = 0, a = 1},            -- unfriendly
            [4] = {r = 1, g = 1, b = 1, a = 1},            -- neutral
            [5] = {r = 0, g = 1, b = 0, a = 1},            -- friendly
            [6] = {r = 0.25,  g = 0.4,  b = 0.9, a = 1},    -- honored
            [7] = {r = 0.6, g = 0.2, b = 0.8, a = 1},      -- revered
            [8] = {r = 0.9, g = 0.8,  b = 0.5, a = 1},      -- exalted
        },
        --[[
        userColors = {
            [1] = {r = 1, g = 0, b = 0, a = 1},            -- hated
            [2] = {r = 1, g = 0.55, b = 0, a = 1},          -- hostile
            [3] = {r = 1, g = 1, b = 0, a = 1},            -- unfriendly
            [4] = {r = 1, g = 1, b = 1, a = 1},            -- neutral
            [5] = {r = 0, g = 1, b = 0, a = 1},            -- friendly
            [6] = {r = 0.25,  g = 0.4,  b = 0.9, a = 1},    -- honored
            [7] = {r = 0.6, g = 0.2, b = 0.8, a = 1},      -- revered
            [8] = {r = 0.9, g = 0.8,  b = 0.5, a = 1},      -- exalted
        }
        ]]--
    }
}

local function InitializeCallback()
    EPDBC:Initialize()
end

-- register plugin so options are properly inserted when config is loaded
function EPDBC:Initialize()
    LEP:RegisterPlugin(addonName, EPDBC.InsertOptions)
    EPDBC:EnableDisable()
end

-- insert our GUI options into ElvUI's config screen
function EPDBC:InsertOptions()
    if not E.Options.args.EPDBC then
        E.Options.args.EPDBC = EPDBC:GetOptions()
    end
end

-- register the module with ElvUI. ElvUI will now call EPDBC:Initialize() when ElvUI is ready to load our plugin
E:RegisterModule(EPDBC:GetName(), InitializeCallback)

function EPDBC:EnableDisable()
    -- these functions have both enable/disable checks
    EPDBC:HookXPText()
    EPDBC:HookXPTooltip()
    EPDBC:HookRepText()
    EPDBC:HookRepTooltip()

    if not E.db.EPDBC.enabled then
        EPDBC:UnhookAll() -- make sure no hooks are left behind
    end
end

function EPDBC:Round(num, idp)
    if num <= 0.1 then
        return 0.1
    end
    local mult = 10^(idp or 0)
    return math.floor(num * mult + 0.5) / mult
end

And last, Options.lua:
Code:

-- import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local E, L, V, P, G = unpack(ElvUI)
-- get the DataBars module
local EDB = E:GetModule("DataBars")
local EPDBC = E:GetModule("EPDBC")

-- translate the module's name. normally I wouldn't do this, but it does have an awkward name
local uiName = L["Progressively Colored DataBars"]

local function InsertCustomColors(options)
    --[[ here for reference
    local customColors = {
        [1] = {r = 1, g = 0, b = 0, a = 1},            -- hated
        [2] = {r = 1, g = 0.55, b = 0, a = 1},          -- hostile
        [3] = {r = 1, g = 1, b = 0, a = 1},            -- unfriendly
        [4] = {r = 1, g = 1, b = 1, a = 1},            -- neutral
        [5] = {r = 0, g = 1, b = 0, a = 1},            -- friendly
        [6] = {r = 0.25,  g = 0.4,  b = 0.9, a = 1},    -- honored
        [7] = {r = 0.6, g = 0.2, b = 0.8, a = 1},      -- revered
        [8] = {r = 0.9, g = 0.8,  b = 0.5, a = 1},      -- exalted
    }
    ]]--
    local order = 60

    for i = 1, 8 do -- hated to exalted
        options.args.reputationBar["**"][i] = options.args.reputationBar["**"][i] or {
            order = order,
            name = FACTION_STANDING_LABEL..i,
            type = color,
            hasAlpha = false,
            get = function(info, r, g, b)
                local c = E.db.EPDBC.reputationBar["*"][i]
                return c.r, c.g, c.b
            end,
            set = function(info, r, g, b)
                local c = E.db.EPDBC.reputationBar["*"][i]
                c.r, c.g, c.b = r, g, b
                EDB:UpdateReputation()
            end
        }
        order = order + 10
    end
    return options
end

function EPDBC:GetOptions()
    local options = options or {
        order = 10,
        type = "group",
        name = uiName,
        childGroups = "tab",
        args = {
            enabled = {
                order = 10,
                name = ENABLE,
                desc = L["Toggle module on/off. If off, it restores DataBars to ElvUI defaults."],
                type = "toggle",
                get = function()
                    return E.db.EPDBC.enabled
                end,
                set = function(info, value)
                    E.db.EPDBC.enabled = value
                    EPDBC:EnableDisable()
                end
            },
            experienceBar = {
                order = 20,
                name = XPBAR_LABEL,
                type = "group",
                args = {
                    capped = {
                        order = 10,
                        name = L["Capped"],
                        desc = L["Replace XP text with the word 'Capped' at max level."],
                        type = "toggle",
                        get = function()
                            return E.db.EPDBC.experienceBar.capped
                        end,
                        set = function(info, value)
                            E.db.EPDBC.experienceBar.capped = value
                            EDB:UpdateExperience()
                        end
                    },
                    progress = {
                        order = 20,
                        name = L["Blend Progress"],
                        desc = L["Progressively blend the bar as you gain XP."],
                        type = "toggle",
                        get = function()
                            return E.db.EPDBC.experienceBar.progress
                        end,
                        set = function(info, value)
                            E.db.EPDBC.experienceBar.progress = value
                            EDB:UpdateExperience()
                        end
                    },
                    xpColor = {
                        order = 30,
                        name = L["XP Color"],
                        desc = L["Select your preferred XP color."],
                        type = "color",
                        hasAlpha = true,
                        get = function()
                            local c = E.db.EPDBC.experienceBar.xpColor
                            return c.r, c.g, c.b, c.a
                        end,
                        set = function(info, r, g, b, a)
                            local c = E.db.EPDBC.experienceBar.xpColor
                            c.r, c.g, c.b, c.a = r, g, b, a
                            EDB:UpdateExperience()
                        end
                    },
                    restColor = {
                        order = 40,
                        name = L["Rested Color"],
                        desc = L["Select your preferred rested color."],
                        type = "color",
                        hasAlpha = true,
                        get = function()
                            local c = E.db.EPDBC.experienceBar.restColor
                            return c.r, c.g, c.b, c.a
                        end,
                        set = function(info, r, g, b, a)
                            local c = E.db.EPDBC.experienceBar.restColor
                            c.r, c.g, c.b, c.a = r, g, b, a
                            EDB:UpdateExperience()
                        end
                    }
                }
            },
            reputationBar = {
                order = 30,
                name = L["Reputation Bar"],
                type = "group",
                args = {
                    capped = {
                        order = 10,
                        name = L["Capped"],
                        desc = L["Replace rep text with the word 'Capped' at max."],
                        type = "toggle",
                        get = function()
                            return E.db.EPDBC.reputationBar.capped
                        end,
                        set = function(info, value)
                            E.db.EPDBC.reputationBar.capped = value
                            EDB:UpdateReputation()
                        end
                    },
                    progress = {
                        order = 20,
                        name = L["Blend Progress"],
                        desc = L["Progressively blend the bar as you gain reputation."],
                        type = "toggle",
                        get = function()
                            return E.db.EPDBC.reputationBar.progress
                        end,
                        set = function(info, value)
                            E.db.EPDBC.reputationBar.progress = value
                            EDB:UpdateReputation()
                        end
                    },
                    color = {
                        order = 40,
                        name = L["Progress Color"],
                        desc = L["Change rep bar color by standing."],
                        type = "select",
                        values = {
                            ["ascii"] = "ASCII",
                            ["blizzard"] = "Blizzard",
                            ["custom"] = L["Custom"]
                        },
                        get = function()
                            return E.db.EPDBC.reputationBar.color
                        end,
                        set = function(info, value)
                            E.db.EPDBC.reputationBar.color = value
                            EDB:UpdateReputation()
                        end
                    },
                    description = {
                        order = 50,
                        name = "---------- " .. L["Custom Colors"] .. " ---------",
                        type = "description",
                        fontSize = "large"
                    },
                    --[[
                    hated = {
                        order = 60,
                        name = FACTION_STANDING_LABEL1,
                        type = "color",
                        hasAlpha = false,
                        get = function()
                            local c = E.db.EPDBC.reputationBar.userColors[1]
                            return c.r, c.g, c.b
                        end,
                        set = function(info, r, g, b)
                            local c = E.db.EPDBC.reputationBar.userColors[1]
                            c.r, c.g, c.b = r, g, b
                            EDB:UpdateReputation()
                        end
                    },
                    hostile = {
                        order = 70,
                        name = FACTION_STANDING_LABEL2,
                        type = "color",
                        hasAlpha = false,
                        get = function()
                            local c = E.db.EPDBC.reputationBar.userColors[2]
                            return c.r, c.g, c.b
                        end,
                        set = function(info, r, g, b)
                            local c = E.db.EPDBC.reputationBar.userColors[2]
                            c.r, c.g, c.b = r, g, b
                            EDB:UpdateReputation()
                        end
                    },
                    unfriendly = {
                        order = 80,
                        name = FACTION_STANDING_LABEL3,
                        type = "color",
                        hasAlpha = false,
                        get = function()
                            local c = E.db.EPDBC.reputationBar.userColors[3]
                            return c.r, c.g, c.b
                        end,
                        set = function(info, r, g, b)
                            local c = E.db.EPDBC.reputationBar.userColors[3]
                            c.r, c.g, c.b = r, g, b
                            EDB:UpdateReputation()
                        end
                    },
                    neutral = {
                        order = 90,
                        name = FACTION_STANDING_LABEL4,
                        type = "color",
                        hasAlpha = false,
                        get = function()
                            local c = E.db.EPDBC.reputationBar.userColors[4]
                            return c.r, c.g, c.b
                        end,
                        set = function(info, r, g, b)
                            local c = E.db.EPDBC.reputationBar.userColors[4]
                            c.r, c.g, c.b = r, g, b
                            EDB:UpdateReputation()
                        end
                    },
                    ]]--
                }
            }
        }
    }
    options = InsertCustomColors(options)
    return options
end


Rilgamon 09-17-19 12:31 PM

I guess this line is the key.
Quote:

There are two "magic" keys you can use in the default table.
I guess the metatable of the db works only based on the default table. ( I guess because metatables are magic for me ;) )

myrroddin 09-17-19 04:57 PM

In this case, P["EPDBC"] = {} is the table with the defaults. The table P is the ElvUI equivalent to
Code:

local defaults = {
    profile = {
    }
}


Fizzlemizz 09-17-19 05:52 PM

Code:

options.args.reputationBar["**"][i] = options.args.reputationBar["**"][i]
I don't know Ace but setting and getting(reading) would be two different things (metatables). This statement is doing both.

Does Ace have a metatable for the get? The magic keys link just describes the set.

Vrul 09-17-19 08:46 PM

The magic keys replace requested keys that don't already exist based on the "*" and "**" entries in your defaults table. You cannot directly access the "**" sub-table in the defaults table via a table that inherits from the defaults table.

myrroddin 09-17-19 09:47 PM

A-ha! In that case, instead of rewriting to figure that out, I just created the reputation colours manually in the options table. After all, there are only eight of them, no big deal.


All times are GMT -6. The time now is 04:20 PM.

vBulletin © 2021, Jelsoft Enterprises Ltd
© 2004 - 2020 MMOUI