WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   [SOLVED] Help with AceDb: Deleting items from table won't stay deleted. (https://www.wowinterface.com/forums/showthread.php?t=56514)

Sweetsour 08-08-18 11:14 PM

[SOLVED] Help with AceDb: Deleting items from table won't stay deleted.
 
I'm currently at a loss with this and have tried many different things to no avail, including searching google :(

To quickly explain what's going on, I'm trying to delete an item from a specific table in my addon's db - that uses AceDb - and it works, but the deletion is reverted when the game/ui is reloaded.

The table below is the table I've been working with to test. In my addon's config, I've coded the ability to remove spells from the group. In my case, I've been trying to remove item #3, "LavaBurst".
Lua Code:
  1. groups = {
  2.     [1] = {
  3.         [1] = "FlameShock",
  4.         [2] = "EarthShock",
  5.         [3] = "LavaBurst",
  6.         [4] = "Earthquake",
  7.         [5] = "ElementalBlast",
  8.     },
  9.     ...
  10. },

The following methods were tried to delete the table item
Lua Code:
  1. -- Tried the simplest way to remove a table item
  2. tremove(db.auras[spec].groups[grp],j)

Lua Code:
  1. -- Tried an advance means of removing a table item
  2. local function RemoveItemFromTable(db,index)
  3.     local numItems = #db
  4.    
  5.     db[index] = nil
  6.    
  7.     if (index < numItems) then
  8.         for i=index,numItems do
  9.             if (db[i + 1]) then
  10.                 db[i] = db[i + 1]
  11.                 db[i + 1] = nil
  12.             else
  13.                 db[numItems] = nil
  14.             end
  15.         end
  16.     end
  17. end

Lua Code:
  1. -- I even tried clearing that table completely and rebuilding it
  2. local function RebuildAuraGroupTable(db,grp)
  3.     local tempTable = {}
  4.    
  5.     for i=1,#db[grp] do
  6.         tinsert(tempTable,db[grp][i])
  7.     end
  8.    
  9.     db[grp] = nil
  10.    
  11.     db[grp] = {}
  12.    
  13.     for i=1,#tempTable do
  14.         db[grp][i] = tempTable[i]
  15.     end
  16. end
Using LuaBrowser, I can verify that "LavaBurst" is correctly removed from the table.

BEFORE DELETION


AFTER DELETION (Before game/UI reload)


AFTER DELETION (After game/UI reload)


It's clear that AceDb didn't recognize the deletion and is just loading slot #5 from the "defaults" table on reload. Is there any way to stop this from happening?

Rilgamon 08-08-18 11:50 PM

Without your real code it's not really possible to help.
It looks like you don't use the db but a local copy of it.

Sweetsour 08-09-18 12:50 AM

Ah, good call.

This is my initialization code
Lua Code:
  1. function Auras:OnInitialize()
  2.  
  3.     local defaults = SSA.defaults;
  4.     local about_panel = LibStub:GetLibrary("LibAboutPanel", true)
  5.  
  6.     if about_panel then
  7.         self.optionsFrame = about_panel.new(nil, "ShamanAuras")
  8.     end
  9.    
  10.     self.db = LibStub("AceDB-3.0"):New("SSA_db",defaults)
  11.     self:SetupOptions()
  12.    
  13.    
  14. end

The function that handles removing an item from the table is located in a different file
Lua Code:
  1. local SSA, Auras, L, LSM = unpack(select(2,...))
  2.  
  3. local function ConstructAuraList()
  4.     ...
  5.     --- this is the button that runs the deletion
  6.     removeAura = {
  7.         order = 4,
  8.         type = "execute",
  9.         name = "Remove",
  10.         func = function()
  11.             tremove(Auras.db.char.auras[spec].groups[grp],j)
  12.         end,
  13.         width = "half",
  14.     }
  15.     ...
  16. end

It's strange, though. Any changes go through no problem, but deleting part of a table doesn't.

Rilgamon 08-09-18 01:46 AM

I'm not sure but iirc tremove does not trigger the metatable of the db-object.
Edit: Perhaps this thread can help you? https://authors.curseforge.com/forum...s-why-immortal
The part with default entries that cant be deleted.
Edit2: Or this http://lua-users.org/lists/lua-l/2008-07/msg00100.html

Sweetsour 08-09-18 02:05 AM

I also tried these methods in place of tremove(), but still no luck :/

Edit: I just saw your edits and will check them out
Edit2: Hmm, great find! I might have to add the values to the table on load, or something.

