Code archives/Miscellaneous/Lua - add blitzmax function to lua object method

This code has been declared by its author to be Public Domain code.

Download source code

Lua - add blitzmax function to lua object method by skn32012
With these functions you can quickly add "methods" to a lua object.

Example:
Function UpperCase:Int(vm:Byte ptr)
	lua_pushstring(vm,lua_tostring(vm,1).ToUpper())
	Return 1
End Function

lua_pushstring(vm,"some value")
lua_addMethod(vm,-1,"ToUpper",UpperCase)


This code would add a "method" ToUpper to the string we pushed to the stack. Obviously this example is pretty useless but if you want to create an interface to a blitz object you could do some more advanced things.

http://www.blitzbasic.com/Community/posts.php?topic=87716 (code for pushing a blitz object to the stack)

Here is a snippet of code to add a stream object onto the stack with methods. It is assuming the functions in the thread above are present...
lua_register(vm,"WriteStream",LuaWriteStream)

Function LuaWritetream:Int(vm:Byte ptr)
	Local path:String = lua_tostring(vm,1)
	lua_pushbmaxobject(vm,WriteStream(path))
	lua_addMethods(vm,-1,["Close","WriteLine"],[LuaCloseStream,LuaWriteLine])
	Return 1
End Function

Function LuaCloseStream:Int(vm:Byte ptr)
	Local stream:TStream = lua_tobmaxobject(vm,1)
	stream.close()
	Return 0
End Function

Function LuaWriteLine:Int(vm:Byte ptr)
	Local stream:TStream = lua_tobmaxobject(vm,1)
	stream.WriteLine(lua_tostring(vm,2))
	Return 0
End Function


You could then in lua do:
stream = WriteStream("blah.txt")
stream:WriteLine("hello world")
stream:Close()
Function lua_getMetaIndex(vm:Byte ptr,index:Int)
	' --- add a meta table and index to the object on the stack ---
	'get the meta table
	If lua_getmetatable(vm,index) = 0
		'add new meta table to index if there wasn't one
		lua_newtable(vm)
		If index < 0
			lua_setmetatable(vm,index-1)
		Else
			lua_setmetatable(vm,index+1)
		EndIf
		lua_getmetatable(vm,-1)
	EndIf
	
	'get __index
	lua_getfield(vm,-1,"__index")
	
	'create __index if there was none
	If lua_istable(vm,-1) = False
		lua_remove(vm,-1)
		lua_newtable(vm)
		lua_setfield(vm,-2,"__index")
		lua_getfield(vm,-1,"__index")
	EndIf
	
	'remove the meta table from stack
	lua_remove(vm,-2)
End Function

Function lua_addMethod(vm:Byte ptr,index:Int,name:String,func:Int(vm:Byte ptr))
	' --- add a method to the object ---
	'force object to have meta table and __index table
	lua_getMetaIndex(vm,index)
	
	'add teh method
	lua_pushcclosure(vm,func,0)
	lua_setfield(vm,-2,name)
		
	'remove __index from stack
	lua_remove(vm,-1)
End Function

Function lua_addMethods(vm:Byte ptr,index:Int,name:String[],func:Int(vm:Byte ptr)[])
	' --- add a method to the object ---
	'validate correct info passed in
	Assert name<>Null And func <> Null And name.Length = func.Length,"invalid methods"
	
	'force object to have meta table and __index table
	lua_getMetaIndex(vm,index)
	
	'add teh method
	For Local funcIndex:Int = 0 Until name.Length
		lua_pushcclosure(vm,func[funcIndex],0)
		lua_setfield(vm,-2,name[funcIndex])
	Next
		
	'remove __index from stack
	lua_remove(vm,-1)
End Function

Comments

LT2012
Had to make changes to get this compiling. Both instances of...

Local stream:TStream = lua_tobmaxobject(vm,1)

...should probably be...

Local stream:TStream = TStream( lua_tobmaxobject(vm,1) )

Also, LuaWritetream should be LuaWriteStream. Thanks for your contribution, though. :)


Code Archives Forum