lua-users home
lua-l archive

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




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

> I hope this was my last email about this :-)

I hope not - share your success (or failure) story, I'd be interested how it turned out :)

Great, let's share :-)
I think I managed to do it, but some other bug is making it hard for me at the moment. With all the testing&trial&error code I have such bad code at the moment that I need to rewrite now and hopefully find the bug that is causing things to go wrong at the moment.

But I had it working for a moment, so I think it's ok! It's all very logical and I have very carefully investigated the Lua stack at every step to see if all was correct and all came back when I needed it.

The only thing that was still a little bit difficult was how to get from the window handle back to the light-user-data-with-metatable.
The only way I could find was the one hinted by Andrew earlier in our discussion: by creating a table in the Lua registry with the window handle as key and the light-user-data-with-metatable as value.
I don't like the Lua registry (especially because of the keys that should be carefully chosen to not mess things up - I use a lightuserdata adressed to some static C variable as key - ), but I think I needed it for this.

Or do you know if there is another/better way?



This is the way ya' do it. You need access to a storage location, even when the stack is empty. Within Lua and the registry is set up for just that. Because the user can't access it, you can stay out of the way of other modules and story your object's metatable by storing it here, keyed to your module's name. Then, you can use `lua_L_checkudata` to see that the userdata that called your method is, in fact, your userdata.

Using the metatable to marshall commands back to Lua is a pattern that I have not seen. It may be a holdover from Lua 5.0 or earlier. I'm new enough to have only seen 5.2/3. 

You may want to read more about uservalues (distinct from userdata). A 'uservalue' is a Lua value that can be, and typically is, unique to every user userdata. This is where you can/would store user information. If you're using Lua 5.1, you can push a table upvalue to the userdata and store unique Lua values inside there, making your metatable's index metamethod retrieve that value, look up the requested key, etc. 5.1 doesn't have `uservalue`s. 

However, userdata is only necessary if you need something else from C. You could use your C call back to:

1:Find the users object by storing a lud -> Lua object reference in the registry.
2: From C, call a Lua function (method on the object) that receives the lua-ized version of the message that came in from windows. This function can then store the values, trigger other callbacks/coroutines, etc.
3: When all has been processed, some value is returned to C and the loop  is closed.

If security is a 'thing', set the `__metatable` field in your objects to `false` or `don't look here`. If Lua code tries to access or reset your object's metatable using `setmetatable`, they will receive the value of this field as their error message.

--Andrew