passing blitzmax object to LUA?

BlitzMax Forums/BlitzMax Programming/passing blitzmax object to LUA?

slenkar(Posted 2009) [#1]
How would I pass a blitzmax object to a lua function, alter one of the fields and pass it back?

If I altered one of the fields would the object change in blitzmax without it being passed back?


N(Posted 2009) [#2]
You can use my wrapper or write your own code to handle passing/receiving objects to/from Lua, beyond that you cannot do this.


Gabriel(Posted 2009) [#3]
Personally, I send the objects as integer handles using HandleFromObject and HandleToObject.

I expect it's theoretically possible to use a BlitzMax object and derive the fields and maybe even function pointers and access them from Lua, but it's not a very safe or easy way to do things.

Much better to create functions in your Types for everything you want to do from Lua and then bind those functions so that Lua can call them.

Lua isn't an Object Oriented language, as such, but it does allow you to create tables (similar to arrays) which are full of function pointers. You could do that in a "constructor" function in lua, so that all the "methods" are instantiated when you create your "object" (table.) Your table will also need one more "hidden" field which you can _Handle or _Peer or something which holds the integer handle. You'll need to pass that back to BlitzMax whenever you call a method so that BlitzMax knows which object it should use to access the method. If everything is functions, and no methods are required, you won't need to do this.

It also allows you to use the : operator as syntactic sugar for passing itself as the first parameter.

EG:

DoSomething(A,B)


is functionally the same as

A:DoSomething(B)



N(Posted 2009) [#4]
but it's not a very safe or easy way to do things.
Not entirely true, considering I did it (and relatively safely, since it's just using the reflection code).

Much better to create functions in your Types for everything you want to do from Lua and then bind those functions so that Lua can call them.
This is true, but only to some degree. Writing tons of glue functions gives me a headache, so I fixed that issue, more or less, by simply exposing types with their methods and fields accessible (unless a specific method or field is set to be hidden).


slenkar(Posted 2009) [#5]
@Nilium - do you have an example script to use with your wrapper?
I got your wrapper fromn the other thread I think.
Just to see it in action.
I havent got a clue how to use it.


@gabriel
integer handles, solves a lot of the issues I thought would crop up
So if I wanted to alter the x field of an object of type car I would have to write a glue function like
type car
function increase_x(c:car)
c.x=c.x+1
endfunction
endtype

instead of just doing c.x=c.x+1 in LUA code.


Gabriel(Posted 2009) [#6]
Well yeah, you could do it like that, but I would probably have a function called SetX and a function called GetX and then you could set and get any combination you want, and let Lua do the work.

EG:

Car:SetX(Car:GetX()+1)


But you could also have:

Car:SetX(Car:GetX()/2)


Without binding any new functions. You can send and receive as any variables as you need, so it makes sense to use them if you can. Don't go overboard though, as there's an overhead in using lots of function parameters, same as there is in BlitzMax itself.

@Noel: Sorry, I'm not at all familiar with your module. I was just answering the question and you can probably see from the post time(s) that I started replying before you finished replying. You're right, of course, binding lots of functions can be a bit of a drag.


N(Posted 2009) [#7]
do you have an example script to use with your wrapper?


Try http://gist.github.com/80159

This is from the example I have in the code archives (I should remove the code from the archives, it's outdated). None of the other stuff I've used this for is really suitable for sharing or example right now. I'll have to work on a more practical use of the code until then.


slenkar(Posted 2009) [#8]
only just got time to check it out now,

Good example! thanks for the code.


slenkar(Posted 2009) [#9]
im trying to move someone around a map

Im creating the character with newchar() which was generated by the reflection code, but I need to return the integer handle to blitzmax so it can be put onto the character list which is used to draw the map.

It says that the char which i created with newchar() is a table and not an integer, how do i get the integer handle?


Gabriel(Posted 2009) [#10]
Well I have no idea how you're doing it, but I guess if you're using reflection, you're using Noel's module. I would assume he puts the BlitzMax object handle in the table somewhere. That's what I do. Isn't there a clue in the newchar() function?


N(Posted 2009) [#11]
Objects are stored using Longs inside of a userdata passed to Lua. I don't use Handle because this doesn't work for passing multiple instances of an object very well (still fiddling with other ideas).

The structure of a BMax object in Lua is, more or less, a table with two metatables, one for field access and one for garbage collection (the field metatable is assigned to the object table, the GC metatable is assigned to the user data), a userdata containing a long to reference the object, and generic callbacks for each method (which method is called is based on the upvalues pushed with the callback).

If you need to add the object to a list, I would recommend that you either add a method to it that adds it to the list, or add it to the list in the constructor.