lua-users home
lua-l archive

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


I have a structure which looks like this (pseudo code):
    Point {
	lua_number x, y;
    }

    GraphicsObj {
	Point pos;
	Point vel;
    }

I have handlers setup in lua so that I can do this:

    zeropoint = Point(0,0)

    obj = GraphicsObj(A_POS, Point(10,10), A_VEL, zeropoint);

the GraphicsObject Lua function constructs a new (C++) GraphicsObject
via a call to a factory function.  The args are parsed and each attribute
passed in is set into the GraphicsObject as appropriate.  When the
attributes of the GraphicsObject are set, the objects used 
as arguments are copied into the C structure.

Here's the tricky bit.

The GraphicsObject and the Point objects have gettable handlers to make
them look like structures:
i.e.:

    obj.A_POS = Point(30.0,10.0)
    obj.A_POS.x = 15

both of the above statements should work.

The way I do this is in the table handler for the GraphicsObj, I return
a userdata pointing to &(obj.pos).  The problem is, that the userdata
I create will eventually be GC'ed .. since it's a pointer to field of
another strucutre, this will cause free() to have fits.

How can I return a pointer to the field 'pos' in the C++ object?

My first thought was to lock a reference to the userdata that I pass
back in, thus it would never be GC'ed, but when I destroy the 
containing object, I'd need to release the reference, and that would
cause it to be GC'ed.  If I don't release the reference, then I'll
eventually take up the entire memory of the system with stale (but locked)
references (yes, it would take a long time, but that's not the point ;-).

I could register the type of my "Point" objects without a GC function,
but then objects like 'zeropoint' would get lost.

I could make a new type, which had all of the tag methods of the normal
Point type, except for a GC, but then anytime I wanted to typecheck
an object to make sure it's what I think it is, I'd have to check the 
'non-gc'ed' version, too... there's a lot of room for error in that.

I tried setting a flag in the object "this is an object which is part
of another object", but since of the composite object will likely happen 
BEFORE the GC of the member object, memory referenced by the userdata object
which points to the member has already been freed, and thus is invalid.

I can't copy the object because then the second statement (obj.A_POS.x = 15)
would not work (because the '.x' would refer to the new copy of the object,
not the actual obj.A_POS object).

Why am I doing this?  I have a large number of objects (many thousands)
which will be updated in C++ most of the time, but I need access to them
in Lua, so instead of making each object a table, which would slow down
C++ access, I want Lua to be able to access the objects as structures.

I suppose that I could make get/set functions for each property in an
object, but the Lua interface to that would be clumsy.

Any suggestions?
--
Mike Cuddy (mcuddy@FensEnde.com, MC312), Programmer, Daddy, Human.
Fen's Ende Software, Redwood City, CA, USA, Earth, Sol System, Milky Way.

       Now I lay me down to sleep / CVS, I pray, my code to keep.  
       If disks crash before I wake: / format, newfs, cvs up, make.

       Join CAUCE: The Coalition Against Unsolicited Commercial E-mail.
                          <http://www.cauce.org/>