Skip to main content
GameDev.net gamedev.net
🔒 Locked

[Lua] Proxy table and #t...

Started by ZealGamedev Nov 5, 2010 at 1:54 PM 7 replies 5k views
Original Post
ZealGamedev
ZealGamedev
I have a proxy table that exists in lua (it is a proxy for a vector that exists in C). The proxy table has the appropriate index/newindex metamethods so that it will read/write to the vector in C. Now, I would like for the table to 'feel' like a normal lua table, for example, it would be nice if the user could still use the the table library (table.insert(), ect...). The problem is, since the proxy table is empty, when the table library uses #t to get the table size, it is always 0.

My question - is there anyway to override the #t method, or is there some other clever way to get the table library to work with my proxy table?

Thanks
Sneftel
Sneftel
The easiest way to get the table library working with your classes would probably be to replace the table functions with custom versions, which treat your proxy tables specially, and defer to the original functions for other tables. That library, as with most of the base libraries, tends to work poorly with metatable-defined semantics, so just defining __len (even if it worked for tables) probably wouldn't do what you needed.
ZealGamedev
ZealGamedev
Yeah I contemplated just creating a special table library for my proxies... However, I really want to maintain the illusion that my proxies ARE just regular tables (for simplicity/elegance)... that means users are going to expect the table library to work with them....

Hrmm what to do what to do...

*ah you mean override the table library itself... that might work...

*Where can I find the implementation for the table library functions? I would like to take a look at how they work...
Sneftel
Sneftel
tablib.c, if I recall correctly.
ZealGamedev
ZealGamedev
Yeah I see them now (defined in ltablib.c actually).

Hrmm so the question is, what is worse -

1.) Modifying the table library to work with my proxies. Which means introducing a tiny bit of extra overhead to the library, and some 'under the hood vodoo' which may confuse some users.

OR

2.) Explain to users that the proxies are NOT regular tables, and wont work with the traditional table library (and provide a separate 'proxy manipulation' library).

I hate both options honestly :( ....

*Just to give a practical example of what I am trying to do - For my GUI system, you can control the items in combo box. You access the item list via 'combobox.items' (which returns the table/proxy). I would really like the user to be able to say something like table.insert(combobox.items, "NewItem"), and have that invoke a metamethod which adds the item to the combo box (which exists in C).

[Edited by - ZealGamedev on November 5, 2010 3:00:04 PM]
Sneftel
Sneftel
OR

3. Make the vector have its own vector-like interface, rather than pretending to be a hashtable.

OR

4. Give the user the choice between 1 and 2.


My gut reaction is that this isn't a significant problem. table.* are expected to perform raw functionality; note, for example, that userdatas don't work with them, and that passing a callable not-a-function into table.foreach doesn't work. I'd venture to guess, actually, that table.whatever working with your proxies would be more surprising to J. Random Hacker than it not working. If it were me, I'd make the proxies userdatas (so that table.whatever would error out, and so that I could make a __len metamethod), and if there was an actual need for some of the tablib operations, I'd make them. I dunno whether I'd put them in tablib, since I don't think a programmer would tend to forget which kind of structure he was working on, but that depends on use cases.
ZealGamedev
ZealGamedev
Hrmm I will have to sleep on this one I think...

Thanks for the input!
Matthew Shockley
Matthew Shockley
Just set the __len metamethod to return the size of the vector.
If I asked you for a hundred dollars would the answer to that question be the same as the answer to this question?
Sneftel
Sneftel
(A) __len metamethods are for userdatas, not tables, and (B) the table library doesn't invoke table metamethods.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.