-- Method #1
Lua Code:
  1. local function RemoveItemFromTable(spec,grp,index)
  2.     Auras.db.char.auras[spec].groups[grp][index] = nil
  3.    
  4.     if (index < #Auras.db.char.auras[spec].groups[grp]) then
  5.         for i=index,#Auras.db.char.auras[spec].groups[grp] do
  6.             if (Auras.db.char.auras[spec].groups[grp][i + 1]) then
  7.                 Auras.db.char.auras[spec].groups[grp][i] = db[i + 1]
  8.                 Auras.db.char.auras[spec].groups[grp][i + 1] = nil
  9.             else
  10.                 Auras.db.char.auras[spec].groups[grp][numItems] = nil
  11.             end
  12.         end
  13.     end
  14. end
  15.  
  16. local function RebuildAuraGroupTable(spec,grp)
  17.     local tempTable = {}
  18.    
  19.     for i=1,#Auras.db.char.auras[spec].groups[grp] do
  20.         tinsert(tempTable,Auras.db.char.auras[spec].groups[grp][i])
  21.     end
  22.    
  23.     -- Clear the group then remake it
  24.     Auras.db.char.auras[spec].groups[grp] = nil
  25.     Auras.db.char.auras[spec].groups[grp] = {}
  26.    
  27.     for i=1,#tempTable do
  28.         Auras.db.char.auras[spec].groups[grp][i] = tempTable[i]
  29.     end
  30. end
  31.  
  32. local function ConstructAuraList()
  33.     ...
  34.     --- this is the button that runs the deletion
  35.     removeAura = {
  36.         order = 4,
  37.         type = "execute",
  38.         name = "Remove",
  39.         func = function()
  40.             --tremove(Auras.db.char.auras[spec].groups[grp],j)
  41.  
  42.             -- I did this first by itself
  43.             RemoveItemFromTable(spec,grp,index)
  44.  
  45.             -- When the above didn't work, I added this, but still no dice :(
  46.             RebuildAuraGroupTable(spec,grp)
  47.         end,
  48.         width = "half",
  49.     }
  50.     ...
  51. end

Vrul 08-09-18 06:20 AM

You can't use an array like that. You want to use a dictionary:
Code:

groups = {
    [1] = {
        ["FlameShock"] = true,
        ["EarthShock"] = true,
        ["LavaBurst"] = true,
        ["Earthquake"] = true,
        ["ElementalBlast"] = true,
    },
    ...
},


Then to remove it you would do:
Code:

groups[1]["LavaBurst"] = false
Don't set it to nil or the default will kick in.


I would suggest posting all of your code because it looks like you could make your options more efficient.

Sweetsour 08-09-18 10:35 AM

Not to worry, the rest of my tables in my defaults are dictonaries. The reason I used an indexed table was that I needed the spells in a specific order, which you can't do with dictionaries. However, the solution I used was making a small addition to my "spells" table.

Original configuration
Lua Code:
  1. ["Adaptation"] = {
  2.     condition = function() return select(10,GetPvpTalentInfoByID(3597)) and IsPvPZone() end,
  3.     spellID = 214027,
  4.     isInUse = true,
  5. },
  6. ["AncestralGuidance"] = {
  7.     condition = function() return select(4,GetTalentInfo(5,2,1)) end,
  8.     spellID = 108281,
  9.     isInUse = true,
  10. },
  11. ["Ascendance"] = {
  12.     condition = function() return select(4,GetTalentInfo(7,3,1)) end,
  13.     spellID = 114050,
  14.     isInUse = true,
  15. },
  16. ...

New configuration
Lua Code:
  1. ["Adaptation"] = {
  2.     condition = function() return select(10,GetPvpTalentInfoByID(3597)) and IsPvPZone() end,
  3.     spellID = 214027,
  4.     group = 4,
  5.     order = 1,
  6.     isInUse = true,
  7. },
  8. ["AncestralGuidance"] = {
  9.     condition = function() return select(4,GetTalentInfo(5,2,1)) end,
  10.     spellID = 108281,
  11.     group = 2,
  12.     order = 3,
  13.     isInUse = true,
  14. },
  15. ["Ascendance"] = {
  16.     condition = function() return select(4,GetTalentInfo(7,3,1)) end,
  17.     spellID = 114050,
  18.     group = 2,
  19.     order = 2,
  20.     isInUse = true,
  21. },

Thanks for the help/insights, everyone :)

Vrul 08-09-18 01:17 PM

If the array was necessary then all you needed to do with your original code was add a false at the end after removing the value. You were taking a table of length 5 and making it length 4 but the defaults were still length 5 so it added the default at the nil location. If AceDB sees a nil in your table when there is a value in that same spot in the defaults it puts the default value in, hence fill with false.

Sweetsour 08-09-18 02:19 PM

That wouldn't have worked with how my addon works because I've designed it so users can move spells between groups. The new method I coded works perfectly.


All times are GMT -6. The time now is 08:52 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI