lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Again, it's helpful to look at the Lua source itself, for example the liolib.c which I mentioned earlier.

The steps involved would be:

1) create the userdata object
2) make a new table and set it as the metatable for the object

^ this gives you a C struct linked with a Lua table, you don't have to do any housekeeping to keep them associated.

3) Now, from the user side, you probably want to make changing values in that table easier for them. That's where you could pre-populate the metatable with a __newindex and an __index function that takes care of storing and retrieving values - so people can use the idiom you described with the onMouseMove example.

For this, you'd have to make a little C function that takes the incoming values and saves them to the metatable itself.

4) Using the table from the C side is simple. You retrieve the metatable for your struct, look up the pertinent function and call it if present. You can find examples for this throughout the Lua *lib.c files as well.

I hope this helps you get on your way. It takes a little effort to get acquainted with the Lua API, but once you get the hang of it, everything should fall into place...





On Tue, Sep 16, 2014 at 11:52 AM, Dirk Schippers <lua@frixx-it.com> wrote:
Thanks Udo and Andrew,

So to make things more specific, at this moment I have a struct containing the window handle.
The light user data pointing to that struct has a metatable.
I should override the __getindex method to be able to interpret:
w._onMouseMove_ = function() ... end

Now I 'm not sure: how/where should I store this function (or its reference?) so that I can call it later?
And: how do I call it later once I know what light user data is to be "called"?
(I assume the latter will be something like pushing the light user data on the stack, getting its metatable, pushing the name "onMouseMove", calling the "__index" function, ... well I think, but I don't really know how to do it)

Can you give me some specific help on this? I have been able to create Lua objects in light user data's before but never have I had to do such interaction between C and Lua objects.

Also, and possibly solved the same way as the above stuff: I would like the window object to contain a "userdata" table where the user can freely store specific data. So __index, called with "userdata" should return a lua_table. Again: where do I store this table to make sure it will always be the same table?

Udo Schroeter schreef op 16/09/2014 10:56:
Hey Dirk,

I'm relatively new to Lua, so take this with a grain of salt.

I would advise against returning a normal table. There would be no way to protect internal fields if you store them there, but more importantly keeping the connection between the Lua table and your window object itself alive could potentially be a major hassle.

Instead, have a look at the liolib.c as an example. There, they use a userdata base object for each file, and associated with it is the standard metatable for files. However, in your case, you would associate your window userdata object with a brand new table when it's constructed. The user can then modify that metatable to set event handlers or other data.

This has the added advantage that you can always easily retrieve the user-defined event handler for any given action from the C side by accessing the metatable.




On Tue, Sep 16, 2014 at 9:54 AM, Dirk Schippers <lua@frixx-it.com> wrote:
Hi,

I am creating a test project (C++) where I have this telnet server which creates a thread for every connected client that has its own Lua environment to play around in.
But I want to do more than: print 5 + 2
So I created some functions: createWindow({...}) which creates a window. I can call it multiple times to create multiple windows.

At this time, the function has become the constructor for an object, which returns a light userdata pointing to a C-struct containing the window handle and some other stuff.

But I want to expand this: I want the return value to become a table where you can put your own events handlers in, like this:

w = window.new({...})
w._onMouseMove_ = function(x, y)
    ...
end

I would also like to be able to pass the event function immediately to the constructor as well but still keep the ability to update the event later on.

Now the question is, how do I handle this: do I create a table (instead of a light userdata) in the constructor for window and add a metatable to it? How should I handle the optional event declaration? Do I need to override the __index or should I keep all of it in lua? How can I call the correct event function in the correct object when I receive the events in my message loop? If I use tables, I don't know how to find them back... How can I keep an index between the window handle and a lua table?
Where do I put the window-handle and stuff like that, whilst keeping the table safe so that noone can change this window handle through Lua code and corrupt the environment? Do I put an extra light userdata inside the table? Can I protect that one?

I know this is a big question but I have the feeling that the answer will be simpler.

Dirk.