Deltanic Posted September 8, 2011 Share Posted September 8, 2011 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
50p Posted September 8, 2011 Share Posted September 8, 2011 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
Deltanic Posted September 9, 2011 Author Share Posted September 9, 2011 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
50p Posted September 9, 2011 Share Posted September 9, 2011 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
Deltanic Posted September 9, 2011 Author Share Posted September 9, 2011 Right, still pretty weird to do t = {} _t = t t = {} But that's not the point anymore, I tested the script above and it results in a C stack overflow at line 24, which contains the _t[k] = v part. I don't get it, what is here the reason for? Link to comment
SDK Posted September 9, 2011 Share Posted September 9, 2011 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
Deltanic Posted September 9, 2011 Author Share Posted September 9, 2011 SDK: Already tried that by doing the metatable inside the custom function. Didn't make errors, but didn't work either. JR10: Why do you ask that? My script is exactly as it is there. Link to comment
JR10 Posted September 9, 2011 Share Posted September 9, 2011 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
SDK Posted September 9, 2011 Share Posted September 9, 2011 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
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now