Sign in to follow this  
cBull

C++ objects in Lua both ways - the solution

Recommended Posts

cBull    122
Some time ago, say two weeks, I started developing with lua. I've found it a nice language, however, C++ objects are not easy supported. Then I've found a toLua library which I like very much. But after a glance a problem appeared. toLua supports only full userdata and not light userdata. And that means that it can only operate on objects created in lua script. What I wanted was the system that would let operate on both light and full userdata (and that means c++ objects created in lua and in c++) in the same way. And that would be object:method(arg1, arg2). That is, in a lua standard way to call "methods". While toLua make it possible for full userdata, the light userdata cannot be accesed in this way. What I've done is a piece of code that creates a binder table that let call methods on light userdata. Here is the code:
function binder_index(table, key)
	f = table[1][key]
	if (f == nil) then
		error("Method/field "..key.." not defined")
	end
	if type(f) == "function" then
	-- method wrapper
		local method = f
		return	function (b, ...)
					return method(b[0], unpack(arg))
				end
	else
	-- variable
		return f
	end
end
	

function bind(class_name, light_userdata)
	local binder = {}
	binder[0] = light_userdata
	binder[1] = _G[class_name]
	
	if (binder[1] == nil) then
		error("Class "..class_name.." not defined")
	end
		
	m = {}
	m["__index"] = binder_index
	setmetatable(binder, m)
	
	return binder
end
The code is quite simple, yet very useful. There is a one problem with using it. For some strange reason toLua (or maybe lua) returns full userdata in a different way than light userdata. For this code to work you need to pass a ligth UD as a pointer to pointer or modify toLua functions to return light userdata in a correct way. Also you have to compile your code with TOLUA_RELEASE defined to avoid toLua type checking. Here is an example how to use this code:
function sample_update(self, time)
	self = bind("CSampleProcess", self)
	dr = time * 30;
	self:setRotation(self:getRotation() + dr)
end
Here CSampleProcess is a class binded to lua with toLua library. As you can see all you have to do is create a binder with bind function, giving the name of the class a light userdata is. It's the first version of this code and it only supports methods (class variables and operators are not working). In the future I'm trying to add variables and operators and maybe defining new variables on lua side. I'll appreciate any comments on this code. Thanks [Edited by - cBull on October 24, 2005 6:34:30 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this