Thread Tools Display Modes
11-14-12, 03:36 PM   #1
Elderin
A Deviate Faerie Dragon
Join Date: Nov 2012
Posts: 17
Accessing Global Data

Let me begin by stating that I have a MyAddon.xml file and a MyAddon.lua file that are properly aware of and function correctly with each other. Additionally, the xml file defines the UI and the lua file contains needed functions, variables, etc.

My assumption: The names of Frame and FontString entities which are defined in my xml file are available as global variables.

The answer to my question is more likely about convention. It seems that within the lua file, after things are loaded, etc., I can access the Frame objects or Fontstring objects directly by name and perform associated functions such as shown below:
Code:
in xml
<FontString inherits="GameFontNormal" name="MyFontStr_1" text="Title x">
...
</FontString>

in lua file
MyFontStr_1:SetText("Title One");
_G.MyFontStr_1:SetText("Title One");
_G["MyFontStr_1"]:SetText("Title One");
getglobal("MyFontStr_1"):SetText("Title One");
I am aware that the _G methods seem to be replacements for getglobal(). And, I also see that using any of the last three allows me to dynamically create the name of the object
Code:
local x = 1;
_G["MyFontStr_"..x]:SetText("Title "..x);
It appears that the four methods shown all change the text value of the FontString object. The question is: Functionaly, are there any differences? Any reason to use one over the other? Or, is it just whatever I myself am comfortable with?

While I have used a FontString as the example of my question, I also assume that these different approachs could be applied to any of the global data that is present at run time.
  Reply With Quote
11-14-12, 04:12 PM   #2
Dridzt
A Pyroguard Emberseer
 
Dridzt's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2005
Posts: 1,360
Unless you are trying to modify/revive an existing addon in which case you may want to avoid an extensive re-write,
it's best if you use the frame manipulation API both to create and script your frames from lua, without using xml.

As to your actual question.
#4 is deprecated and should not be used (it means Blizzard can disable it at their convenience since they've warned it's to be phased out)
#3 and #2 are equivalent, the difference is only in style as long as the key to the table is a contiguous string.
If you had spaces in the name then table["two words"] needs to be used t.two words will not work.
#1 makes an implicit lookup in the global table but is otherwise the same as #2 and #3.
  Reply With Quote
11-14-12, 05:30 PM   #3
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,323
Originally Posted by Elderin View Post
Code:
MyFontStr_1:SetText("Title One");
_G.MyFontStr_1:SetText("Title One");
_G["MyFontStr_1"]:SetText("Title One");
getglobal("MyFontStr_1"):SetText("Title One");
Originally Posted by Dridzt View Post
#1 makes an implicit lookup in the global table but is otherwise the same as #2 and #3.
As stated, #2 and #3 are exactly the same in both function and performance, however #1 is faster since it only requires a single index operation. #2 and #3 have to index _G from the global environment, which is a reiteration of itself, then index MyFontStr_1 from the resulting table. This requires 2 indexing operations and is therefore much slower in comparison. Note the number of indexing operations are measured before the processing of FontString:SetText(), which adds a couple more indexing operations to it (one to check the FontString table and the other to default into its metatable).

To break down the use of each, #1 is best if you need to access just one object directly. #3 would be for dynamically accessing from a list of objects in which you need to apply values to a name in order to construct it. #2 has no practical use. It has nothing more to offer than #1 and uses up more CPU to process for the same result.
__________________
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 : 11-14-12 at 05:40 PM.
  Reply With Quote
11-14-12, 05:40 PM   #4
Elderin
A Deviate Faerie Dragon
Join Date: Nov 2012
Posts: 17
Thanks, all.

Originally Posted by Dridzt View Post
Unless you are trying to modify/revive an existing addon in which case you may want to avoid an extensive re-write, it's best if you use the frame manipulation API both to create and script your frames from lua, without using xml.
It seems like I read somewhere that Blizz preferred UI definitions in the separate xml file. However, most books on addons are relatively few and older now. I recently read on a forum that it was considered better and more elegant to do it all in lua now. When it comes to coding, I am all about elegant. However, I am currently working on a project based on a quite old addon long since not supported. And so, trying not to do a complete rewrite even though much does not resemble the original stuff and so far, I have added a lot. Perhaps my next iteration will be doing away with the xml file.

Thanks, again, guys.

Last edited by Elderin : 11-14-12 at 05:43 PM.
  Reply With Quote
11-14-12, 05:52 PM   #5
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
Right - Blizz prefers to do it that way. But they don't care how you do it.

The only time you really need XML is if you are defining a template to use and a frame-factory type function won't suffice.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
11-14-12, 09:53 PM   #6
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,323
Most people prefer to use Lua over XML. I really don't see any proof either way on long term performance impacts. The idea was that XML was for static UI structures while you'd use Lua for creating dynamic frames. With nearly everything being supported in Lua, pretty much everyone has phased out XML. I think the tree-like XML structure is easier to read and understand in this fashion than lines of linear Lua code. That's just my preference though. It's up to you to decide which way you want to go.
__________________
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
11-15-12, 02:09 AM   #7
Vlad
A Molten Giant
 
Vlad's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 793
Shame we can't write templates using lua.
__________________
Profile: Curse | Wowhead
  Reply With Quote
11-15-12, 02:15 AM   #8
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
The biggest problem with XML is that it's incredibly verbose, and is just a hassle to write by hand.

Also, using XML, all references must be global, which is another big argument against it. While in Lua you can write:

Code:
local f = CreateFrame("Frame")
f:RegisterEvent("ADDON_LOADED")
f:SetScript("OnEvent", MyAddOn.EventHandler)
... if you're using XML, you have to create 1-3 globals and 1-2 functions to achieve the same thing.

Firstly, you have to give the frame a global name, or you won't be able to access it from your Lua code.

Secondly, you have to create an anonymous function to register the event in an OnLoad script, or a global function to be assigned as the OnLoad script.

Finally, you either have to make MyAddOn.EventHandler a global function outside of the MyAddOn table (eg. instead of function MyAddOn:EventHandler() ... end you'd need function MyAddOn_EventHandler(MyAddOn) ... end) or double up on function calls by creating another anonymous wrapper function:

Code:
<Frame name="SomeGlobalSpam">
	<Scripts>
		<OnLoad>
			self:RegisterEvent("ADDON_LOADED")
		</OnLoad>
		<OnEvent>
			MyAddOn:EventHandler(event, ...)
		</OnEvent>
	</Scripts>
</Frame>
__________________
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.
  Reply With Quote
11-14-12, 04:13 PM   #9
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
You shouldn't use getglobal(), as it's not only deprecated but is now actually a function-wrapper around _G and is thus actually slower due to the overhead of the function call.

The rest are functionally equivalent, the main difference being syntactic sugar. The only time I use _G["whatever"] is when I am passing in an unknown string (as through a function parameter) or constructing a string; otherwise I use _G.whatever.

Edit: Damn it, Dridzt!
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
11-14-12, 04:16 PM   #10
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
The getglobal function is deprecated and shouldn't be used for anything. In terms of performance you're essentially looking up "getglobal" in _G in the first place, then the overhead of a function call plus another lookup in _G for whatever you're trying to access.

I personally just use the variable name when I need to access it with two exceptions. If I have a variable with the same name in a more local scope and need to get to the global I would use _G["var"], and if I need to dynamically create the variable name I could concatenate the key together.

_G.var is just syntactic sugar for _G["var"].
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Accessing Global Data

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