LUA scripts

Started by
28 comments, last by Zorbfish 17 years ago
Hi there! I am new to LUA and I am embbeding it into my engine. Please answer me this two questions: 1) Can I define a function name with dots in the name? In my C++ functions I have defined for Lua: "Mesh3D.New" and so I want to add another function in LUA called "Mesh3D.PaintRed". Can I do that in LUA, like this? Note that Mesh3D is not a class in LUA.

function Mesh3D.PaintRed(x)
        return 2*x;
end
2) I am working with pointers in LUA to find my objects and I am scared that the guys who writes the script (or even myself) passes a wrong type of pointer to the parameter (e.g: he passes a Texture pointer to an Object3d pointer parameter). If that occurs I will get a C++ access violation error and everything will crash, and it will be very difficult to find the bug on the LUA script. Therefore I proposed the following solution:

function SafePointer(myPointer, myPointerType)
      return {Pointer = myPointer, PointerType = myPointerType);
end

TYPE_3ds =1000; -->Constant

function Mesh3D.New3ds(Filepath,p1,p2)
     
local     tempPointer = Mesh3D.Unsafe_New3ds(p1,p2);
      return SafePointer(tempPointer ,  TYPE_3ds};

end

function Render.3ds(My3ds, p1,p2,p3)
if (My3ds.PointerType= TYPE_3ds) then
Render.3ds(My3ds.Pointer,p1,p2,p3);
else
     Debug.MessageBox("Render.3ds was called by passing incorrect object. Only My3ds object should be passed. A pointer of type " .. My3ds.PointerType .. "was passed.");       

     end

end

And my question is: if the user passes to the Render.3ds function a parameter that is not a table (like SafePointer), will the statement (My3ds.PointerType= TYPE_3ds) return NIL or will LUA crash with an error? If it's the second case, how do I check if My3ds is of SafePointer type? Thank you so much in advance! I really appreciate all your feedback! Rod [Edited by - Kylotan on March 7, 2007 5:28:00 AM]
Advertisement
(1): No I don't believe you can do that in Lua. The reason is that Lua uses "." as an operator, to access elements of a table for instance (table1.table2.my_key = 5). I believe Lua function syntax is: first letter must be a case-insensitive letter, followed by any number of letters, numbers, or underscores.


(2): This seems like overkill to me. You want to check each and every function parameter to ensure its correctness? That adds a small penalty cost for one function, but to put it in all your functions the penalty cost will add up linearly to the # of calls you make.

I think the answer depends on what binding library (if any) you are choosing to use in your game. For example, Luabind uses an exception handling mechanism: link. Using existing functionality like that seems like a much less painful idea to me.



Hope that some of what I said helps.

Hero of Allacrost - A free, open-source 2D RPG in development.
Latest release June, 2015 - GameDev annoucement

1.) Yes this is possible Mesh3d would be a table in lua and because a function is a valid data type in lua this would be legal. The code below would also give you the same results

function chode(x)
return 2*x
end

Mesh3D.PaintRed = chode

Hopefully this helps.

2.)

I'm slightly confused as your safe pointer function doesn't actually check anything. I would actually suggest looking into a c++ solution where you have a class that encapsulates your pointer and the type and then all the objects that you actually pass around in lua will be pointers to a single class type. Then when you get the object in c++ you can do something like this.

// suto code below

CLuaSafePointer * pLSP = getdata();
if(pLSP.type == LSP_TYPEIWANT)
{
// do something
}
else
// throw error or ignore
Quote:Original post by Namatsu
1.) Yes this is possible Mesh3d would be a table in lua and because a function is a valid data type in lua this would be legal. The code below would also give you the same results

function chode(x)
return 2*x
end

Mesh3D.PaintRed = chode

Hopefully this helps.

2.)

I'm slightly confused as your safe pointer function doesn't actually check anything. I would actually suggest looking into a c++ solution where you have a class that encapsulates your pointer and the type and then all the objects that you actually pass around in lua will be pointers to a single class type. Then when you get the object in c++ you can do something like this.

// suto code below

CLuaSafePointer * pLSP = getdata();
if(pLSP.type == LSP_TYPEIWANT)
{
// do something
}
else
// throw error or ignore


Thanks! The C++ encapsulation class seems like a great solution! I will implement that, it seems excellent.

About No. 1) Could you please explain the table approach in order to define my functions with a dot in the middle like Mesh3D.PaintRed ? I am new to lua and I don't really get what you are saying...

did you previously define Mesh3D = {}? What about PaintRed?
or did you define Mesh3D = {PaintRed= myFunction} ?

Thanks so much everyone!
Cheers!
Rpd
THinking again... it's not a so good idea, since even though it's easy to pass from LUA the pointer of the encapsulation class to C++, I have some C++ that push poitners to LUA. In order for this to work, I would have to maintain new instances of these "encapsulation" objects, and that would consume a lot of memory. I don't want to duplicate my data.

