lua-users home
lua-l archive

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


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