ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   Tutorials & Other Helpful Info (https://www.esoui.com/forums/forumdisplay.php?f=172)
-   -   Adding new option while keeping SavedVars (https://www.esoui.com/forums/showthread.php?t=9608)

Saenic 03/07/21 07:15 AM

Adding new option while keeping SavedVars
 
Heya,

I've got an addon which uses SavedVariables. Now I want to add a new variable to the SavedVars and have the users keep their old settings.

Example old variables
Code:

defaults = {
    useDummy = false,
    startValue = 500
}

db = ZO_SavedVars:NewAccountWide("MyAddon_SavedVars", 1, nil, defaults)

Example new variables
Code:

defaults = {
    useDummy = false,
    startValue = 500,
    beAwesome = true
}

db = ZO_SavedVars:NewAccountWide("MyAddon_SavedVars", 1, nil, defaults)

And then I use the db variable with LibAddonMenu-2.0

When I give the new version to a user with old SavedVars they get an error. When I reinstall it, it works.
So for existing users the db variable does not include the new beAwesome value.

I have read about SavedVariables versioning here here https://www.esoui.com/forums/showthr...avedVars%3ANew
But then you would overwrite all existing SavedVars which is not what I want.

Is there a way to add a new variable and keep the old user settings?

Baertram 03/07/21 07:28 AM

The SV always keep old data until you change the sv version (1 in your case) to something else, or you totally change the SV type (e.g. ZO_SavedVars:NewAccountWide -> :NewCharacterIdSettings).
You are not overwriting them if you just add new valus. This should work pretty well if you do not try to access values too early, or got other errors in your code (before e.g.).

Explanation:
After assigning db = ZO_SavedVars: ... the SV are kept in the game memory (table db) until a reloadui/logout is done. At this time the db entries will be written to the disk live/SavedVariables/<yourAddonsTXTFileName>.lua.

The "default" values are used if the SV are missing (after a fresh install e.g.). Else the data read form the SV lua file will be read into the table db and ONLY those are used. So adding values to the defaults that were not there before is the way to add new settings, correct. They will mix in between the data from the disk (lua file -> read into table db in memory).
But if you try to access the new variables before the ZO_SavedVars are created this might throw an error (liek accessing db.??? before db = ZO_SavedVars:NewAccountWide was done).

btw: If you create new addons think about adding savedvariables support for several servers (live eu, live na, pts) directly from the start (if you think settings of your addon should save differently for the same account on different servers). Could be an advantage or disadvantage.
You can use the last parameter "profile" of ZO_SavedVars:NewAccountWide / ZO_SavedVArs:NewCharacterIdSettings for that purpose by passing in GetWorldName() -> This will retun the server name string, e.g. "NA Megaserver" or "EU Megsaver" or "PTS".
https://wiki.esoui.com/AddOn_Quick_Q...cal_machine.3F


Without getting your total code and the error message with the total details (expand it via the checkbox) we can only assume what is wrong in your code.
Please provide the data.

Sharlikran 03/07/21 11:42 AM

What I basically use now
lua Code:
  1. function MasterMerchant:Initialize()
  2.   local systemDefault = {
  3.     <<stuff>>
  4.   }
  5.   self.systemSavedVariables = ZO_SavedVars:NewAccountWide('ShopkeeperSavedVars', 1, nil, systemDefault, nil, 'MasterMerchant')
  6.   <<stuff>>
  7. end
The last part is what the previous author put so I can't remove it. It would work the same as.
lua Code:
  1. function MasterMerchant:Initialize()
  2.   local systemDefault = {
  3.     <<stuff>>
  4.   }
  5.   self.systemSavedVariables = ZO_SavedVars:NewAccountWide('ShopkeeperSavedVars', 1, nil, systemDefault)
  6.   <<stuff>>
  7. end

What is odd about what you are sharing, I don't have any issues adding a new value to the systemDefault table. In fact I loop over the table used by the saved vars to remove the old unused values.

Saenic 03/07/21 12:58 PM

Thanks Baertram and Sharlikran for the quick reply. I understand now that it uses the defaults only when there is no SavedVar entry.

The error my friend had was caused by an older version of LibAddonMenu in a subfolder of another addon :rolleyes:

Sharlikran 03/07/21 02:09 PM

That is good to know I appreciate that. Sometimes people say we figured it out thanks, yet there was no reason or solution presented.

Because I approach things a little more black and white when it comes to programming I do still have my concern that circumstances with which the user resolved their situation is a false positive.

Meaning that the behavior that you reported shouldn't occur (or at least doesn't occur for me) and having a conflict between different versions of the same Library shouldn't be the solution.

Baertram 03/07/21 02:13 PM

Thanks for the feedback Saenic. Glad you found the cause.

For the future: At best provide the code of the addon you are working on in total somewhere (github, dropbox, gist, etc.) and post the error message in total as well (expanded so one can see what variables were at what state as the error happened). It's much faster and easier to see if there is anything nil because of a any typo, scope or other error, and it's much easier to help (instead of guessing).

Shadowfen 03/07/21 10:31 PM

I use a function from my LibSFUtils library, called LibSFUtils.defaultMissing(). You pass in the saved variable table and the defaults table and it recurses down the defaults table looking for values that are not in the saved variable table. When a variable:value is found to be missing, it is put into the saved variable table. If there is a variable already in the saved variable table, then its value is left untouched.

My typical usage is:
Code:

    local save = ZO_SavedVars:NewAccountWide(savedvar, sv_version, nil, defaults)
    LibSFUtils.defaultMissing(savedvar, defaults)  -- adds in new variables in old savevars


Baertram 03/08/21 02:14 AM

Quote:

Originally Posted by Shadowfen (Post 43364)
I use a function from my LibSFUtils library, called LibSFUtils.defaultMissing(). You pass in the saved variable table and the defaults table and it recurses down the defaults table looking for values that are not in the saved variable table. When a variable:value is found to be missing, it is put into the saved variable table. If there is a variable already in the saved variable table, then its value is left untouched.

My typical usage is:
Code:

    local save = ZO_SavedVars:NewAccountWide(savedvar, sv_version, nil, defaults)
    LibSFUtils.defaultMissing(savedvar, defaults)  -- adds in new variables in old savevars


Ist't the standard defaults of ZO_SavedVars doing the same?
I mean if I just add an entry to a default table which is used in my SavedVars already it will be added if it did not exist (was nil in the disk file) before upon login/reloadui.

Did test this today (PTS), works fine without any manual effort or funcitons to check and do code, but I'm pretty sure it always worked that way.

Shadowfen 03/08/21 03:42 PM

Quote:

Ist't the standard defaults of ZO_SavedVars doing the same?
I mean if I just add an entry to a default table which is used in my SavedVars already it will be added if it did not exist (was nil in the disk file) before upon login/reloadui.
It does in the very simplest of cases - which you tested.

If you have a table in your saved variables and you add a new value inside of that table, then the simple ZOS default does not work - because it does not recurse into subtables to check there as well. It says yeah, subtable_a exists and does not bother to look if subtable_a["whatever"] exists.

Baertram 03/09/21 06:04 AM

Oh right, understood. Thanks!


All times are GMT -6. The time now is 06:47 AM.

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