Thread Tools Display Modes
08-30-12, 12:20 PM   #1
Aanson
A Flamescale Wyrmkin
Join Date: Aug 2009
Posts: 124
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.
__________________
__________________
  Reply With Quote
08-30-12, 01:19 PM   #2
Jarod24
A Theradrim Guardian
AddOn Author - Click to view addons
Join Date: Jul 2012
Posts: 66
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.

..
## 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.
__________________
Author of IfThen, Links in Chat
  Reply With Quote
08-30-12, 01:27 PM   #3
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
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.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 12-12-15 at 12:07 PM.
  Reply With Quote
08-30-12, 02:21 PM   #4
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by Jarod24 View Post
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
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.

Last edited by Phanx : 12-16-15 at 01:13 AM.
  Reply With Quote
11-23-14, 01:10 PM   #5
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
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
  Reply With Quote
11-24-14, 06:47 PM   #6
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Please don't quote an entire 100+ line post, especially if it's the last post in the thread.

Originally Posted by cokedrivers View Post
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
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.

Last edited by Phanx : 11-24-14 at 06:51 PM.
  Reply With Quote
11-25-14, 08:54 PM   #7
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Thank You Phanx for all you knowledge and wisdom with wow and lua.

Coke
  Reply With Quote
12-12-15, 11:28 AM   #8
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
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.
  Reply With Quote
12-12-15, 12:20 PM   #9
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Originally Posted by Resike View Post
Originally Posted by Phanx View Post
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
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
12-12-15, 01:10 PM   #10
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by SDPhantom View Post
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.
  Reply With Quote
12-12-15, 02:41 PM   #11
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
No, that returns "nil".
__________________
Grab your sword and fight the Horde!
  Reply With Quote
12-12-15, 04:14 PM   #12
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Lombra View Post
No, that returns "nil".
Oh, sneaky...
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Saved Variables

Thread Tools
Display Modes

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