lua-users home
lua-l archive

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


On 7/28/08, Michael Ferenduros <mike.ferenduros@gmail.com> wrote:
> You can establish the relationship in two ways:
> 1) Use luaL_ref() to create a reference to the matrix, and store it in
> the vector struct. This will pin the Matrix until you release the ref
> (which you should do when the vector gets gc'd)
> 2) Stick the matrix in the vector userdata's environment-table. This
> has the same effect - as long as the vector exists, it'll keep the
> matrix alive - plus it's a bit more friendly to the garbage-collector.

Thanks again for the replies. I haven't done anything with luaL_ref
and environment tables so I thought I would try both to see how they
work.

For luaL_ref/unref, I added the __gc metamethod to MyVector so I can
call luaL_unref. Then for both, I added the following in my __index
function for MyMatrix where I create the Vector. I think both are
working and things seem to clean up in the right order at the right
times, but I would really appreciate it if any body sees any problems
with the snippet below.


		MyVector* return_vector = (MyVector*)lua_newuserdata(lua_state,
sizeof(MyVector));
		return_vector->myMatrix2 = the_struct;
		return_vector->theRow = array_index;
		
#ifdef USE_LUAREF
		lua_pushvalue(lua_state, -2-1); // copy the matrix on top of the
stack: [MyMatrix2 index MyVector MyMatrix2]
		// Thought: I am creating a unique ID for each vector even though
the matrix may be shared. I think a better way is to associate an id
with the matrix and store it there, but I don't want to change my
MyMatrix2 userdata.
		int ref_id = luaL_ref(lua_state, LUA_REGISTRYINDEX); // pop the
matrix off the stack and put it into the registry for referncing
		return_vector->refID = ref_id;

#elif defined(USE_ENV_TABLE)
		lua_newtable(lua_state); // stack: [MyMatrix2 index MyVector table]

		lua_pushvalue( lua_state, 1 );  /* Put MyMatrix2 on top of the
stack. [MyMatrix2 index MyVector table MyMatrix2] */
		lua_rawseti( lua_state, -2, lua_objlen( lua_state, -2 ) + 1 );    /*
env[ #env + 1 ] = MyMatrix2, pops MyMatrix2 */
		
		// stack: [MyMatrix2 index MyVector table]
		lua_setfenv( lua_state, -2 );    // Makes the table on top of the
stack the environment table for MyVector (at -2)
		// stack: [MyMatrix2 index MyVector]
#endif
		luaL_getmetatable(lua_state, MYVECTOR_METATABLEID);
		lua_setmetatable(lua_state, -2);


> OTOH, you might want to think hard about whether this is really worth
> the trouble, and potential for unexpected behaviour. The m[{1,2}]
> solution looks a lot nicer IMHO.You could also handle m{1,2} if you
> wanted (but only for getting, not setting).

Yes, I'm not sure if this is worth it, but I wanted to at least know
how to do it and see if I could do it in this simple test case. I
still have yet to decide if I want to implement for my real stuff.

What is the following case you describe? m{1,2}
Is this a function call? m({1,2}). Is this the functable technique I
read about somewhere else?

Thanks,
Eric