Thread Tools Display Modes
01-28-10, 12:51 PM   #1
Amenity
Guest
Posts: n/a
Addon file system structuring

I'm sure this has probably come up at some point but I couldn't find anything on it in my searches...so sorry if this is oft-repeated.

Hypothetical scenario: I've got a clock addon. Due to my anal-retentiveness, it's separated into the following files:

clock.lua --All the frames & appearance-related stuff defined here.

thingus.lua --The actual timing function.

clock.toc --Self-explanatory.


1. Is there any reason not to do this?

2. When loading multiple Lua files in a single addon, are they simply appended to the preceeding file in-order as defined in the ToC? Or are they handled as "separate addons"? Example with two files:

Code:
local thingus = somevalue
Code:
function dostuff(when)
    print(thingus)
end
Will that toss an error? Or is the second file appended to the end of the first, making thingus a defined value for the dostuff function?

3. Assuming an addon of considerable size, is it better to have many small files or a few/one large file?

4. Assuming file structure "matters", how does directory structure factor into this?

Thanks in advance!

Last edited by Amenity : 01-28-10 at 12:54 PM.
  Reply With Quote
01-28-10, 12:57 PM   #2
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,925
They are loaded in the sequence listed in the TOC but local entities in one file can only be accessed via another file if there is a non lock function to grab them.

I have used that functionality with my LootAlerter addon with all the data in one file, common functions in another etc. The downside is that functions that you want to use outside of the file will mean they are in the public domain and naming conflicts could get in the way. The upside is that the code is separated for easier access to source data.

If the addon will be less than 500 or even more lines stick with just the one file to avoid the non local issue at least. If you do need them split up, try and find a way to maximize the use of the local option so that only what you need to be public is public and that it is unique to your addon enough for it not to get mixed up.

I've course that is just my view and understanding on things. I have always learning that local is good. The more localised the better.
__________________


Characters:
Gwynedda - 70 - Demon Warlock
Galaviel - 65 - Resto Druid
Gamaliel - 61 - Disc Priest
Gwynytha - 60 - Survival Hunter
Lienae - 60 - Resto Shaman
Plus several others below level 60

Info Panel IDs : http://www.wowinterface.com/forums/s...818#post136818
  Reply With Quote
01-28-10, 01:02 PM   #3
Rilgamon
Premium Member
 
Rilgamon's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 822
New file, new variables. Nothing is shared.
Last patch added an argument call to every file.
So there is a table you can use for all files and that
keeps values set in one file. I have an init.lua that I use
for nearly all new addons with something like this

Code:
local name, table = ...

if(name) then
  table.version = GetAddOnMetadata(name,"Version") or '0.0'
  table.author = GetAddOnMetadata(name,"Author") or '<Nobody>'
  table.appinfo = GetAddOnMetadata(name,"Notes-"..GetLocale()) or GetAddOnMetadata(name,"Notes") or '<No Info>'
  table.title = GetAddOnMetadata(name,"Title-"..GetLocale()) or GetAddOnMetadata(name,"Title") or name
  table.character = UnitName("player")
  table.crealm = GetRealmName()
  table.faction,_ = UnitFactionGroup('player')
end
__________________
The cataclysm broke the world ... and the pandas could not fix it!
  Reply With Quote
01-28-10, 01:06 PM   #4
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,925
Oh, not heard about that. So ... are the values contained in that table at that time ?

So I could keep my data separate and localized and it will be accessible in other files loaded after ? Or am I missing something ?
__________________


Characters:
Gwynedda - 70 - Demon Warlock
Galaviel - 65 - Resto Druid
Gamaliel - 61 - Disc Priest
Gwynytha - 60 - Survival Hunter
Lienae - 60 - Resto Shaman
Plus several others below level 60

Info Panel IDs : http://www.wowinterface.com/forums/s...818#post136818
  Reply With Quote
01-28-10, 02:25 PM   #5
Amenity
Guest
Posts: n/a
Originally Posted by Xrystal View Post
Oh, not heard about that. So ... are the values contained in that table at that time ?

So I could keep my data separate and localized and it will be accessible in other files loaded after ? Or am I missing something ?
I'm a bit confused myself. How exactly is that method any different from any other local variable generation in a previously-loaded file? Looks like you're just making a table. What am I missing?
  Reply With Quote
01-28-10, 02:31 PM   #6
p3lim
A Pyroguard Emberseer
 
p3lim's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2007
Posts: 1,710
The table is kinda a local global, for usage within any files of the addon in question.

No matter what file you add stuff to that table it will stick to all files.

