WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   AceDB-3.0 not saving (https://www.wowinterface.com/forums/showthread.php?t=55993)

gempir 01-22-18 05:36 AM

AceDB-3.0 not saving
 
This thread is similar to my previous one, but I just can't figure out why AceDB is not working correctly.

I have followed the AceDB Tutorial here like 5 times and have read others but can't get AceDB working correctly. https://www.wowace.com/projects/ace3...b-3-0-tutorial

Currently I have this menu:


It has toggles, sliders, dropdowns everything working nicely actually. Even the profiles tab works and i can see different profiles. (Like Realm, Default, Char etc.)

But nothing saves correctly. After reloading or logging out NOTHING is saved. I have deleted the saved variables probably 10x now and tried restarting, logging out, reloading etc. Nothing seems to work.

This is how the saved variables file looks like:


Lua Code:
  1. gempDB = {
  2.     ["profileKeys"] = {
  3.         ["Wraths - Proudmoore"] = "Default",
  4.     },
  5.     ["profiles"] = {
  6.         ["Default"] = {
  7.         },
  8.     },
  9. }

Which makes sense, the Menu in the screenshot is just filled with my default values.

This is my Initialization:

Lua Code:
  1. G.ace = LibStub("AceAddon-3.0"):NewAddon("gempUI", "AceConsole-3.0", "AceEvent-3.0")
  2.  
  3. function G.ace:OnInitialize()
  4.     self.db = LibStub("AceDB-3.0"):New("gempDB", defaults, true)
  5.     options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
  6.  
  7.  
  8.     LibStub("AceConfig-3.0"):RegisterOptionsTable("gempUI", options)
  9.     self.optionsFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("gempUI", "gempUI")
  10. end

If you want to see the full addon you can see it here:
https://github.com/gempir/gempUI/blo...9a1/config.lua

"gempDB" is my Saved Variables Variables references in the .toc file

Code:

## SavedVariables: gempDB
At this point I'm reading the AceDB code and trying to debug my way through it wanting to find out where I am doing something wrong.

I even copy pasted this example https://wow.gamepedia.com/WelcomeHom...3_to_the_Party

and tried it out and can't get it working in my current setup. Which makes me think I am loading the libraries wrong or something? I have no clue at this point.
I'm running 0 addons besides my own addon so there is no interference with other libraries.


Has anyone struggled in a similar way with AceDB? I've tried not using acedb and saving into gempDB directly in the getters/setters. This works without a problem, but I really would like the Profile solution of AceDB and not write my own Profile management.

myrroddin 01-22-18 08:06 AM

This has been mentioned before: AceDB does NOT write updated values to your saved variables file unless the user changes a setting from the default to something else.

If nothing has been changed from the defaults table, then nothing is written.

Let's say you have this default table:
Lua Code:
  1. local defaults = {
  2.     profile = {
  3.         pet = "dog",
  4.         breed = "Doberman"
  5.     }
  6. }
When you load the addon, then exit out of the game, you will NOT see entries for pet or breed. Now load the addon again, and change pet to "cat"; NOW AceDB will write an entry that says pet = "cat".

gempir 01-22-18 08:59 AM

Yeah I totally get that and I've read that before aswell, but that's not my issue. My issue is I can't change anything and get it saved.

Like changing the default profile is a change from the defaults, so it should show up in the saved vars. But it doesn't and the ingame menu resets after a reload.

Lombra 01-22-18 10:36 AM

So do the options actually work and affect the addon functionality? Regardless of whether they get saved.

Have you tried printing the contents of gempDB after changing something to see if it's "physically" written to the DB?

gempir 01-22-18 10:43 AM

Quote:

Originally Posted by Lombra (Post 326585)
So do the options actually work and affect the addon functionality? Regardless of whether they get saved.

Have you tried printing the contents of gempDB after changing something to see if it's "physically" written to the DB?

Yeah I've tried that. They are written to the self.db table and can be printed out etc. but after a reload they are lost.

But gempDB itself stays empty besides the Boilerplate stuff, I've posted above.

myrroddin 01-23-18 08:34 AM

Okay, if gempDB the table is populating, and changing settings in game actually does stuff, yet reloading the UI and exiting out of the game do not write to disk, then you probably have a file permission issue.

Assuming you use Windows, is your game installed in some variant of Program Files\World of Warcraft? If so, move the game to a neutral folder, like C:\ or C:\Blizzard\World of Warcraft. Windows is notorious for not letting the Program Files path have write privileges.

You can further test this by installed a totally different AddOn, changing its settings, then either reloading the UI or exiting out and checking the saved variables file. If nothing is written, then you know for sure.

gempir 01-23-18 08:58 AM

Quote:

Originally Posted by myrroddin (Post 326599)
Okay, if gempDB the table is populating, and changing settings in game actually does stuff, yet reloading the UI and exiting out of the game do not write to disk, then you probably have a file permission issue.

Assuming you use Windows, is your game installed in some variant of Program Files\World of Warcraft? If so, move the game to a neutral folder, like C:\ or C:\Blizzard\World of Warcraft. Windows is notorious for not letting the Program Files path have write privileges.

You can further test this by installed a totally different AddOn, changing its settings, then either reloading the UI or exiting out and checking the saved variables file. If nothing is written, then you know for sure.

I doubt it's file permissions. Every other addons works fine and all settings save fine. Like I said replacing AceDB with my own custom implementation works aswell, so it's AceDB specific.

Also my WoW is here: C:\Games\Blizzard\World of Warcraft not in "Program Files"

BUT I did not mean gempDB Table is populating. the self.db (internally from AceDB) Table is Populating, not gempDB.

gempDB looks like this (even when changing a lot of settings):


myrroddin 01-24-18 11:13 AM

As an experiment, temporarily remove all .ace from your G table, so it reads like G:OnInitialize, G.db, etc.

Further, I suspect (but can't confirm) that the following line is the root of your issue. Assuming that your posted code is the first Lua file loaded that isn't a localization file or a library, the tables G and V do not exist as far as AceDB is concerned, but F does. It would greatly help if you posted a zip of your addon for downloading and testing.

What are the full names for F, G, and V? What do they represent? Single letters are beyond vague.
Code:

local F, G, V = unpack(select(2, ...))

gempir 01-24-18 01:16 PM

Quote:

Originally Posted by myrroddin (Post 326606)
As an experiment, temporarily remove all .ace from your G table, so it reads like G:OnInitialize, G.db, etc.

Further, I suspect (but can't confirm) that the following line is the root of your issue. Assuming that your posted code is the first Lua file loaded that isn't a localization file or a library, the tables G and V do not exist as far as AceDB is concerned, but F does. It would greatly help if you posted a zip of your addon for downloading and testing.

What are the full names for F, G, and V? What do they represent? Single letters are beyond vague.
Code:

local F, G, V = unpack(select(2, ...))

Hmm that could be it... Tbh I haven't looked a ton into namespaces with lua etc. and just saw this of a way of sharing Variables across files easily. F stands for Functions and has global functions like createBorder or so. G is just for Variables for my UI like G.texture which is the default texture, and finally V is less used but was supposed to be something for Variables like V.playerName and the name is stored in there.

I saw something similar in ElvUI and just started copying it in my own way, guess it doesn't make a ton of sense and I'm just using it as a dirty hack currently.
I start all my lua files with that btw.

This explains it a bit:
Lua Code:
  1. local addon, core = ...
  2. local name, ns = ...
  3.  
  4. core[1] = {} -- F, functions
  5. core[2] = {} -- G, globals like fonts, textures, media, Ace3
  6. core[3] = {} -- V, variables
  7.  
  8. local F, G, V = unpack(select(2, ...))

You can download the Addon via github https://github.com/gempir/gempUI/archive/master.zip just rename the folder inside the zip to gempUI

Rilgamon 01-25-18 06:39 AM

This construct makes no sense. '...' represents the arguments passed to every file loaded in your addon.
There are only 2 arguments. The first is the name of your addon. And the second is a table unique for your addon.

So you should only have one line. It should look more like this

Code:

local name, ns = ...
ns.F = {} -- F, functions
ns.G = {} -- G, globals like fonts, textures, media, Ace3
ns.V = {} -- V, variables
local F, G, V = ns.F,ns.G,ns.V


gempir 01-25-18 08:10 AM

The line does make sense.

Lua Code:
  1. select(2, ...)

Means it returns all arguments after 2 (including 2) so only "ns" in your example.

Unpack then turns the table of core into 3 variables into F,G,V

Lua Code:
  1. local F, G, V = unpack(select(2, ...))

So it's basicly the same as your example but ignores the name of the addon.

Rilgamon 01-26-18 03:04 PM

Quote:

Originally Posted by gempir (Post 326609)
Lua Code:
  1. local F, G, V = unpack(select(2, ...))

Your code has two variables for the addon name (name, addon)
And two for the addon table (ns, core)
So for me it does not make sense to have different names for the same variables.
And as you say select will always unpack core so why not use it?

It would highly increase readability.

gempir 01-26-18 03:45 PM

The name core is only ever seen in the main lua file. All others just know about F, G, V which is kinda nice IMO. but I agree readability could be improved. It takes a minute to understand what the hell unpack, select, etc. do

But sadly it's not having an impact on Ace3, I've tried using a local variable for Ace instead of G.ace but I'm having no luck with saving variables either.

gempir 01-26-18 04:21 PM

UPDATE!

Okay so after debugging this for days now I've finally figure out the problem. Somehow Ace3's OnInitialize function does not work as expected. The official docs show this:

Lua Code:
  1. AceDBExample = LibStub("AceAddon-3.0"):NewAddon("AceDBExample")
  2.  
  3. function AceDBExample:OnInitialize()
  4.   self.db = LibStub("AceDB-3.0"):New("AceDBExampleDB")
  5. end

"AceDBExampleDB" is the saved var from the .toc file. I've done the same with my "gempDB" but I finally found out that it's nil at this point of the loading process.

I hacked together this quick fix:

Lua Code:
  1. function G.ace:OnInitialize()
  2.     local frame = CreateFrame("FRAME", "SavedVarsFrame");
  3.     frame:RegisterEvent("ADDON_LOADED")
  4.     frame:SetScript("OnEvent", function(self, event, arg1)
  5.         if arg1 == "gempUI" then
  6.             self:UnregisterEvent("ADDON_LOADED")
  7.             G.ace.db = LibStub("AceDB-3.0"):New("gempDB", defaults, true)
  8.             options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(G.ace.db)
  9.         end
  10.     end)
  11. [..]

and VOILA my config now saves correctly after reloading. The only Idea I have is that AceDB listens to the wrong ADDON_LOADED event? But I'm assuming the first argument of :NewAddon dictates the addon name, and that's what I have.

Lua Code:
  1. G.ace = LibStub("AceAddon-3.0"):NewAddon("gempUI", "AceConsole-3.0", "AceEvent-3.0")

So. Anyone an Idea what's going on? Should I maybe open an issue on their wowace page?

myrroddin 01-30-18 07:26 AM

Quote:

Originally Posted by gempir (Post 326639)
Should I maybe open an issue on their wowace page?

No, because there is nothing wrong with Ace3. I looked at your code, and the issue is confusion about Ace3's API, basic WoW Lua, and using ElvUI's code.

Stop looking at ElvUI's code. Just. Please. Stop. Delete all knowledge of it from your brain. Never look at it again. I cannot stress this enough as it is possibly the worst example of how to write and maintain a full UI, and new Lua authors get lost in trying to understand.

I don't have time right now to write up a brief and correct way to write your GempUI, but I will do my best when I do have time. When I do write it up, I shall endeavor to document it as clearly as possible.

gempir 01-30-18 08:18 AM

Quote:

Originally Posted by myrroddin (Post 326696)
No, because there is nothing wrong with Ace3. I looked at your code, and the issue is confusion about Ace3's API, basic WoW Lua, and using ElvUI's code.

Stop looking at ElvUI's code. Just. Please. Stop. Delete all knowledge of it from your brain. Never look at it again. I cannot stress this enough as it is possibly the worst example of how to write and maintain a full UI, and new Lua authors get lost in trying to understand.

I don't have time right now to write up a brief and correct way to write your GempUI, but I will do my best when I do have time. When I do write it up, I shall endeavor to document it as clearly as possible.

Okay thanks. There are few examples of good UIs that also use similar libraries as I am. Also ElvUI is highly sucessful and has a lot of configuration options, so I thought looking at their Code can't be too bad, but from what you are describing it sounds like ElvUI is the wordpress of World of Warcraft.

I appreciate any tips.

Lombra 01-30-18 09:20 AM

I don't have any experience with the ElvUI source, but in general it might be better starting with a simpler example.

I had a look at the Ace3 source, and the logic behind OnInitialize was a bit confusing to me, so I don't know what could've gone wrong there.

I think you can definitely submit a ticket, but first you should narrow your code down. Make as simple as possible an example of the OnInitialize method not firing.

gempir 01-30-18 10:09 AM

I think this is a bit too focused on ElvUI here. All Im doing is using wow addon namespace with a table.

Rilgamon 02-01-18 02:28 AM

Do you really need Ace-Addon? If you dont use any other function from this lib you can just leave it alone and directly register ADDON_LOADED like you do in OnInitialize. Every ACE-Lib is standalone. e.g. I use, Ace-Db, Ace-Config but never Ace-Addon.


For my addons I do it this way ... where childName is the addon name and addon is the namespace-table, defaults is the table where defaults are defined.
Lua Code:
  1. if(event=='ADDON_LOADED') then
  2.     if(arg1 ~= childName) then return end
  3.     addon['db'] = addon['db'] or LibStub("AceDB-3.0"):New(childName.."DB", nil, default)
  4.     if(type(defaults) == 'table') then
  5.         addon['db']['profile'][childName] = addon['db']['profile'][childName] or CopyTable(defaults)
  6.     else
  7.         addon['db']['profile'][childName] = addon['db']['profile'][childName] or {}
  8.     end

Rilgamon 02-01-18 04:49 AM

I wrote two test-addons and both work as they should. The first without AceAddon and the second with.

Lua Code:
  1. ## Interface: 70300
  2. ## Title: Example_AceDB_01
  3. ## SavedVariables: Example_AceDB_01DB
  4.  
  5. AceDB-3.0/AceDB-3.0.xml
  6. Example_AceDB_01.lua

Lua Code:
  1. local addonName, addonTable = ...
  2. local defaults = {
  3.     profile = {
  4.         loaded = addonName,
  5.         open = false
  6.     }
  7. }
  8. local f = CreateFrame("FRAME")
  9. local function handleEvent(self, event)
  10.     if(event == "ADDON_LOADED") then
  11.         if(arg1 ~= childName) then return end
  12.         addonTable['db'] = addonTable['db'] or LibStub("AceDB-3.0"):New(addonName.."DB", defaults, true)
  13.         self:UnregisterEvent("ADDON_LOADED")
  14.         self:RegisterEvent("MAIL_SHOW")
  15.         self:RegisterEvent("MERCHANT_SHOW")
  16.     elseif(event == "MERCHANT_SHOW") then
  17.         addonTable['db']['profile']['open'] = false
  18.     elseif(event == "MAIL_SHOW") then
  19.         addonTable['db']['profile']['open'] = true
  20.     end
  21. end
  22. f:RegisterEvent("ADDON_LOADED")
  23. f:SetScript("OnEvent", handleEvent)

Lua Code:
  1. ## Interface: 70300
  2. ## Title: Example_AceDB_02
  3. ## SavedVariables: Example_AceDB_02DB
  4. AceAddon-3.0/AceAddon-3.0.xml
  5. AceDB-3.0/AceDB-3.0.xml
  6. Example_AceDB_02.lua

Lua Code:
  1. local addonName, addonTable = ...
  2. local defaults = {
  3.     profile = {
  4.         loaded = addonName,
  5.         open = false
  6.     }
  7. }
  8. local AceDBExample = LibStub("AceAddon-3.0"):NewAddon(addonName)
  9. local function handleEvent(self, event)
  10.     if(event == "MERCHANT_SHOW") then
  11.         addonTable['db']['profile']['open'] = false
  12.     elseif(event == "MAIL_SHOW") then
  13.         addonTable['db']['profile']['open'] = true
  14.     end
  15. end
  16. function AceDBExample:OnInitialize()
  17.     addonTable['db'] = addonTable['db'] or LibStub("AceDB-3.0"):New(addonName.."DB", defaults, true)
  18.     local f = CreateFrame("FRAME")
  19.     f:RegisterEvent("MAIL_SHOW")
  20.     f:RegisterEvent("MERCHANT_SHOW")
  21.     f:SetScript("OnEvent", handleEvent)
  22. end

You can find them in the WoWI-SVN


All times are GMT -6. The time now is 07:49 PM.

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