[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Feature request: per-value uservalue
- From: Sean Conner <sean@...>
- Date: Tue, 21 Mar 2017 03:28:00 -0400
It was thus said that the Great Xavier Wang once stated:
> 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.
>
> 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.
Lua has the following types:
nil
boolean
number
string gc but value semantics
table gc per-instance metatable
function gc
thread gc
userdata gc per-instance metatable
lightuserdata*
(* In C, you can distinguish between a full userdata and a lightuserdata,
but in Lua, type() does not make that distinction and simply returns
'userdata')
> 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:
Actually, all the above types marked with 'gc' are subject to garbage
collection if no references exist to the "object".
> 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.
First off, metamethods are not "fall-back" (they don't chain
indefinitely). Second, the __gc metamethod *IS* required for proper
resource cleanup in the face of userdata (not all certainly, but anything
that deals with non-memory resources does).
> 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.
What you are asking for is a typed Lua. The above example could be done
with a proper type system (where derived types are considered distinct from
each other, unlike in C where derived types like:
typedef double percent;
typedef double degreee;
are considered the same). There are probably ways to accomplish what you
want without a radical redesign of Lua.
> 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.
I can't tell if you have a version of Lua that does what you want, or are
asking for Lua to support what you want ..
-spc