lua-users home
lua-l archive

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


Lua GC's functions just like any other value.

However, if you would like to know in your C code that this has been done
(perhaps to free up cached values from memory or close a handle to a device,
etc.) you will have to wrap the functions up with a userdata so that you can
get the GC notification (metamethod).  It would be incredibly nice if Lua
called the GC metamethod for tables as well as userdatas, then you could
know that a whole collection of items (as a collection, and without making a
userdata to be the collection) was no longer in use.  However, I've had that
discussion on this list and no one spoke up as agreeing with me.

Lua is, however, terribly flexible so there are numerous ways you could get
your GC notification.
1. Make a userdata rather than a function and set the _call [sp] metamethod.
2. Make a table of your group of functions and include a userdata in the
table, then assume the table is gone when the userdata is GCed (not really
accurate though so be careful with this sloppy approach).
3. Make a userdata in place of the table of your group of functions, then
set the _index metamethod to return the functions (perhaps through the
simple expedient of a helper table and setting the _index metamethod to that
table.  (You know I rather like this approach, personally.  It doesn't fix
the case of wanting GC notification for a table from inside Lua since you
can't make userdatas from inside Lua, but it just may be that from within
Lua you never need this anyway.)  Hmm, this just might be the start of a
good method for protecting your Library tables as well, hmm..
4. Give your function an upvalue that is a userdata, and use the GC
notification from the userdata.

Heck, thanks for posting the question, possibility 3 is so useful I'm glad
you made me think of it. :)


-----Original Message-----
From: lua-bounces@bazar2.conectiva.com.br
[mailto:lua-bounces@bazar2.conectiva.com.br]On Behalf Of Brett Bibby
Sent: Thursday, October 16, 2003 2:53 AM
To: Lua list
Subject: Re: object handling


Thanks for the info, really helpful.  How can I get lua to garbage
collect functions?  Over time as I run more and more functions, some
become unneeded.  Is there any way to get rid of these?
Brett

----- Original Message -----
From: "Kevin Baca" <lualist@aidiastudios.com>
To: "'Lua list'" <lua@bazar2.conectiva.com.br>
Sent: Wednesday, October 15, 2003 10:40 PM
Subject: RE: object handling


> Yes.
>
> Also, check out the __gc metamethod.  With it you can do the converse.
> When a lua object is GC'd you can then delete the C object.
>
> -Kevin
>
> >
> > Kevin,
> > That's very helpful, thanks.  If I call a functin that
> > deletes an object in my engine, can I then delete the table
> > (e.g.A123) by setting it to nil? Thanks again, Brett
> >
> > ----- Original Message -----
> > From: "Kevin Baca" <lualist@aidiastudios.com>
> > To: "'Lua list'" <lua@bazar2.conectiva.com.br>
> > Sent: Wednesday, October 15, 2003 10:09 AM
> > Subject: RE: object handling
> >
> >
> > > To pass the table A123 to a lua function from C:
> > >
> > > //Retrieve the lua function
> > > lua_pushstring( L, "funcname" )
> > > lua_gettable( L, LUA_GLOBALSINDEX );
> > >
> > > //Retrieve A123 (assuming it is a global)
> > > lua_pushstring( L, "A123" )
> > > lua_gettable( L, LUA_GLOBALSINDEX )
> > >
> > > lua_call( L, 1, 0 ) //call funcname() with 1 arg and 0 return vals
> > >
> > > Some other things to think about:
> > >
> > > You could have a lua function create the lua table and the C
object
> > > simultaneously, then store a reference (userdata) to the C object
in
> > the
> > > lua table.
> > >
> > > Conversely, create the lua table and the C object
> > simultaneously from
> > C
> > > and store a reference to the lua table in the C object
> > (perhaps using
> > > the lua_ref() macro).
> > >
> > > Or you can mix and match as you desire.
> > >
> > > Either way, once you have a way to create objects you might want
to
> > > think about defining all object variables (C-side and
> > lua-side) in lua
> > > because lua provides such a nice syntax for that sort of thing.
> > >
> > > Example:
> > >
> > > -- This creates a new tank object that contains a reference
> > > -- to a C object (as a userdata)
> > >
> > > function Tank( tankDef )
> > >     local tank =
> > >     {
> > >         ammo = tankDef.ammo,
> > >         health = tankDef.health
> > >     }
> > >
> > >     -- Create the C object (a userdata) and store a ref to
> > >     -- it in tank.__cobj__
> > >     tank.__cobj__ = C_tankCreate( tankDef.actorData )
> > >
> > >     return tank
> > > end
> > >
> > > -- The following will call Tank() and tank0 will
> > > -- refer to the new tank
> > >
> > > tank0 = Tank
> > > {
> > >     ammo = 10,
> > >     health = 100,
> > >     actorData =
> > >     {
> > >         -- Internal C data
> > >         followTerrain = true,
> > >         collideable = true,
> > >     }
> > > }
> > >
> > > This way you can define lua-side data and C-side data in in the
same
> > lua
> > > config table.
> > >
> > > Hope that makes sense.
> > >
> > > -Kevin
> > >
> > > > Newbie question....
> > > >
> > > > We're trying to come up with an efficient way to handle our game
> > > > objects from lua.  For a given game object, we define a complete
> > > > schema that includes the engine data and the game
> > extensions to that
> > > > data.  So for example, an Actor schema will have some
> > core internal
> > > > use variables and some additional game specific variables
> > (e.g. tank
> > > > might have armor, player might have health, etc.)  Currently, we
> > > > stuff the engine's internal variables into a C struct and the
> > > > additional variables into a lua table, then use lua bindings
> > > > to call engine functions that operate on the internal data
> > > > and use lua directly to manipulate the lua tables. So far so
good.
> > > >
> > > > At authoring time all of this is transparent to the
> > designer.  They
> > > > simply create instances of actors and add new variables
> > to them as
> > > > they need them.  When they export the game, we split the data
and
> > > > generate a guid for each engine object and embed that in
> > the engine
> > > > data and then create a lua table with the same name as
> > the guid that
> > > > also contains elements to hold the additional variables.
> > > >
> > > > My questions are:
> > > >
> > > > 1.  Is this a lame way to do this?  What are the other
> > ways? (either
> > > > implicitly or explicitly) 2.  If I have a guid of A123
> > (stored as a
> > > > 4 byte int, not char) and I create a lua table as A123 =
> > {}, when I
> > > > call from the engine into lua, what do I need to pass lua (or
> > > > configure before calling) so that a lua funciton can receive the
> > > > correct table to operate on?  I tried several experiments
> > passing in
> > > > the A123 as a number and a string and it doesn't work.
> > Do I need to
> > > > pass the table itself?  How do I do that?
> > > >
> > > > Thanks for the help.
> > > > Brett
> > > >
> >