Therefore my idea of implementing SafePointer was that it returns a table with two values, the pointer, and the pointer type, so that i make the structure in LUA for every C++ pointer returning function, and then check the pointer parameters in LUA checking if the PointerType of that structure is the one that corresponds.

Quote:
2): This seems like overkill to me. You want to check each and every function parameter to ensure its correctness? That adds a small penalty cost for one function, but to put it in all your functions the penalty cost will add up linearly to the # of calls you make.

I think the answer depends on what binding library (if any) you are choosing to use in your game. For example, Luabind uses an exception handling mechanism: link. Using existing functionality like that seems like a much less painful idea to me.


Thanks Roots for your answer :). No I just want to check the parameters that are passed as pointers, no more. All the other parameters are left unchecked, and it is used only in functions that use pointer parameters.

Could you explain me more what do you mind by "binding library"? I am using LUA 5.1. Are you proposing me to catch C++ errors with LUA? the thing is that if I pass a bad pointer to the C++ function, there is no check in C++ to see if the parameter is right, so the code would "throw" no error, but crash the program instead. This is because I would never expect in C++ to pass a parameter of other type to a pointer (in C++ you would get compile error, while from LUA as I am using pMYObject* = (static_cast) LuaGetuserData(s,1), anything can be passed).
Note: I don't have my project with me now, the syntax of the previous function surely is different, but you get the idea :)

What do you suggest?!

Thanks so much in advance!
Rod

P.S: The use of my solution would be like this:

TYPE_3ds =1000; -->Constantfunction SafePointer(myPointer, myPointerType)      return {Pointer = myPointer, PointerType = myPointerType);endfunction Mesh3D.New3ds(Filepath,p1,p2)     local     tempPointer = Mesh3D.Unsafe_New3ds(p1,p2);      return SafePointer(tempPointer ,  TYPE_3ds};endfunction Render.3ds(My3ds, p1,p2,p3)if (My3ds.PointerType= TYPE_3ds) thenRender.3ds(My3ds.Pointer,p1,p2,p3);else     Debug.MessageBox("Render.3ds was called by passing incorrect object. Only My3ds object should be passed. A pointer of type " .. My3ds.PointerType .. "was passed.");            endendAirplaneMesh= Mesh3D.New3ds("MyPlane.3ds",34,2);Render.3ds(AirplaneMesh, 5,2,3); --> I am sure that AirplaneMesh is of type 3ds since I can check it's "PointerType" parameter.
Quote:Original post by Anonymous Poster

About No. 1) Could you please explain the table approach in order to define my functions with a dot in the middle like Mesh3D.PaintRed ? I am new to lua and I don't really get what you are saying...

did you previously define Mesh3D = {}? What about PaintRed?
or did you define Mesh3D = {PaintRed= myFunction} ?

Thanks so much everyone!
Cheers!
Rpd


as far as I know you cant have a '.' in a variable name, you are actually accessing a variable inside a table when you call Mesh3D.new in your script. having defined Mesh3D.new in c++, Mesh3D should be a table already. but if you were defining something purely in lua you would have to do the Mesh3D = {} first. Hopefully this explains things better.
Quote:Original post by Namatsu

as far as I know you cant have a '.' in a variable name, you are actually accessing a variable inside a table when you call Mesh3D.new in your script. having defined Mesh3D.new in c++, Mesh3D should be a table already. but if you were defining something purely in lua you would have to do the Mesh3D = {} first. Hopefully this explains things better.


Yes Mesh3D.New is already defined in C++, so as you say Mesh3D it should be a table already. Since it is a table, then we agree that I don't have to define Mesh3D = {}, but how do I tell LUA that the new function PaintRed (not defined in C++) is a member of Table Mesh3D?

Like previous example : Mesh3D.PaintRed()?


Thanks so much!
Cheers!
Rod
correct

function Mesh3d.PaintRed(x)
return 2*x
end

should work
Quote:Original post by Namatsu
correct

function Mesh3d.PaintRed(x)
return 2*x
end

should work


wow that's what I wanted! thanks!

Oh, one more thing!:
In the following example, would LUA asume a.Fruit= nil, and call DoSomething or would LUA produce a runtime error?

local NewStructure = {Fruit = "banana", Color = "yellow");
local a = 4; --> simple number

if(a.Fruit ~= "banana")
DoSomething()
end

What about if a was not defined at all?

Thanks so much in advance!!!! This is all really helpful! Thanks :)

Cheers!
Rod
local a = 4if(a.Fruit ~= "banana") then	a=7end


This will give you a error similar to this at runtime.

'attempting to index 'a' (a number)' or
'attempting to index 'a' (a nil value)'
if a was a nil value

I believe you would need to do something similar to this.

if type(a) == "table" then	if a.Fruit ~= "banana" then		a=7	endend

This topic is closed to new replies.

Advertisement