Registering new object types + methods

Started by
2 comments, last by WitchLord 18 years, 1 month ago
Hey people, I've been experimenting with angelscript for a few days now, seems good, but theres a few strange things that i'd like to have clarified. doesnt seem to mention it in the docs. I've registered a couple of classes (eg vector+matrix classes) using RegisterObjectType + RegisterObjectBehaviour + RegisterObjectMethod and these seem to work well. These are registered as asOBJ_CLASS. So then i wanted to register some new primitive types (basically a typedef for type safety) using asOBJ_PRIMITIVE. I told it the data size was sizeof(unsigned int) and i expected the type to behave as any other primitive, like an int for example :) So then i wanted to register some methods for that type. Imagine it like a namespace, but when it gets passed to the method function, it passes it by reference instead of by value... This seems logical for a class, but i expected the asOBJ_PRIMITIVE type would treat it differently (passing by value all the time). Am i just completely wrong? There were no docs to go by, so i just started applying logic :P Heres my scenario specifically. In my engine code, i have a lot of c interface functions which deal handles to objects like materials/models/textures/etc.. These handles are 32bit values, so i figured i'd treat them as a primitive rather than a class (this is because i wanted them passed by value, NOT by reference).. I then register my c functions that receive these handles as member functions to that primitive type using asCALL_CDECL_OBJFIRST (expecting it to pass the object, in this case a registered primitive as the first paramater). When i do texture.GetHeight(), the C function receives a reference to the object rather than the value, which breaks everything and means i need to wrap all my functions. Basically, i want to be able to treat these handles like class isntances in the script because its nicer for the user. The problem is that handles need to be passed by value, not by reference. And when i call a 'member function', it seems to pass by reference even for a PRIMITIVE type.
Advertisement
AngelScript is able to pass these registered types by value to registered functions in the parameters, but what you're doing is slightly different. You're not passing the value to the function in the parameter (as far as AngelScript is concerned), instead you're calling a method on the object, in which case AngelScript does what it always does, i.e. setup the 'this' pointer to point to the value.

In your case you'll have to register the class methods as global functions instead. Unless you want to use the wrapper functions.

// This should workint height = GetHeight(texture);


I don't think I can modify AngelScript to support what you want in a clean way. I'll keep it in mind though, and if I do come up with a solution I'll implement it for you.

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

I was affraid that was the case,
At the moment i am using global functions exactly as you describe.
But yeah, having to write wrappers to treat it like a class is a bit of a shame.

What i was hoping is that because it was registered as a primitive type, when it sets up the 'this' pointer, it would continue to pass by value instead of reference (seems logical in that a primitive should never need be passed by reference, thats what classes are for).

Since there was no documentation clearly defining the difference between asOBJ_CLASS and asOBJ_PRIMITIVE i was thinking that must be the obvious differencee. So it seems intuitive at that level at least.

I do think it would be very nice to be able to treat handles like objects. Many libraries/API's deal handles, and treating them like a class seems a lot cleaner to code from the script point of view. So yeah, any thought towards that would be heaps appreciated.

Thanks!
Turkey
The flag asOBJ_CLASS, asOBJ_PRIMITIVE, etc, that you pass to the RegisterObjectType() method is only meant to tell AngelScript how the type is handled by C++, so that native calling conventions can be properly supported. It's not used to change the way AngelScript interprets the type.

I have a slightly different solution for you, that I believe will work exactly as you want:

// Register a type that can passed around as an object handle, // but cannot be instanciated by the scriptRegisterObjectType("texture", 0, 0);// Add the AddRef and Release behaviours, so that the type can // be passed around as object handles. Since the application will // do the memory management for these objects, the functions // doesn't have to do anythingRegisterObjectBehaviour("texture", asBEHAVE_ADDREF, asFUNCTION(DummyAddRef), asCALL_CDECL_OBJLAST);RegisterObjectBehaviour("texture", asBEHAVE_RELEASE, asFUNCTION(DummyRelease), asCALL_CDECL_OBJLAST);// Now register the functions that take the pointer as // first parameter as class methods to the typeRegisterObjectMethod("texture", "int GetHeight()", asFUNCTION(GetHeight), asCALL_CDECL_OBJFIRST);// A function to create the object handle is neededRegisterGlobalFunction("texture @CreateTexture(256,256)", asFUNCTION(CreateTexture), asCALL_CDECL);-----// The AddRef and Release methods doesn't do anything, unless you want them tovoid DummyAddRef(texture *ptr) {}void DummyRelease(texture *ptr) {}texture *CreateTexture(int w, int h){  texture *ptr = new texture(w,h);  return ptr;}int GetHeight(texture *ptr){  return ptr->height;}


With the above registration the scripts should be able to work with the textures as object handles.

// AngelScriptvoid test(){  texture @txt = CreateTexture(128,128);  if( txt != null )  {     int height = txt.GetHeight();  }}


Give it a try. I think it will work well.

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

This topic is closed to new replies.

Advertisement