Thread Tools Display Modes
04/02/14, 06:09 PM   #1
Vuelhering
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 169
two questions about saved variables

Maybe someone can shed some light on this...

Q1:
Let's say I have a saved variable named "sv", which I load through
Code:
sv = ZO_SavedVars:New("myaddon", major, nil, {} , nil) or {}
I can do things like
sv.foo = "bar", and d(sv.foo) produces "bar".

But traversing sv with pairs() is bizarre. How do I traverse the keys I just stored?


Q2:
Saved variables are different for each character.

How do I make one that's global to all characters?
  Reply With Quote
04/02/14, 07:22 PM   #2
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
Instead of using :New() use :NewAccountWide()

That said, I don't use their saved variables API. I just do it all manually. (So much easier on my sanity...)
  Reply With Quote
04/02/14, 07:31 PM   #3
Halja
 
Halja's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 111
In lua pairs() may not guaranty order on arrays and if the array has different types. Things may come back in a different order. Ipairs if will you are using indexed table sections. You don't have to traverse the whole lua table with pairs() or ipairs(). You can make jumps.

The following is was not tested. I may have typos. Given your savedvars file look something like this.
Lua Code:
  1. savedVars =
  2.     {
  3.         ["Default"] =
  4.         {
  5.             ["@AccountName"] =
  6.             {
  7.                 ["$AccountWide"] =
  8.                 {
  9.                     ["IndexTable"] =
  10.                     {
  11.                         [1] =
  12.                         {
  13.                             ["LName"] = [[Doe]],
  14.                             ["FName"] = [[Jon]],
  15.                         },
  16.                         [2] =
  17.                         {
  18.                             ["LName"] = [[Doe]],
  19.                             ["FName"] = [[Jane]],
  20.                         },
  21.                         [3] =
  22.                         {
  23.                             ["LName"] = [[Smith]],
  24.                             ["FName"] = [[John]],
  25.                         },
  26.                     },
  27.                     ["version"] = [[0.1.3]],
  28.                     ["Location"] =
  29.                     {
  30.                         ["X"] = 10,
  31.                         ["Y"] = 20,
  32.                     },
  33.                 },
  34.             },
  35.         },
  36.     }
As long as there is just one "Location" this dot notation works.
Lua Code:
  1. local x =  savedVars.Location.X
  2. local y = savedVars.Location.Y

And this for indexed tables:
Lua Code:
  1. for k,v  in ipairs (savedVars.IndexTable) do
  2.         d(v["LName"])
  3.         d(v["FName"])
  4. end

I know of two calls for saved varables. The ESOUI sample shows one.
Saved for each character:
local savedVars = ZO_SavedVars:New(savedVariableName, version, namespace, defaults, profile)

Save for the Account:
local savedVars = ZO_SavedVars:NewAccountWide(savedVariableName, version, namespace, defaults, profile)

--halja

Last edited by Halja : 04/02/14 at 07:33 PM.
  Reply With Quote
04/02/14, 07:34 PM   #4
Vuelhering
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 169
Originally Posted by Seerah View Post
Instead of using :New() use :NewAccountWide()

That said, I don't use their saved variables API. I just do it all manually. (So much easier on my sanity...)
Ah, that'll fix Q2.

How do you do it, Seerah? You still have to go through their api to write out the variables, don't you?

Thanks


Originally Posted by Halja View Post
And this for indexed tables:
Lua Code:
  1. for k,v  in ipairs (savedVars.IndexTable) do
  2.         d(v["LName"])
  3.         d(v["FName"])
  4. end
Ah, that might fix Q1.
  Reply With Quote
04/02/14, 07:40 PM   #5
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
Not at all. Saved variables get written to the file upon reload our logout, just like in WoW. Have a loot at one of my addons if you wish to see how I handle them. (defaults table is usually near the top of the file with upvalues, and code to handle saved vars is usually toward the bottom in the first function to run)
  Reply With Quote
