Version 17, last updated by Pilus at July 17, 2011 20:06 UTC
Details about lua
Links to use full info
http://www.wowwiki.com/World_of_Warcraft_API - API list for all ingame wow functions
http://www.wowwiki.com/Lua_functions - API list of all lua functions available ingame
http://www.wowwiki.com/Widget_API - GUI widget API
http://www.wowwiki.com/Events_(API) - List of ingame events
http://wowprogramming.com/utils/xmlbrowser - Browser / viewer for the blizzard interface codes
http://wowprogramming.com/utils/artbrowser/Interface - Browser of ingame art
http://books.google.dk/books?id=tFZyUCoZe7EC&printsec=frontcover#v=onepage&q&f=false - Parts of a book about lua programming in wow
http://lua-users.org/wiki/LuaDirectory - General lua information
Classes in the GH addons
Lua itself is not a object oriented programming language. There are however some ticks that we can do to use structures the works just like classes. The following is a template for how we create classes in the GH AddOns.
function GHI_Example(val1)
local class = GHClass("GHI_Example");
local val2,FuncA;
FuncA = function(v)
val2 = v;
end
class.PubFunc = function()
return val2;
end
val2 = 0;
funcA(val1);
return class;
end
The above template contains a few variables as examples. These can of cause be replaced by whatever is needed. The variable(s) marked with pink are the constructor. The line marked in green are where we define local variables and local functions. When they are written there they will be treated as local in all following lines. The orange area are definition of functions. The function FuncA in this example is a local function and is only available within the class. Because FuncA are defined as local in the green area, it is available in the whole class, even the lines above the where the function is written. The function PubFunc are a public function and are available outside the class as exampleClass.PubFunc(). The blue area are the initialization where local variables are given standard values and eventual initialization functions are called.
If we want the class to be a singleton (an object that is always the same no matter how many copies there are made), we just need to switch a few lines around in the top and add a little bit of code.
local class
function GHI_Example(val1)
if class then
return class;
end
class = GHClass("GHI_Example");
local val2,FuncA;
FuncA = function(v)
val2 = v;
end
class.PubFunc = function()
return val2;
end
val2 = 0;
funcA(val1);
return class;
end
This makes the class object being defined as the same variable every time this function is called. If the class have been created already it returns that, otherwise it creates it.
General structure of the GH AddOns
One of the architecture patterns normally used for application is Model-View-Presenter. In the GH addons we are using some patterns that can be related to that. We are using two different types of structure for the UI.
- A. The view is updated by the presenter, which gets it information from the model
- B. The presenter creates the view and gives it the information from the model.
A is the same method as blizzard uses for the UI in wow. However in their case the model is instead the game client. It is a safe method where the validation of actions can be preformed in the API between the presenter and the model. The UI are typically defined in XML and just updated by the presenter.
B is the method that we have mainly used in GHM and the BuffUI. The presenter creates what frames are needed and also controls the data once they are retrieved from the model. This is a bit more insecure, as the data can either be tampered with trough hooking or data can get lost on error. Examples in GHM are where the data for editing an item are retrieved from the model, the info are placed inside the menu and once the user clicks Ok, the data and modifications are send back into the model.
Naming conventions
The following is a few naming conversions we use in the GH addons.
- Variable names start with small letter and have a large letter in the beginning of each new word. E.g. amountOfSomething or itemUseCounter.
- Function names are like variables, but starts with a large letter. E.g. IncreaseCounter or TestSomeFeature.
- If it is necessary that a function or variable is global it should have either GHI_, GHM_, GHU_, GHP_ or GH in front of the name, depending on what relation the variable got. This is to avoid naming conflicts with variables from other addons.
- Files should be named in the same way as global variables. E.g. GHI_AreaBuff.lua. (note: this is currently not the case regarding the files in GHI, but it will be fixed soon).
Clean coding
There is a few advises on how to create clean code that I am trying my best to follow while making the AddOns. It is advises I got from a book called “Clean Code”. There is many pages of good information and practice, but here is a few good key rules that I think stands out.
- For most variables it is better to use long variable names that actually explains what the variable contains. (the very local counters such as ‘i’ or ‘t’ are not included in this).
- Do not make comments to explain bad code – rewrite the code instead
- Leave the pieces of code prettier and more tidy than you found them
- Normally functions should not contain more than a few lines of code. The function should only carry out one task and it should be named accordingly. This applies even if the function will only be called one place. In this way there will be a lot more functions, but it will be easier to see what the code does.