WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Saved Variables (https://www.wowinterface.com/forums/showthread.php?t=44038)

Aanson 08-30-12 12:20 PM

Saved Variables
 
Hey guys, again I'm looking for a little guidance and/or a point in the right direction. I'm always very willing to put the work in and read and learn so a simple pointer to a tutorial etc would be great as well.

I've got to the stage now with my addon where I'd like to start saving variables to disk so that settings will be set between sessions.

Could someone possibly take out a few mins to write a short list of what needs to be done.

I think I need the logical order of things so that I can try to get it right in my head; I always find that that makes it easier for me to absorb the information.

PS: A big thank you to the authors who have been kind enough to answer my previous questions.


Aanson.

Jarod24 08-30-12 01:19 PM

All variables that you want to save must be named in you .TOC file under the SavedVariables section
Toc file info: http://www.wowwiki.com/TOC_format

Blizzard saves the settings in a lua file with you addon name in the WTF folder.

Quote:

..
## SavedVariables: MyVarA, MyVarB
## SavedVariablesPerCharacter: somePercharVariable
Blizzard will load and replace the variable with the saved settings.
There is a few events to tell you when this has happened. It will be done loading when ADDON_LOADED has fired.


I suggest using a table and save settings inside the table like keys. That way you minimize what you need to change when you add more settings or even remove them.

maybe something like this. just a suggestion, but its not needed.

Lua Code:
  1. MyAddonSettings = {};
  2. MyAddonSettings["Debug"] = true;
  3. MyAddonSettings["Setting1"] = false;
  4. MyAddonSettings["Playername"] = "Bob";

there are also some libraries (ace?) to do this for you.

SDPhantom 08-30-12 01:27 PM

Saved Variables are first defined in the TOC file. This tells WoW which globals to save for your addon when the user logs out.

TOC:
Code:

## SavedVariables: Global_Name
## SavedVariablesPerCharacter: Global_Name

It's pretty straightforward what each line does. The first is used to register the global Global_Name to be saved account-wide. The second does this just for the character you logged on. That's only half of it as you need to define the global in Lua too just like any other variable. The only difference is WoW saves the variable and fires PLAYER_LOGOUT when logging out or reloading UI. Saved data if any is available when ADDON_LOADED fires for your addon.

Phanx 08-30-12 02:21 PM

Quote:

Originally Posted by Jarod24 (Post 261226)
there are also some libraries (ace?) to do this for you.

Especially for something as simple as defining a saved variable, I would recommend avoiding the use of libraries until you have a decent understanding of how the system actually works first. Then, if you want to use a library for some reason (eg. to make it easier to manage separate settings profiles), it won't be a black box.

Here is the simple system I use for managing default settings in my addons:

In MyAddon.toc:
Code:

## SavedVariables: MyAddonDB
In MyAddon.lua:
Code:

-- This function gets run when the PLAYER_LOGIN event fires:
function MyAddonDB:PLAYER_LOGIN()
        -- This table defines the addon's default settings:
        local defaults = {
                x = 0,
                y = 200,
                p = "BOTTOM",
                font = {
                        face = "Friz Quadrata TT",
                        size = 14,
                        outline = "OUTLINE",
                },
                color = {
                        r = 0,
                        g = 1,
                        b = 1,
                }
        }

        -- This function copies values from one table into another:
        local function copyDefaults(src, dst)
                -- If no source (defaults) is specified, return an empty table:
                if type(src) ~= "table" then return {} end
                -- If no target (saved variable) is specified, create a new table:
                if not type(dst) then dst = {} end
                -- Loop through the source (defaults):
                for k, v in pairs(src) do
                        -- If the value is a sub-table:
                        if type(v) == "table" then
                                -- Recursively call the function:
                                dst[k] = copyDefaults(v, dst[k])
                        -- Or if the default value type doesn't match the existing value type:
                        elseif type(v) ~= type(dst[k]) then
                                -- Overwrite the existing value with the default one:
                                dst[k] = v
                        end
                end
                -- Return the destination table:
                return dst
        end

        -- Copy the values from the defaults table into the saved variables table
        -- if it exists, and assign the result to the saved variable:
        MyAddonDB = copyDefaults(defaults, MyAddonDB)
end


cokedrivers 11-23-14 01:10 PM

Quote:

Originally Posted by Phanx (Post 261244)
Especially for something as simple as defining a saved variable, I would recommend avoiding the use of libraries until you have a decent understanding of how the system actually works first. Then, if you want to use a library for some reason (eg. to make it easier to manage separate settings profiles), it won't be a black box.

Here is the simple system I use for managing default settings in my addons:

In MyAddon.toc:
Code:

## SavedVariables: MyAddonDB
In MyAddon.lua:
Code:

-- This function gets run when the PLAYER_LOGIN event fires:
function MyAddonDB:PLAYER_LOGIN()
        -- This table defines the addon's default settings:
        local defaults = {
                x = 0,
                y = 200,
                p = "BOTTOM",
                font = {
                        face = "Friz Quadrata TT",
                        size = 14,
                        outline = "OUTLINE",
                },
                color = {
                        r = 0,
                        g = 1,
                        b = 1,
                }
        }

        -- This function copies values from one table into another:
        local function copyDefaults(src, dst)
                -- If no source (defaults) is specified, return an empty table:
                if type(src) ~= "table" then return {} end
                -- If no target (saved variable) is specified, create a new table:
                if type(dst) then dst = {} end
                -- Loop through the source (defaults):
                for k, v in pairs(src) do
                        -- If the value is a sub-table:
                        if type(v) == "table" then
                                -- Recursively call the function:
                                dst[k] = copyDefaults(v, dst[k])
                        -- Or if the default value type doesn't match the existing value type:
                        elseif type(v) ~= type(dst[k]) then
                                -- Overwrite the existing value with the default one:
                                dst[k] = v
                        end
                end
                -- Return the destination table:
                return dst
        end

        -- Copy the values from the defaults table into the saved variables table
        -- if it exists, and assign the result to the saved variable:
        MyAddonDB = copyDefaults(defaults, MyAddonDB)
end


How would you use these defaults in your addon would it be MyAddonDB.x ?

of would this function replace your:
Code:

local cfg = MyAddonDB.defaults

MyFrame = CreateFrame("frame")
MyFrame:SetPoint(cfg.p, UIParent, cfg.x, cfg.y)

The reason I ask is I would like to get away from Ace for some of the addons im working on and if this will alow me to have a defaults like ace does then the only othe part Ill have to figure out is in-game config to change things without doing a /reload.

Thanks Coke

Phanx 11-24-14 06:47 PM

Please don't quote an entire 100+ line post, especially if it's the last post in the thread. :(

Quote:

Originally Posted by cokedrivers (Post 300975)
How would you use these defaults in your addon would it be MyAddonDB.x ?

Yes. The defaults are just that -- default values. They should only be used to initialize the db table; you should never be referring to values in the defaults table or applying them to things in your addon. If you're currently doing this with AceDB:

Code:

local defaults = {
    global = {
          point = "TOP",
          x = 0,
          y = -100,
    }
}

local db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
local cfg = db.global

SomeFrame:SetPoint(cfg.point, cfg.x, cfg.y)

Then using the method in my last post you would do this instead:

Code:

local defaults = {
    point = "TOP",
    x = 0,
    y = -100,
}

MyAddonDB = copyDefaults(defaults, MyAddonDB)
local cfg = MyAddonDB

SomeFrame:SetPoint(cfg.point, cfg.x, cfg.y)

However, if you want to offer profile support, I'd suggest you just continue using AceDB.

Also, this thread is very old. I suggest you check this more current one instead:
http://forums.wowace.com/showthread.php?t=21864

cokedrivers 11-25-14 08:54 PM

Thank You Phanx for all you knowledge and wisdom with wow and lua.

Coke

Resike 12-12-15 11:28 AM

I know this thread is pretty old, but i would like to correct a major error with Phanx'es code, which is probably just a typo:

Lua Code:
  1. if not type(dst) then
  2.     dst = { }
  3. end

If the not is not there it will auto reset your settings to the default one every time you log in.

SDPhantom 12-12-15 12:20 PM

Quote:

Originally Posted by Resike (Post 312251)
Quote:

Originally Posted by Phanx (Post 261244)
Code:

        -- This function copies values from one table into another:
        local function copyDefaults(src, dst)
                -- If no source (defaults) is specified, return an empty table:
                if type(src) ~= "table" then return {} end
                -- If no target (saved variable) is specified, create a new table:
                if type(dst) then dst = {} end
                -- Loop through the source (defaults):
                for k, v in pairs(src) do
                        -- If the value is a sub-table:
                        if type(v) == "table" then
                                -- Recursively call the function:
                                dst[k] = copyDefaults(v, dst[k])
                        -- Or if the default value type doesn't match the existing value type:
                        elseif type(v) ~= type(dst[k]) then
                                -- Overwrite the existing value with the default one:
                                dst[k] = v
                        end
                end
                -- Return the destination table:
                return dst
        end


I know this thread is pretty old, but i would like to correct a major error with Phanx'es code, which is probably just a typo:

Lua Code:
  1. if not type(dst) then
  2.     dst = { }
  3. end

If the not is not there it will auto reset your settings to the default one every time you log in.

type() always returns a string no matter what you give it. This means using it directly as a conditional will always return true and using not on it will always return false. The correction on this should be the following.
Code:

if type(dst) ~= "table" then dst = { } end

Resike 12-12-15 01:10 PM

Quote:

Originally Posted by SDPhantom (Post 312252)
type() always returns a string no matter what you give it. This means using it directly as a conditional will always return true and using not on it will always return false. The correction on this should be the following.
Code:

if type(dst) ~= "table" then dst = { } end

If dst is nil then type(dst) will also return nil.

But of course the ~= "table" checker could be better.

Lombra 12-12-15 02:41 PM

No, that returns "nil".

Resike 12-12-15 04:14 PM

Quote:

Originally Posted by Lombra (Post 312254)
No, that returns "nil".

Oh, sneaky...


All times are GMT -6. The time now is 10:18 AM.

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