Jump to content

Metatables introduction?


Deltanic

Recommended Posts

Hello thar,

I've been told a few days ago that I could use metatables to track variable changes and call an event for this. Now, I'm not told HOW so It'd be nice to get some introduction to it.

Here's what I'm trying to do, and I thought metatables could solve it afaik:

I want to use a text variable in a GUI elements, and whenever this variable change, the GUI gets triggered to change too. Ofcourse I can do guiSetText each time after I changed the variable, but that's a hell to do if you have a lot.

So my first thought was to create a DX GUI system, so every render would automatically update the text if it's variable is changed. But a DX GUi is a little bit a lot of work..

So basically, I want to change the gui text when the text variable has been changed.

Link to comment

I'm not sure about variables changes but as someone told you, metatables are the way to go. One thing I'd advice you as well is OOP in Lua. If you want to know how to track your variable change, visit this website: http://www.lua.org/pil/13.4.4.html

Also, have a read here: http://www.lua.org/pil/13.4.1.html to know more about __index

and http://www.lua.org/pil/13.4.2.html for __newindex.

After visiting the first link, you should know enough how it works, but I suggest you read them all lessons to have better understanding. I hope it helps.

Link to comment

Difficult, but I've read it. I don't really get the proxy part; where is that needed for? First the 't' table gets created, then localized, and then created again. What the hell is the point of that?

And basically, this would change the window title?

  
_guiCreateWindow = guiCreateWindow 
function guiCreateWindow ( posX, posY, width, height, text, relative ) 
    local element = _guiCreateWindow ( posX, posY, width, height, text, relative ) 
    local tbl = { 
        element=element, 
        posX=posX, 
        posY=posY, 
        width=width, 
        height=height, 
        text=text 
    } 
    return tbl 
end 
  
resourceGui = {} 
local _t = resourceGui   
  
local meta = { 
    __newindex = function (t,k,v) 
        if k == "text" then 
            guiSetText ( t.element, v ) 
        end 
        _t[k] = v 
    end 
} 
setmetatable(resourceGui, meta) 
  
resourceGui.window = guiCreateWindow ( blah ) 
resourceGui.window.text = "NewTitle" 

Link to comment

The point of proxy is to track any action that took part in the table (that is, set values or get values). What the hell is the point of that? I'm telling you now, you may probably know already that when you assign a table variable to another variable, it will copy the reference of the table. That means, if you do any modifications to the referenced table, the changes will take place in the original table as well. For instance:

t = { 1, 2, 3 }; 
local _t = t; -- assign the reference of table "t" to table "_t" (that is proxy) 
print( t[ 1 ] ); -- it will print 1 
_t[ 1 ] = 5; -- change the value of t[ 1 ]  Yes, that is right, t[ 1 ]! 
print( t[ 1 ] ); -- it will print 5 
  

I hope you understand now.

Link to comment

i'm not very experienced on this topic. But I noticed that you create a table, set it's proxy and metatable and then add a another table to the table. I'm guessing you need to set the metatable on that new table.

resourceGui.window = guiCreateWindow ( blah ) 
setmetatable(resourceGui.window, meta) 
resourceGui.window.text = "NewTitle" 

Link to comment

Thought you edited it.

_guiCreateWindow = guiCreateWindow 
function guiCreateWindow ( posX, posY, width, height, text, relative ) 
    local element = _guiCreateWindow ( posX, posY, width, height, text, relative ) 
    local tbl = { 
        element=element, 
        posX=posX, 
        posY=posY, 
        width=width, 
        height=height, 
        text=text 
    } 
    return tbl 
end 
  
resourceGui = {} 
local _t = resourceGui   
  
resourceGui = {} 
  
local meta = { 
    __index = function ( t,k ) 
        return _t [ k ] 
    end , 
    __newindex = function (t,k,v) 
        if k == "text" then 
            guiSetText ( t.element, v ) 
        end 
        _t[k] = v 
    end 
} 
setmetatable(resourceGui, meta) 
  
resourceGui.window = guiCreateWindow ( blah ) 
resourceGui.window.text = "NewTitle" 

Try that.

Link to comment

Ok, tested and figured it out.

The biggest problem was that you were making a proxy of the resourceGui table, while you needed the resourceGui.window table.

You also need the __index in the metatable because when you set the window text, you're retrieving "t.element".

resourceGui = {} 
  
local meta = { 
    __newindex = function (t,k,v) 
        if k == "text" then 
            guiSetText ( t.element, v ) 
        end 
        _t[k] = v 
    end, 
    __index = function (t,k) 
        return _t[k] 
    end 
} 
resourceGui.window = guiCreateWindow ( 0.25,0.25,0.5,0.5,"OldTitle", true ) 
_t = resourceGui.window 
resourceGui.window = {} 
setmetatable(resourceGui.window, meta) 
  
resourceGui.window.text = "NewTitle" 

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...