[Solved] Send a BlitzMax Array to Lua?

BlitzMax Forums/Brucey's Modules/[Solved] Send a BlitzMax Array to Lua?

MOBii(Posted 2016) [#1]
How can I send BlitzMax AppArgs Array:String to Lua?
Local argn:Int = 0
For Local argv:String = EachIn AppArgs
	echo argn + ", ~q" + argv + "~q"
Next


I want it to be compatible to Stand Alone Lua in arg:
while arg and arg[1] do
	local a = table.remove(arg, 1)
	if a == "-flag1" then echo "I got flag1"
	elseif a == "-flag2" then echo "I got flag1"
	else	echo "No Flags" end
end


My attemt:
' I been Googling but I don't have those in my library/mod:
' lua_pushbmaxarray(State:Byte Ptr, arr:Object)
' lua_tobmaxarray:Object(State:Byte Ptr, index:Int)

This is one of my trying:
Method MOBii_SetArray(_Namn:String, _arr:String[])
	If L Then
		lua_pushlightuserdata(L, _arr)
		lua_setglobal(L, _Namn)
	End If
End Method


I try send Array arr to Lua:
Local arr:String[] = [ "arg0", "-flag1", "-flag2" ]	' Make a temp test array
MOBii_SetArray("arg", arr)				' Try Send array to Lua


In Lua when I cry catch the the arr, I get this Error:
Syntax Error :: line: 95, attempt to index global 'arg' (a userdata value)

I have no luck in my testing, what "a userdata value" is!

I am trying to set Lua arg[0] = "String" manually from BlitzMax, but so far I can't figure it out how to do it!


Derron(Posted 2016) [#2]
Check my adjusted code here:
https://github.com/GWRon/Dig/blob/master/base.util.luaengine.bmx

There is an adjustment in "CallLuaFunction()" (you need to handled "typeId.extends(arrayTypeID)" instead of only "typeId = arrayTypeId".

I also made some adjustments to "luaPushArray" as Lua is 1-based, not 0-based like BlitzMax.



Next I had to adjust your code:
Lua:
function ArgTest(arg)
	myprint("ArgTest called")
	while arg and arg[1] do
		local a = table.remove(arg, 1)
		myprint ("a: ".. a)
		if a == "-flag1" then
			myprint ("I got flag1")
		elseif a == "-flag2" then
			myprint("I got flag2")
		else
			myprint("No Flags")
		end
	end
end

(I had no "echo", but passed "myprint" (a blitzmax function) to Lua, so you need to replace it with your print-function (or echo).
Echo might be not available for me, as I blacklist certain lua-modules (else user lua-scripts might do evil things).


BlitzMax:
	Local arr:String[] = [ "arg0", "-flag1", "-flag2" ]
	local args:object[] = [arr]
	luaEngine.CallLuaFunction("ArgTest",args)


The change here is, that "CallLuaFunction" accepts already an array (arg1, arg2 ...). So if you pass "arr" directly, it is like saying: "arg0 = arg0, arg1 = -flag1".

So wrapping them in an args-array is then doing what you want.

So currently, passed args are able to get fetched in lua via
function test(argA,argB, argC)


If you really want to have
function test(args)

Then you might truncate "CallLuaFunction" to just call "luaPushArray" (or the second command, if you passed a null-param / length-0-array).


Output on my test was then:
./bmk makeapp -t console -quick -r -x "Dig.git/samples/lua/lua.bmx"
[ 90%] Processing:base.util.luaengine.bmx
[ 92%] Compiling:base.util.luaengine.bmx.release.linux.x86.s
flat assembler  version 1.68  (32768 kilobytes memory)
5 passes, 23945 bytes.
[ 95%] Processing:lua.bmx
[ 97%] Compiling:lua.bmx.console.release.linux.x86.s
flat assembler  version 1.68  (32768 kilobytes memory)
3 passes, 4049 bytes.
[100%] Linking:lua
Executing:lua
LUA print: ArgTest called
LUA print: a: arg0
LUA print: No Flags
LUA print: a: -flag1
LUA print: I got flag1
LUA print: a: -flag2
LUA print: I got flag2


bye
Ron


MOBii(Posted 2016) [#3]
I test download: https://github.com/bmx-ng/brl.mod
My brl.reflection.mod is Version: 1.03 and lack: TFunction, TConstant (maybe more?)

the Downloaded Version: 1.05 that have my lacking functions: TFunction, TConstant
I can't build brl.reflection.mod, I get this:
C:/BlitzMax/mod/brl.mod/reflection.mod/reflection.c: In function 'bbDebugDeclVarAddress':
C:/BlitzMax/mod/brl.mod/reflection.mod/reflection.c:74:13: error: 'BBDebugDecl {aka struct BBDebugDecl}' has no member named 'var_address'
  return decl->var_address;
             ^
C:/BlitzMax/mod/brl.mod/reflection.mod/reflection.c: At top level:
C:/BlitzMax/mod/brl.mod/reflection.mod/reflection.c:131:30: error: unknown type name 'BBInterface'
 const char * bbInterfaceName(BBInterface * ifc) {
                              ^
C:/BlitzMax/mod/brl.mod/reflection.mod/reflection.c:135:28: error: unknown type name 'BBInterface'
 BBClass * bbInterfaceClass(BBInterface * ifc) {
                            ^
C:/BlitzMax/mod/brl.mod/reflection.mod/reflection.c: In function 'bbObjectImplementsInterfaces':
C:/BlitzMax/mod/brl.mod/reflection.mod/reflection.c:140:13: error: 'BBClass {aka struct BBClass}' has no member named 'itable'
  return clas->itable != 0;
             ^
C:/BlitzMax/mod/brl.mod/reflection.mod/reflection.c: In function 'bbObjectImplementedCount':
C:/BlitzMax/mod/brl.mod/reflection.mod/reflection.c:144:13: error: 'BBClass {aka struct BBClass}' has no member named 'itable'
  return clas->itable->ifc_size;
             ^
C:/BlitzMax/mod/brl.mod/reflection.mod/reflection.c: At top level:
C:/BlitzMax/mod/brl.mod/reflection.mod/reflection.c:147:1: error: unknown type name 'BBInterface'
 BBInterface * bbObjectImplementedInterface(BBClass * clas, int index) {
 ^
C:/BlitzMax/mod/brl.mod/reflection.mod/reflection.c: In function 'bbObjectImplementedInterface':
C:/BlitzMax/mod/brl.mod/reflection.mod/reflection.c:148:13: error: 'BBClass {aka struct BBClass}' has no member named 'itable'
  return clas->itable->ifc_offsets[index].ifc;
             ^
Build Error: failed to compile (1) C:/BlitzMax/mod/brl.mod/reflection.mod/reflection.c


Looking at your luaengine.bmx:
Extern
	Function lua_boxobject( L:Byte Ptr,obj:Object )
	Function lua_unboxobject:Object( L:Byte Ptr,index:Int)
	Function lua_pushlightobject( L:Byte Ptr,obj:Object )
	Function lua_tolightobject:Object( L:Byte Ptr,index:Int )
	Function lua_gcobject( L:Byte Ptr )
End Extern
I see those function are the functions from maxluajit.mod\lua_object.c

I can't build maxluajit.mod because I can't build brl.reflection.mod v1.05

If I try build all modules from:
https://github.com/bmx-ng/brl.mod

the gcc crash (TDM MinGW 64bit 5.1.0-2), for every single module I try build

My primary problem is:
How can I build: brl.reflection.mod v1.05 so I can build maxluajit.mod

Of the look of it, your luaengine.bmx don't need maxluajit.mod
But I think the problem is the same: I need to make maxluajit.mod\lua_object.c work!


MOBii(Posted 2016) [#4]
I curse myself, It's hard to realize that I am lesser intelligent sometimes!
First I didn't understand Lua arg = {} is an Array not a class/Type, I get fooled that you can have functions in the array/table
the second one if I don't push the arrayname as Int I get arg['1'] not arg[1], that's was my real mistake!

Sending AppArgs to Lua:
MOBii_CreateTable("arg")
Local argn:Int = 0
For Local argv:String = EachIn AppArgs
	MOBii_TableSetString("arg", argn, argv)
	argn :+ 1
Next

...

' ------------------------------------------------------------[BLLua.MOBii_TableSetString]---
Method MOBii_TableSetString(_Table:String, _Namn:String, _Data:String)
	If L Then
		lua_pushstring(L, _Table)								' put the table in varname
		lua_gettable(L, LUA_GLOBALSINDEX)
		
		If MOBii_isString(_Namn) Then 
			lua_pushstring(L, _Namn)							' push the String "key"
		Else
			lua_pushinteger(L, Int(_Namn))							' push the Int(key)
		End If
		lua_pushstring(L, _Data)								' push the new value
		lua_settable(L, -3)									' set table["key"] to "value"
	End If
End Method
I still don't know If I need to pop something when I am done lua_settable?


I run from cmd:
argv.exe MOBii Mimi Astrid



Catch in Lua:
for k, v in pairs(arg) do
	echo("arg["..k.."] = "..v)
end


in my console:
arg[0] = argv.exe
arg[1] = MOBii
arg[2] = Mimi
arg[3] = Astrid



I still like to know howto build: brl.reflection.mod v1.05 and zeke.maxluajit.mod

PS: I like your CallLuaFunction:Object(name:String, args:Object[] = Null)
It's beautiful written!


Derron(Posted 2016) [#5]
@ Reflection
You might use Grable's extended Reflection (which is available in my Dig.git-framework too) - or you have to check the open "pull request" to maxmods/brl.mod by me.

You could even remove the TFunction/TConstant handling, as it is not used for sending arrays to Lua.


@ callLuaFunction
Have a look at "brl.maxlua" - it contains the .c-file too (I needed to add some code to make it compile as non-module in my case).
I enhanced maxlua-functions (array and other things) and made them superstrict.



@ maxlua jit
If you only call lua from time to time (in my case I only use it on special game events - "onMoneyChanged", "onEnterRoom", "onMinute") and I did not see any measureable improvements using LuaJit.


@ brl.reflection 1.05
The error you got is because you used the module for BlitzMax-NG (which supports interfaces).
You have to use the ones for vanilla (from maxmods).



bye
Ron


MOBii(Posted 2016) [#6]
Thank thee Derron very much!
With your help my brl.reflection.mod is now v1.25 and zeke.maxluajit.mod is now builded!

FootNote:
My interface between BlitzMax and Lua is static, my interface is integrated/stuck with the environment not portable (Stand Alone) as your luaengine.bmx!
When I leaned howto send one array-object at a time, I can send array's to Lua, as for now I only use it 1 time when Application startup to send the AppArgs

I test to jit.off() my heaviest Lua script and LuaJit on/off do nothing on my code too, that was a eye opener!
The only script I can see the speed difference is with sieve.Lua example.