LUA scripts

Started by
28 comments, last by Zorbfish 17 years ago
Quote:Original post by Namatsu


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.
***


Thanks! :) I didn't know about type().
Is there a way to check the table type, like for example what happens if
a = {Fruit= "banana", Color= "Yellow"} -->Fruit table/structureb = {Animal = "Rat", NumberOfLegs = 4} --> Animal Table/structureif type(b) == "table" then	if b.Fruit ~= "banana" then 		b=7	endend


In this case b is also a table, but does not have the member Fruit. Will LUA return a runtime error or nil? How do I check if a is a Fruit table/structure or an Animal table/Structure?!

Thanks so much!!!! :)
Cheers!
Rod
Advertisement
a = {Fruit= "banana", Color= "Yellow"} -->Fruit table/structureb = {Animal = "Rat", NumberOfLegs = 4} --> Animal Table/structureif type(b) == "table" then	if b.Fruit ~= "banana" then 		b=7	endend


yes this code is valid. the second 'if' statement would fail because b.Fruit is a nil value. You could do something like this to let you know if an invalid table was passed in. assuming you have a logger class bound to lua.

a = {Fruit= "banana", Color= "Yellow"} -->Fruit table/structureb = {Animal = "Rat", NumberOfLegs = 4} --> Animal Table/structureif type(b) == "table" then	if b.Fruit ~= "banana" then 		b=7	else		Logger.Error("blah")	endend
Thank you so much! :)
Cheers!
Rod
Oh.. by the way:

Should I call from C++

RenderElements::Mesh3D_ASE_Node *tempASE_Node = 		static_cast<RenderElements::Mesh3D_ASE_Node*>(lua_touserdata(s,1));ORRenderElements::Mesh3D_ASE_Node *tempASE_Node = 		(RenderElements::Mesh3D_ASE_Node*)(lua_touserdata(s,1));


In other words, should I call a static cast, or a simple cast?!
I saw it both ways on the internet.

Thanks so much!
Cheers!
Rod
both should work as far as I know. Maybe someone else has a bit more insight on this subject than me.
Thanks Namatsu! :)

I managed that to work! Thank you so much!

However, I got another problem now...

Quote:
-->Constants for Pointer Types
TYPE_ASE = 1000;
TYPE_3ds=1001;
TYPE_Texture=1002;
TYPE_DisplayList=1003;
TYPE_Object3D=1004;
-->

function SafePointer(myPointer, myPointerType)
if (myPointer~= nil) then
return {Pointer = myPointer, PointerType = myPointerType};
else
--> Debug.MessageBox("Problem!");

return nil;
end

end

function CheckPointer(FunctionName, DesiredPointerType, VariableToTest)
if (type(VariableToTest) == "table") then
if (VariableToTest.PointerType == DesiredPointerType) then
return true;
else
--> Debug.MessageBox("Incorrect parameter passed in ".. FunctionName .. ". A Safe Pointer must be passed of type " .. DesiredPointerType .. ". Parameter passed was of type ' " .. type(VariableToTest) .. " '.", "Incorrect parameter passed in " .. FunctionName);

return false;

end

else
--> Debug.MessageBox("Incorrect parameter passed in ".. FunctionName .. ". A Safe Pointer was NOT passed", "Incorrect parameter passed in " .. FunctionName);

return false;

end

end

function Mesh3D.NewASE(Filepath,TextureFilter,p1,p2,p3)

local tempPointer =Mesh3D.UnsafeNewASE(Filepath, TextureFilter, p1,p2,p3,done);

LastSafePointer = SafePointer(tempPointer , TYPE_ASE);
return LastSafePointer;


end



function Render.ASE(SafePointer_ASE,p1, p2, p3, p4)

if CheckPointer("Render.ASE", TYPE_ASE, SafePointer_ASE) then
Render.UnsafeASE(SafePointer_ASE.Pointer, p1, p2,p3,p4,done);

end
end


