Calling function when lua table value is changed.

Started by
4 comments, last by AverageJoeSSU 14 years, 1 month ago
I would like to call functions based on what value inside of a table is changed. I know i can use metamethods but i dont quite understand if i can do this. so if x,y,z values change i would call setPosition(x,y,z) or if Active changes to true from false I would call self.setActive() . would i use the __index metamethod? how can i check for the changed value. would i have to duplicate the table with old values and do a compare? is there a simpler way to do this? Thanks for any ideas. -Joe

------------------------------

redwoodpixel.com

Advertisement
after thinking about it... i think i'll just do the check outside of the lua environment, will make it easier. I almost feel like something like x,y, and z position that can possibly change every frame would likely want to exist in the native level and be queryable by lua.

------------------------------

redwoodpixel.com

You might want to keep all that data inside Lua if Lua owns those objects. Calling a native callback every time you want to query the state of the object in Lua will be very expensive. My design is all state is stored in Lua and only when the object is "dirty" does it push the state back into the native replica and only then once per frame is possible to minimize the overhead of Lua<->Native interface.

Good Luck!

-ddn
I should prolly put more context....

I'm referring to my editor's interaction with lua... let alone lua's interaction with the engine.

x,y,z is a bad example, since the native renderer/updater/physics is the only thing that cares about x,y,z EVERY frame.

but... basically i have the ability to edit a lua table live... in a WPF control... pic. The problem is I am changing the state, but not handling the state change.

But the thing is... being able to manipulate and handle these things is different based upon each value... and i may be missing a layer of interaction altogether.

------------------------------

redwoodpixel.com

This can be done, however like ddn3 noted it can be expensive. I wouldn't use this in time-critical code.

The way you'd do this is to use a proxy table that acts as an 'event handler'. The proxy table never holds any data, but has the metamethod for __newindex. The issue that you probably ran into that newindex is only called, as the name suggests, when a new index is accessed. Thus, after the first time you set the index the metamethod no longer gets called.

As an example, here's how it works written in Lua. You'd obviously want to connect your proxy to your C callback in the real version.

//This would be your monitored table/objectlocal realTable = {}//This function is called when a property is setlocal function OnNewIndex(self, key, value)	print(("Updating field: %s to %s"):format(key, value))        //Set the property on the real table	getmetatable(self).__index[key] = valueend//For anything that might change the properties you want to watch they have to access the real table through the proxylocal proxy = setmetatable({}, {__newindex = OnNewIndex, __index = realTable})assert(proxy.foo == nil)proxy.foo = "bar"assert(proxy.foo == "bar")

i see, yes this make sense... and for something like level design through an editor, this could be doable.

------------------------------

redwoodpixel.com

This topic is closed to new replies.

Advertisement