lua-users home
lua-l archive

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


Hi, I have written a function that allows me to expose functions to
Lua from C/C++.

I can register functions like this in C++:

RegisterFunc(lua_script, &Report_LuaPrint, "print", this, "console" );
RegisterFunc(lua_script, &SystemMode::Quit, "quit", this, "system" );

which lets me call them in Lua like so:
console.print("hello world")
system.quit()

I have reached a point where I would prefer more than one level of namespaces.
For example, myApp.math.cos() or even myApp.graphics.console.print(4)
would be something I would like to do.

But I'm stumped on how to do it. Below is the code I'm currently using
to register my functions. It was pieced together from some other
things I needed it to do (mainly the userlightdata), copying from some
of the Lua source code, and a lot of trial and error. I don't claim to
fully understand it, but it seems to work. Can somebody tell me how to
extend it to deal with more namespaces?


bool RegisterFunc(lua_State* script,
						   lua_CFunction function_ptr,
						   const char* function_name,
						   void* user_light_data,
						   const char* library_name)
{
	/* Validate arguments. */
	if (!script || !function_ptr || !function_name)
	{
		return false;
	}
	if (0 == strlen(function_name))
	{
		return false;
	}
	
	/* This will embed the function in a namespace if
		desired */
	if(NULL != library_name)
	{
		lua_getglobal(script, library_name);  /* check
		whether lib already exists */
		if (lua_isnil(script, -1)) /* no? */
		{  
			lua_pop(script, 1);
			lua_newtable(script);  /* create it */
			lua_pushvalue(script, -1); /* duplicate it */
			lua_setglobal(script, library_name);
			/* that auto-pops one of the table references
			 * but since we dup'd it, one is left
			 */
		}
		/* will have the global table on the stack now */
	}
	else
	{
		lua_pushvalue(script, LUA_GLOBALSINDEX);
	}
	
	/* Register function into script object.
	 * Also passes pointer to a SpaceObjScriptIO instance 
	 * via lightuserdata.
	 */
	lua_pushstring( script, function_name );  /* Add function name. */
	lua_pushlightuserdata( script, user_light_data );  /* Add pointer to
this object. */
	lua_pushcclosure( script, function_ptr, 1 );  /* Add function pointer. */
	lua_settable( script, -3);
	
	/* pop the table that we created/getted */
	lua_pop(script, 1);
	
	return true;
}

Thank you,
Eric