04/02/14, 07:46 PM   #6
Xrystal
caritas omnia vincit
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 369
Traversing the keys was a nightmare for me.

Say with a saved variable table as follows:

Lua Code:
  1. XrysGatherer_SavedVariables =
  2. {
  3.     ["Default"] =
  4.     {
  5.         ["@Xrystal"] =
  6.         {
  7.             ["$AccountWide"] =
  8.             {
  9.                 ["Options"] =
  10.                 {
  11.                     ["ShowAlert"] = 0,
  12.                     ["version"] = 1,
  13.                 },
  14.                 ["Data"] =
  15.                 {
  16.                     ["Bleakrock Isle"] =
  17.                     {
  18.                         ["raw jute"] =
  19.                         {
  20.                             [1] =
  21.                             {
  22.                                 ["X"] = 0.526202,
  23.                                 ["Date"] = 20140331,
  24.                                 ["Trade Skill"] = [[Clothing]],
  25.                                 ["Item Type"] = [[Raw Material]],
  26.                                 ["Y"] = -0.137464,
  27.                                 ["Action"] = [[Collect]],
  28.                                 ["Time"] = [[23:01:20]],
  29.                             },
  30. .... etc

Despite having my variable SVData being registered as being the Data table in the file traversing SVData grabs the whole table tree.

eg:

SVData[zone][item][values] cannot be traversed by doing pairs(SVData) as the first value that appears is not the zone values or even the data value. Instead it shows up Default then account etc. I ended up writing a function to generate a table just containing the data I need for display purposes.

This is an example of how I generated the data element of the table so I could search through it.
Lua Code:
  1. local function UpdateHarvestHistory()
  2.     harvestHistory = {}
  3.     for default,sv in pairs(XrysGatherer_SavedVariables) do
  4.         for account,accountv in pairs(sv) do
  5.             for accountWide,acWideV in pairs(accountv) do
  6.                 for index,data in pairs(acWideV) do
  7.                     if index == "Data" then
  8.                         table.insert(harvestHistory,data )
  9.                     end
  10.                 end
  11.             end
  12.         end
  13.     end
  14. end

This is the only way I was able to consistently access the data using the for/pairs functions.

Also, although I am not 100% sure of it, but I believe the local variable you set up to write to the saved variable table can be cleared for each gaming session so that individual game sessions will not be storing a massive table in memory apart from your actual global saved variables table.

I initialise my addon table as such:
SVData = ZO_SavedVars:NewAccountWide(addonSV, 1, "Data", SVDefault)
where addonSV = "XrysGatherer_SavedVariables" and SVDefault is an empty table by default.

Now, when I set SVData = {} at the start of the addon and when player activated I thought it was forcing a clear of the data table. Apparently not as I definitely recall still having my data available and accessible via XrysGatherer_SavedVariables, and it didn't wipe the data out on log out, from memory, it just cleared the sessions version of the data.

So, and I suppose some further testing should really be done to be sure, I suspect the SVData variable set up to create the saved variables is really a session table that updates the Saved variables table on log out. Unlike wow where it seems to be a link to the same data. This could be useful if I wasn't imagining it as it could mean that you have access to session data as well as all data.

Hopefully I haven't confused things further but this almost fried my brain during the beta weekends trying to get this all to work rofl.
  Reply With Quote
04/02/14, 07:47 PM   #7
Vuelhering
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 169
Originally Posted by Seerah View Post
Not at all. Saved variables get written to the file upon reload our logout, just like in WoW.
Ah lol, so it'll write out just due to the text file and "## SavedVariables:" keyword?

I'll take a look if this doesn't work right. Thanks.
  Reply With Quote
04/02/14, 09:36 PM   #8
Vuelhering
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 169
Originally Posted by Xrystal View Post
Now, when I set SVData = {} at the start of the addon and when player activated I thought it was forcing a clear of the data table. Apparently not as I definitely recall still having my data available and accessible via XrysGatherer_SavedVariables, and it didn't wipe the data out on log out, from memory, it just cleared the sessions version of the data.
Yep, I just verified this.
  Reply With Quote
04/11/14, 09:38 PM   #9
Xrystal
caritas omnia vincit
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 369
Okay, I've been working on the saved variables some more today so that I can get a way to import data, delete duplicates, wipe whole segments etc but still have the information accessible as normal without the need to log out ( except in the case of importing another file if importing several at a time ).

Anyways, the picture attached shows the output from the following traversal function ( which won't work under normal circumstances so have to pull some strings ).

This function only goes as far as the first useful set of information that is used to write to the saved variables using the table that you set up at the beginning.

EG. Normally I would write something along the lines of table.insert(SVData[zone][item],{ ... etc ... }). I had to set my saved vars to the Data subtable so that I knew when I got to the information I wanted.

Lua Code:
  1. local function CheckSavedVars()
  2.     for default,sv in pairs(XrysGatherer_SavedVariables) do
  3.         ChatMsg:AddMessage("Default: "..tostring(default).." "..tostring(sv).." "..tostring(type(sv)))
  4.         for account,accountv in pairs(sv) do
  5.             ChatMsg:AddMessage("Account: "..tostring(account).." "..tostring(accountv).." "..tostring(type(accountv)))
  6.             for accountWide,acWideV in pairs(accountv) do
  7.                 ChatMsg:AddMessage("AcWide: "..tostring(accountWide).." "..tostring(acWideV).." "..tostring(type(acWideV)))
  8.                 for index,data in pairs(acWideV) do
  9.                     ChatMsg:AddMessage("Data/Version: "..tostring(index).." "..tostring(data).." "..tostring(type(data)))
  10.                     if index == "Data" then
  11.                         for i,v in pairs(data) do
  12.                             ChatMsg:AddMessage("Contents: "..tostring(i).." "..tostring(v).." "..tostring(type(v)))
  13.                         end
  14.                     end
  15.                 end
  16.             end
  17.         end
  18.     end
  19. end

In short the results were along the lines of what I was seeing happening but it is nice to get confirmation in writing.

The SavedVariables table actually stores both the values imported into memory when you first log in and the values added via the SVData table after it is initialised that session. I am assuming the ZO_SavedVars object knows what to do when you want to look at the data via SVData as it has access to both old and new data if accessed directly but you can't traverse it like you can the original table.

The first block of "Data" tables is your existing data and the second block of "Data" tables are your current session data. Handy for those addons that may want to keep track of session records. Yes, it has given me ideas for another feature, in between my work on the map pins.

Just something for your brains to tick over.

The question is whether this knowledge helps me with my current saved variable update problems.

edit:
Ah, now I see why I was getting confused with lack of information before. My harvestHistory extraction routine is automatically grabbing both the full data and the session data, not realising that both loads of data are in the table. It also explains why it is not letting me clear all the data I was expecting when I tell it to clear. It's because the stuff it isn't clearing is the current sessions data. Looks like 0.0.9 will be a little while longer before it's update.

edit2:
Actually after a few logins and reloads between test runs of my debug code and it seems there is no specific order to the data, just that there are multiple blocks of the Account Data table. One for all data ( or just what was loaded ) and one for the current session possibly. Although for some reason it is letting me delete certain data but not all data. Must be something else that decides what gets kept and what doesn't during the session manipulation of the saved variables.

edit3:
Scratch that. Looks like it must have been due to some dodgy account ID due to the import tests I was doing. So more tests to see if I can get the same corruption to happen again.
Attached Thumbnails
Click image for larger version

Name:	Screenshot_20140412_042136.jpg
Views:	799
Size:	646.9 KB
ID:	118  

Last edited by Xrystal : 04/11/14 at 11:15 PM.
  Reply With Quote

ESOUI » Developer Discussions » General Authoring Discussion » two questions about saved variables


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off