[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: LightUserData and metatables
- From: Jerome Vuarand <jerome.vuarand@...>
- Date: Mon, 12 Oct 2009 16:34:33 +0200
2009/10/12 liam mail <email@example.com>:
> 2009/10/12 Jerome Vuarand <firstname.lastname@example.org>
>> 2009/10/12 liam mail <email@example.com>:
>> > Whilst integrating C++ with Lua which enables the passing of C++ objects
>> > to
>> > Lua, calling methods, operators and vice versa I have encountered a
>> > problem
>> > with my current implementation. I use the method with is described on
>> > the
>> > wiki entitled Luna and which is also described in many other
>> > publications
>> > such as Game Programming Gems.
>> > The crux of my problem is that a new user data is only created when an
>> > object is currently not alive in Lua, when it is the pointer which was
>> > returned when the lua_newuserdata was created is pushed onto the stack
>> > using
>> > lua_pushlightuserdata and has it's metatable attached. This metatable
>> > defines the functions to be called for the operators such as __eq and
>> > __le;
>> > yet a lightuserdata is only equal to itself and does not look at the
>> > metatable to see if the operator is defined for the type, whilst it does
>> > look at the metatable for methods.
>> > Is there a way whilst still using the operators instead of say a le
>> > function
>> > (obj:le(rhs)) to accomplish this, or is using this type of function for
>> > the
>> > operator or using a table to represent the data the only method. Ie. is
>> > there a way to trick Lua into looking at the metatable of the
>> > lightuserdata
>> > for the operators without modifying the source of Lua itself?
>> Your first paragraph is a little confusing. I'm not sure what you did
>> exactly, and what userdata is full or light.
>> Light userdata are not meant to represent objects, but rather as a
>> convenience to pass C values around. If you have a C object that you
>> want to manipulate from Lua you should embed them in a full userdata.
>> You cannot push a full userdata. What you can do however is associate
>> a userdata with its address in some table (e.g. the registry), and
>> from the address you can push back the full userdata with a table
>> indexing operation (lua_gettable).
> Sorry for the confusion I will try to explain again :)
> Say for example a C++ class instance is pushed to Lua twice for a Lua
> function parameters. The first time it is detected that the instance is not
> currently valid in Lua and therefore a full userdata is created and the
> returned pointer is stored to enable the validity check and also to allow it
> being exchanged again. When the same instance is passed the second time it
> is detected that the instance is valid in Lua, the pointer instance
> returned by the creating of the full user data is pushed onto the stack and
> the types metatable is associated with the light user data.
This still doesn't make much sense (especially since you're almost
repeating what was in your first email), but...
> This enables methods to be called on the light user data via a lookup in the
> metatable yet fails on the operators.
... do you realize that by setting the metatable of a light userdata
you are actually setting the metatable of all light userdata at once ?
> Are you suggesting that the second time it is pushed the pointer returned
> from creating the full user data is pushed onto the stack then lua_gettable
> is called and this will enable the type to be seen as a full user data? If I
> do this is there still a need to attach the types metatable to the table
> pushed onto the stack via lua_gettable or should it be valid?
You would call lua_gettable, but you wouldn't have a table on the
stack, you would have a full userdata, already configured.