Its very good to use for stuff like embedding and localization.
  Reply With Quote
01-28-10, 02:41 PM   #7
Shadowed
...
Premium Member
Featured
Join Date: Feb 2006
Posts: 387
It's a way of making your addon more self contained, before if you spread an addon out between multiple files you had to have a global somewhere.

Before you would have to do something like:

Code:
-- localization.enUS.lua
AddonLocals = {["foo"] = "foo"}

-- Addon.lua
local Addon = {}
local L = AddonLocals
Now you can do:

Code:
-- localization.enUS.lua
local Addon = select(2, ...)
Addon.L = {["foo"] = "foo"}

-- Addon.lua
local Addon = select(2, ...)
local L = Addon.L
It really just gives you cleaner syntax.
  Reply With Quote
01-28-10, 02:47 PM   #8
Amenity
Guest
Posts: n/a
Originally Posted by p3lim View Post
The table is kinda a local global, for usage within any files of the addon in question.

No matter what file you add stuff to that table it will stick to all files.

Its very good to use for stuff like embedding and localization.
Right, I understood that part. My sense of confusion is how it does this.

I think my confusion has to do with my ignorance of calling name as an argument to if. In other words, he's doing this:

Code:
local name, table = ...

if(name) then
    blahblahtablecrap
end
And I'm thinking this:

Code:
local name, table = ...

if name then
    blahblahtablecrap
end
I'm also assuming that ellipsis use in Lua is similar to C (i.e., "variable number of whatever").
  Reply With Quote
01-28-10, 02:53 PM   #9
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,925
Very interesting. So where is the original information on this as I can't see it in the UI forums 3.3 changes.

What other values are in ... From the looks of it the first argument is the addon's name and the second one is its global table. Any other information in there ?

So say in my localization.enUS.lua file I currently do this.
<MyAddon>Translator_L["DescriptiveName"] = "Translated Text"

And then in my main addon I would usually do something like this.
local _L = <MyAddon>Translator_L;
print(_L["DescriptiveName"])


Instead I can now do this ?
AddonData = select(2,...)
AddonData.Translator_L["DescriptiveName"] = "Translated Text"

AddonData = select(2,...)
local _L = AddonData.Translator_L;

As long as each file in that addon you want to update and/or use the addons data will need to add that first line each time? So in essence they have created a global table for all addons that are loaded on the system ? Whether or not the values are used ?
__________________


Characters:
Gwynedda - 70 - Demon Warlock
Galaviel - 65 - Resto Druid
Gamaliel - 61 - Disc Priest
Gwynytha - 60 - Survival Hunter
Lienae - 60 - Resto Shaman
Plus several others below level 60

Info Panel IDs : http://www.wowinterface.com/forums/s...818#post136818
  Reply With Quote
01-28-10, 02:55 PM   #10
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
The parentheses are unnecessary in the same manner as a semicolon is unnecessary - in most cases. Only when attempting to disambiguate (in the case of an if) or use all on one line (in the case of semicolon when using /script within WoW) are they necessary.
__________________
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
01-28-10, 03:10 PM   #11
Shadowed
...
Premium Member
Featured
Join Date: Feb 2006
Posts: 387
Originally Posted by Xrystal View Post
Very interesting. So where is the original information on this as I can't see it in the UI forums 3.3 changes.

What other values are in ... From the looks of it the first argument is the addon's name and the second one is its global table. Any other information in there ?

So say in my localization.enUS.lua file I currently do this.
<MyAddon>Translator_L["DescriptiveName"] = "Translated Text"

And then in my main addon I would usually do something like this.
local _L = <MyAddon>Translator_L;
print(_L["DescriptiveName"])


Instead I can now do this ?
AddonData = select(2,...)
AddonData.Translator_L["DescriptiveName"] = "Translated Text"

AddonData = select(2,...)
local _L = AddonData.Translator_L;

As long as each file in that addon you want to update and/or use the addons data will need to add that first line each time? So in essence they have created a global table for all addons that are loaded on the system ? Whether or not the values are used ?
It was in 3.3 so it should be there. First argument is the addons folder name, second is the table. Saying it's global isn't accurate thought, it's really just a local table that's shared between the files loaded in the addon folder. No other addon can access it short of adding their own file that is loaded from your TOC.

But yes, you could change it to that.
  Reply With Quote
01-28-10, 03:13 PM   #12
p3lim
A Pyroguard Emberseer
 
p3lim's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2007
Posts: 1,710
Originally Posted by Xrystal View Post
AddonData = select(2,...)
AddonData.Translator_L["DescriptiveName"] = "Translated Text"
Mind the local, else its just global again.
  Reply With Quote
