Thread Tools Display Modes
06-08-13, 03:20 PM   #1
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
Modules + Metatables

Hello all,

I've always sucked at using metatables, so I've always tried to avoid them. However, the time has come when I need to create a proper modular addon, and metatables are a necessity. After spending a good long while trying to wrap my head around these damn things, I think I broke my brain.

I've whipped up a quick test project for myself (located on GitHub here).

It works, except for the fact that my Aura module (Modules\Aura.lua) isn't instantiated. When one aura frame updates, it updates all aura frames created by that module with identical properties, whereas I need frames to update individually. I know I need to get into turning my modules into classes using metatables, but my brain doesn't work when it comes to this stuff.

Any help or hints would be appreciated

Thanks in advance, Nib.

Last edited by Nibelheim : 06-08-13 at 05:39 PM.
  Reply With Quote
06-08-13, 06:24 PM   #2
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
I don't see any metatable usage in the code you linked?
__________________
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
06-08-13, 06:27 PM   #3
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
Originally Posted by Phanx View Post
I don't see any metatable usage in the code you linked?
Correct. More looking for help on how to implement them at all, so that each aura frame created via the Aura.lua module exists in it's own instance and updates only itself. >.>

When making earlier attempts, I kept on referring back to this guide here (it looks like the methodology the modular addons I've looked at use) but couldn't quite understand how to implement such concepts into my little addon.

Last edited by Nibelheim : 06-08-13 at 06:30 PM.
  Reply With Quote
06-08-13, 06:34 PM   #4
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Well, don't feel bad about your inability to understand that guide... after a quick glance I don't really know what it's talking about either, or what all the C code examples have with writing WoW addons. A better title for that thing might be "Introduction to Lua programming for C programmers". :/

I wouldn't bother with a metatable, unless you plan to be dynamically changing the metatable contents. Instead, I'd just add all the functions I wanted to a table:

Code:
local auraFunctions = {
    Update = function(self, ...)
        -- do something
    end,
    SetAura = function(self, aura)
        self.__aura = aura
    end,
    SetUnit = function(self, unit)
        self.__unit = unit
    end,
}
... and then copy them onto each aura icon as it's created:

Code:
function MyAddon:NewAura(unit, aura)
    local f = CreateFrame("Frame")
    f:SetSize(24, 24)
    -- etc.

    for k, v in pairs(auraFunctions) do
        f[k] = v
    end

    f:SetUnit(unit)
    f:SetAura(aura)
    f:Update()
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 : 06-08-13 at 06:37 PM.
  Reply With Quote
06-08-13, 06:39 PM   #5
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
Originally Posted by Phanx View Post
I wouldn't bother with a metatable, unless you plan to be dynamically changing the metatable contents. Instead, I'd just add all the functions I wanted to a table:
Ohh, nifty idea. Thanks
  Reply With Quote
06-10-13, 02:54 AM   #6
Kagura
A Fallenroot Satyr
Join Date: Nov 2008
Posts: 21
There's multiple ways of using metatables, but the below is one of the ways I use it and probably easiest to compare to "regular" way of OOP programming.

A working example you can find at https://github.com/Nimaear/Singulari...ster/Addon.lua

Lua Code:
  1. local Aura = {
  2.     timer = nil, -- not necessary here, but is still nice to have a list of "member variables"
  3.     static = nil,
  4.     SetTimer = function (self, timer)
  5.         self.timer = timer
  6.     end,
  7.     New = function(self, timer)
  8.         local this = {
  9.             timer = timer or 0 -- intialize defaults here
  10.         } -- Creating a new "instance"
  11.  
  12.         setmetatable(this, {__index = self}) -- this is basically what makes it "work"
  13.         return this
  14.     end
  15. }
  16.  
  17.  
  18. local a1 = Aura:New()
  19. local a2 = Aura:New()
  20. a1:SetTimer(3)
  21. a2:SetTimer(4)
  22. Aura.static = 3
  23.  
  24. print(a1.timer, a2.timer)  -- 3 4
  25.  
  26.  
  27. print(a1.static, a2.static)  -- 3 3
  Reply With Quote
06-10-13, 02:32 PM   #7
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
Thanks all for the help Much appreciated. I shall now start work on my little project, and hopefully there won't be any kinks along the way

At least metatables make sense now. Creating a table which is of another table and falls back to table, but is not equal to table.

Last edited by Nibelheim : 06-10-13 at 02:54 PM.
  Reply With Quote
06-10-13, 04:57 PM   #8
ravagernl
Proceritate Corporis
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 1,176
Just had this funky idea about a prototype constructor function. Might be helpfull in one way or another, also might have a gazillion of syntax errors
lua Code:
  1. local tinsert, tremove = table.insert, table.remove
  2. local function CreateFactory(name, meta, ftype, construct, ...)
  3.     local active, inactive, factory, i = {}, {}, {}, 0
  4.     function factory:retreive()
  5.         local instance = tremove(inactive)
  6.         if not instance then
  7.             i = i + 1
  8.             instance = setmetatable(CreateFrame(ftype or 'Frame', name and name..i or nil), meta)
  9.             if construct then
  10.                 construct(instance, ...)
  11.             end
  12.         end
  13.         active[instance] = true
  14.     end
  15.     function factory:release(instance)
  16.         if not active[instance] then return end
  17.         active[instance] = nil
  18.         tinsert(inactive, instance)
  19.     end
  20.     return factory
  21. end

Last edited by ravagernl : 06-10-13 at 05:18 PM.
  Reply With Quote
06-12-13, 06:44 PM   #9
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,327
Metatables aren't that difficult once you get the hang of it. I would recommend reading up on the Official Lua Manual §2.8 on metatables. It defines which keys in a metatable are capable of performing which actions. Metatables allow the programmer to define how they want the associated object to act when manipulated. Everything from indexing and calling the value as a function to mathematical operations can be defined. Do note some of these "overrides" have been disabled in the WoW implementation of Lua.
__________________
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

WoWInterface » Developer Discussions » Lua/XML Help » Modules + Metatables


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