[bmx] Lua - add blitzmax function to lua object method by skn3 [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:38

Previous topic - Next topic

BlitzBot

Title : Lua - add blitzmax function to lua object method
Author : skn3
Posted : 1+ years ago

Description : 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.

<a href="../Community/postsb692-2.html?topic=87716" target="_blank">http://www.blitzbasic.com/Community/posts.php?topic=87716</a> (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()


Code :
Code (blitzmax) Select
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 :


LT(Posted 1+ years ago)

 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.  :)