01-28-10, 03:15 PM   #13
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,323
To better explain how WoW passes the new global vararg expression, I'm going to put up examples of before and after in context of function wrapping.

ToC File:
Code:
File1.lua
File2.lua
WoW 3.2:
Code:
local function File1()
-- File1.lua run as code chunk
end;
File1()

local function File2()
-- File2.lua run as code chunk
end;
File2()
WoW 3.3:
Code:
local function LoadAddOn(AddOnName)
	-- Note AddOnName contains the folder name of the addon
	local AddOnTable={};

	local function File1(...)
	-- File1.lua run as code chunk
	end;
	File1(AddOnName,AddOnTable)

	local function File2(...)
	-- File2.lua run as code chunk
	end;
	File2(AddOnName,AddOnTable)

	-- And so on...
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
01-28-10, 03:47 PM   #14
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,925
rofl, might have to play with it a bit to get full understanding of it

basically we can now have every variable local and that addon table will allow us access ? Or am I still confused ? rofl
__________________


Characters:
Gwynedda - 70 - Demon Warlock
Galaviel - 65 - Resto Druid
Gamaliel - 61 - Disc Priest
Gwynytha - 60 - Survival Hunter
Lienae - 60 - Resto Shaman
Plus several others below level 60

Info Panel IDs : http://www.wowinterface.com/forums/s...818#post136818
  Reply With Quote
01-28-10, 04:01 PM   #15
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,323
Originally Posted by Xrystal View Post
rofl, might have to play with it a bit to get full understanding of it

basically we can now have every variable local and that addon table will allow us access ? Or am I still confused ? rofl
Ya, just think of it as an upvalue passed to the entire addon, although it isn't available to the XML files, just the Lua ones.
__________________
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
01-28-10, 04:02 PM   #16
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Do this in every file:

Code:
local addon_name, addon_table = ...
Then, in File1, you can do this:

Code:
function addon_table:PrintHello()
        print(string.format("Hello! This AddOn is named %s", addon_name))
end
In File2, you can then call:

Code:
addon_table:PrintHello()
...and get what you'd expect.
__________________
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
01-28-10, 04:10 PM   #17
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,925
Aha, yep, thats what I envisioned, but kept forgetting functions are objects too

Might make some of my addons more cleaner working that way
__________________


Characters:
Gwynedda - 70 - Demon Warlock
Galaviel - 65 - Resto Druid
Gamaliel - 61 - Disc Priest
Gwynytha - 60 - Survival Hunter
Lienae - 60 - Resto Shaman
Plus several others below level 60

Info Panel IDs : http://www.wowinterface.com/forums/s...818#post136818
  Reply With Quote
01-28-10, 04:40 PM   #18
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,925
Oh, I don't believe I missed it rofl .. The amount of times I've read this post http://forums.worldofwarcraft.com/th...37376853&sid=1 and I never saw the part about the addon stuff.

ADDON LOADING
When a .lua file is loaded you can now access the name of the AddOn containing it, and an AddOn specific table (essentially an AddOn variable scope) by assigning them from ...:

local addonName, addonTable = ...;

The same table is sent to every file in a particular AddOn (each AddOn gets its own table).
Something to think on when I next do some updates to my addons where this would be beneficial.
__________________


Characters:
Gwynedda - 70 - Demon Warlock
Galaviel - 65 - Resto Druid
Gamaliel - 61 - Disc Priest
Gwynytha - 60 - Survival Hunter
Lienae - 60 - Resto Shaman
Plus several others below level 60

Info Panel IDs : http://www.wowinterface.com/forums/s...818#post136818
  Reply With Quote
01-28-10, 04:57 PM   #19
Rilgamon
Premium Member
 
Rilgamon's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 822
To reduce the confusion this part
Code:
if(name) then

end
is not required. The first argument is always set.
Dont know why I still have it
__________________
The cataclysm broke the world ... and the pandas could not fix it!
  Reply With Quote
01-28-10, 04:59 PM   #20
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,925
Rofl, thanks for the clarification there Was trying to think of times when it wouldn't exist
__________________


Characters:
Gwynedda - 70 - Demon Warlock
Galaviel - 65 - Resto Druid
Gamaliel - 61 - Disc Priest
Gwynytha - 60 - Survival Hunter
Lienae - 60 - Resto Shaman
Plus several others below level 60

Info Panel IDs : http://www.wowinterface.com/forums/s...818#post136818
  Reply With Quote

WoWInterface » Developer Discussions » General Authoring Discussion » Addon file system structuring

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