lua-users home
lua-l archive

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


2017-03-21 2:26 GMT+08:00 Tim Hill <drtimhill@gmail.com>:
>
> On Mar 19, 2017, at 8:55 PM, 云风 Cloud Wu <cloudwu@gmail.com> wrote:
>
>
>
> Tim Hill <drtimhill@gmail.com>于2017年3月20日周一 上午11:12写道:
>>
>> Other than tables or full userdata (which have per-value metatables), what
>> do you need? I’m unclear on what use a metatable on a particular string, or
>> a light userdata would have (why would it not be a full userdata in that
>> case?).
>>
> lightuserdata can be a sub struct of an complex C/C++ object .
>
> For example, in 3d engine, a node of a 3d object as a lightuserdata would be
> better than full userdata. If you query a node of a 3d object from lua , you
> can create a full userdata proxy for it, but you should also cache it in
> uservalue because it should be the same value in next query ( __eq is not
> enough if you want to use it as a table key).
>
> Using lightuserdata (with metatable) for a 3d node would simplify the
> bindings of 3d engine and reduce the overhead.
>
>
> But a light userdata with a metatable basically *IS* a full userdata. The
> only difference is that the full userdata is allocated by Lua, and undergoes
> garbage collection .. which you ALSO want for the __gc. As you noted, the
> technique here is to allocate a full userdata that just holds a C pointer
> (aka a light userdata).
>
> Your request won’t get you a lower overhead .. it will just get you
> something else that is identical to full userdata but with a different name.
>
> —Tim
>

IMO there are two different things in Lua: values and objects. values
are the thing that in local value or table slots, and objects are the
subject of garbage collect.

A 123 (number) is a value, and a table {} is a object, and if you write:

local t = {}

then t is a table value, refers to a gc-able table object (the {} itself).

All of all, there are only two object type has the __gc behavior now,
table and userdata. so make such a api:

collectgarbage({}, function() print "collect!" end)

or:

lua_gc(LUA_SETGC, 1);

will hand the gc, so per-value metatable is not impossible, we only
need move __gc out of metatable.

meta-methods makes a fall-back behavior for Lua values (not only
objects), gc is a theoretical standalone feature, it only works for
specific object, even not for all gc subjects.

but this will break API (I think for Lua is not a big deal), so let's
backward a step: just make per-value uservalue.

for that, we can make different behavior for different value (not only
object!), percent 4 will different with digree 4. In game engine, we
only need a smart pointer, not need gc for node (node can be collect
when swap scene). well Lua has metatable to change value behavior, but
only for heavy object! We have change to make a cheap way to make all
Lua values could have it's own behavior.

in short, if you need the __gc behavior, use the full userdata. But
when you need change a single value's behavior and needn't gc support,
per-value (uservalue|metatable) makes more freedom to do what you
want.



-- 
regards,
Xavier Wang.