(This is not really a quote but I haven't found how to do the code tag. does not work ;)


So I first call:

mySafePointerTableASE =Mesh3D.NewASE("MyFile",1,2,3)
Render.ASE(mySafePointerTableASE, 4,5,6,7);

expecting that mySafePointerTableASE gets stored a table of type:
{Pointer = myPointer, PointerType = myPointerType}.
However when I call Render.ASE I get the following error:

"Attempt to index local 'SafePointer_ASE' (a userdata value)"
function Render.ASE(SafePointer_ASE,p1, p2, p3, p4)  if  CheckPointer("Render.ASE", TYPE_ASE,  SafePointer_ASE) then        Render.UnsafeASE(SafePointer_ASE.Pointer, p1, p2,p3,p4,done);    end       end


So yes... it's a userdata value (so the SafePointer structure got stored), but what's the problem with trying to access SafePointer_ASE.Pointer?!!?

Thanks so much in advance!
Cheers
Rod
try changing it to this just to test.


function SafePointer(myPointer, myPointerType)
if (myPointer ~= nil) then
local retval = {Pointer = myPointer, PointerType = myPointerType}
return retval
else
...
[ source ] is what you want

I hate to arrive to the party a little late, but I think all of these safe wrappers are a bit overkill.

There is actually a safe way to do this built into the language. The idea is that you create a userdata for each of your objects, like you are doing now. However, you also assign each a metatable. There would be a metatable for each object type. Then to check the type of an object, you simply check the userdata's metatable. This may be a bit over the top, however, it does allow you to treat your userdata like real objects. I think it is going to let you use Mesh3D.PaintRed act the way you want. I assume that Mesh3D is a class in C++ and you have mutlipule instances of this class. If this is not the case, then what I am suggesting is most likely over kill, otherwise, it is most likely the cleanest solution. So what exactly are you trying to do here? Are there many instances of the same C++ class that you would like to expose to Lua? Or is it mostly singleton type classes with only one instance?
Quote:Original post by Namatsu
try changing it to this just to test.


function SafePointer(myPointer, myPointerType)
if (myPointer ~= nil) then
local retval = {Pointer = myPointer, PointerType = myPointerType}
return retval
else
...



Thanks so much Namatsu!!!
I got it fixed! I found another error in my code too, I was passing a wrong variable too. However applying this two fixes now it works :)


Cheres!
Rod
Quote:Original post by Dwiel
[ source ] is what you want

I hate to arrive to the party a little late, but I think all of these safe wrappers are a bit overkill.

There is actually a safe way to do this built into the language. The idea is that you create a userdata for each of your objects, like you are doing now. However, you also assign each a metatable. There would be a metatable for each object type. Then to check the type of an object, you simply check the userdata's metatable. This may be a bit over the top, however, it does allow you to treat your userdata like real objects. I think it is going to let you use Mesh3D.PaintRed act the way you want. I assume that Mesh3D is a class in C++ and you have mutlipule instances of this class. If this is not the case, then what I am suggesting is most likely over kill, otherwise, it is most likely the cleanest solution. So what exactly are you trying to do here? Are there many instances of the same C++ class that you would like to expose to Lua? Or is it mostly singleton type classes with only one instance?


Hi Dwiel!
Thanks for joining the party! :)

I read your design proposal, and it seems interesting, although I am not understanding some points: How do I do this "Then to check the type of an object, you simply check the userdata's metatable."?

I guess that what you are proposing is to use "classes" in LUA using metatables and assigning functions to each of these classes right? I read a lot about this but didn't get it well yet. Could you provide me a simple example?

By the way, this is what I am trying to do:
I got in C++ many linked lists that contain objects. For example I have a linked list of 'ASE' objects. In LUA I am trying to create a new nodes and then pass this pointer nodes to another functions to manipulate them. Sometimes I need to call object's member functions and sometimes I have to pass the object's pointer to another functions. Most of the times I don't need to delete the nodes explicitly since all the linked list gets deleted at the end of the program, so I don't really need to explicitly call the deconstructor as it's managed by the linked list. So if I have to delete a node I don't want it to be implicit, but explicitly through another function like DeleteBlah()...

Maybe your class simple example will enlighten me... ;)

Thanks so much in advance!
Cheers!
Rod

This topic is closed to new replies.

Advertisement