Question about passing objects from script

Started by
1 comment, last by dxben 19 years, 1 month ago
Suppose I have C++ classes in my game that I want to expose and they look like this:

class A
{
   
}

class B
{
  doIt(A* a);
}
Is it possible, presuming I've registered both classes, to be able to be in AngelScript and make an instance of A and pass it to an instance of B's doIt() method? Is this possible to do even though doIt takes a * pointer? I was working with Squirrel and just found out you can't pass by reference or pointer to any registered methods, which presents a problem for me. The only way to do it is to write a wrapper class that takes a type by value and then pass it to the real object by pointer, but that is not only slow (copy by value) but also time consuming for me since I'd have to go and write all of these wrapper classes. Any help on how this works in AngelScript would be apreciated. [Edited by - dxben on February 27, 2005 9:53:16 AM]
Advertisement
I don't think there is any scripting language that will let you just pass a normal C pointer, without any kind of extra work. It just isn't safe enough in a scripting environment to give that much freedom to the script writer.

AngelScript may come slightly closer to what you need, but may not do exactly what you want.

AngelScript can pass arguments by reference to functions, however, in order to provide a safe sandbox environment it makes a copy of the object and passes the reference to the copy, and not the original object. Thus if you intend to store the object pointer, you can't register the function to take a reference.

AngelScript also supports object handles, which basically are reference counted pointers. If you register a pair of ADDREF/RELEASE behaviour functions for the class A, then AngelScript will allow you to pass the argument by handle. To C++ an object handle looks like a normal pointer, except that you'll have to call Release() on it before exiting the function.

engine->RegisterObjectType("A", sizeof(A), asOBJ_CLASS);engine->RegisterObjectBehaviour("A", asBEHAVE_ADDREF, "void f()", asMETHOD(A, AddRef), asCALL_THISCALL);engine->RegisterObjectBehaviour("B", asBEHAVE_RELEASE, "void f()", asMETHOD(A, Release), asCALL_THISCALL);// This function is registered as void func1(A &in)void func1(A *arg){  // We receive a pointer (or reference) to a copy of   // the real object thus we cannot store the pointer.  // We can read the properties though.  // If the reference is register as &out (or &inout),   // then we can also set the object's properties and   // the script engine will copy the values back to   // the real object afterwards.}engine->RegisterGlobalFunction("void func1(A &in)", asFUNCTION(func1), asCALL_CDECL);// This function is registered as void func2(A@)void func2(A *arg){  // This time we receive a pointer to the real object.  // The script engine increased the reference count on  // the object and expects us to decrease it before   // returning.   arg->Release();  // Of course, if we were going to store the object   // pointer, we should have called AddRef() first.}engine->RegisterGlobalFunction("void func2(A@)", asFUNCTION(func2), asCALL_CDECL);


If your class doesn't have a reference counter, it would be possible to register a pair of global functions, that does the reference counting in another way (or not at all if you have some other way of doing memory management).

I hope this helps you clear your doubts on AngelScript.

What I described above is what AngelScript supports today. I also intend to allow application writers to register normal functions that take a pointer, and tell AngelScript to take care of the reference counting. You would still have to register the AddRef/Release functions, but you wouldn't have to rewrite all your functions to call Release() on the pointer before returning.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

It sounds like then what most people are doing today is writing a set of classes that are specifically meant to be consumed by script, and which then wrap or delegate into the engine classes in a higher level way, and then register those special classes to the script engine. This seems to be the norm regardless of the script platform.

I can understand the safety aspect of it, I guess I'll probably just have to write those wrapper classes, or if I use Angel, just let it make the copy for me.

This topic is closed to new replies.

Advertisement