Thread Tools Display Modes
02-23-09, 07:02 AM   #1
Zimran
A Deviate Faerie Dragon
AddOn Author - Click to view addons
Join Date: Feb 2008
Posts: 11
Yet another SavedVariables question...

I've searched and looked at other mods and just can't figure this one out. I'm sure I'm just being dense (as per usual). This is my code:

Code:
local addon = CreateFrame("Frame")

addon:RegisterEvent("ADDON_LOADED")
addon:SetScript("OnEvent", function(self, event, addon)
	if addon ~= "MyAddon" then return end
	if event == "ADDON_LOADED" then
		MyAddonDB = MyAddonDB or {
			Setting = true,
		}
		self:UnregisterEvent(event)
	end
	print(tostring(MyAddonDB.Setting))  -- this prints "true"
end)

print(tostring(MyAddonDB.Setting)) -- this gives an error
The error is "attempt to index global 'MyAddonDB' (a nil value)".

It seems like the print statement outside of the OnEvent function is executing before the database has been created / initialized. If this is indeed the problem then how can I ensure that the database is available to the rest of the addon? I tried creating a function and calling it from the OnEvent function and this works but it's not really what I'd like.

Any assistance is most appreciated and any other constructive comments on the code and how / why I can do something better is also welcome.

Thanks, Zim

Last edited by Zimran : 02-23-09 at 07:06 AM. Reason: Typo
  Reply With Quote
02-23-09, 07:21 AM   #2
Mera
Retired of WoW, In ESO :)
 
Mera's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Apr 2008
Posts: 331
you have the solution yourself this is because you call it outside the entry function that is supposed to delay your mod correctly
__________________
If you need to reach me I'm in ESO, @class101 or "Fathis Ules i"
addons: SpamBayes, BrokerCPU
projects: ThunderBayes
Mera[xeh]? - La CroisadeEcarlate (wow)
  Reply With Quote
02-24-09, 05:16 AM   #3
ZikO
An Aku'mai Servant
Join Date: Jun 2008
Posts: 36
Post

I believe WoW using lua as interpreter read all lua files indicated in *.toc file (as well as XML file if it's there too) before any events have been fired. If there are also commands as well as assignments like
Code:
print()
local aaa = "bbb"
probably (im not sure yet it might be checked) these commands and assignment are executed immediately sometimes before any functions. Now as you have this line in your code:
Code:
print(tostring(MyAddonDB.Setting)) -- this gives an error
WoW does not know anything about MyAddonDB because your function:
Code:
addon:SetScript("OnEvent", function(self, event, addon)
has not been called yet, thus, has not executed these lines:
Code:
MyAddonDB = MyAddonDB or {
    Setting = true,
}
Thus, MyAddonDB = nil which means it does not exist in this particular time even if MyAddonDB is global.
  Reply With Quote
02-27-09, 10:42 PM   #4
eliljey
A Deviate Faerie Dragon
Join Date: Feb 2009
Posts: 14
The entire interface is event driven. Events are used to throttle the execution of code in order to ensure that things run when they're supposed to. Since your print statement is gated by an event or function call it tries to run it as soon as the addon is loaded, which is also when the saved vars are being pulled in. Thus you're trying to access a variable that does exist yet.

So to answer your question:
"If this is indeed the problem then how can I ensure that the database is available to the rest of the addon?"

That's what the various events are for. The main one of interest in this case is the ADDON_LOADED event. That is used to gate when you get access to saved variables by ensuring that the addon has finished loading them and everything has been initialized. Any code you want to run that requires variables or whatever needs to be gated by at least this event if not others.
  Reply With Quote
03-02-09, 08:13 AM   #5
IBLJerry
A Deviate Faerie Dragon
AddOn Author - Click to view addons
Join Date: Dec 2006
Posts: 12
The addon loading process of the client is as follow:
  • (Load all dependencies, if needed)
  • Load, parse and execute all XML and lua files listed in the TOC, in order.
  • Load the SavedVariables files, if needed
  • Broadcast the ADDON_LOADED event for this addon to the UI
  • (Load all addons that are declared as LoadWith for this addon)

If your TOC is like this:
Code:
## SavedVariables: MyAddonDB

main.lua
And your main.lua file is like this:
Code:
MyAddonDB = {
  count = 0,
}

local function test ()
   print (MyAddonDB.count)
   MyAddonDB.count = MyAddonDB.count + 1
end

test()

local f = CreateFrame"Frame"
f:SetScript("OnEvent", function (self, event, addon)
    if addon == "MyAddon" then
        test()
    end
end)
f:RegisterEvent"ADDON_LOADED"
The first time the addon is loaded, it will print "0" then "1"
The second time the addon is loaded, it will print "0" then "2"!

Why ?

The first time, the SavedVariables file is empty, and thus the "MyAddonDB" file is not overwritten.
The second time, the SavedVariable file exists, with a count of 2, so the "MyAddonDB" variable is overwritten by the one in this file.
Of course, when saving the variables after the second run, MyAddonDB.count is 3, so the next time the addon is loaded, it will print "0" then "3".
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Yet another SavedVariables question...


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