Sign in to follow this  

Registering new object types + methods

This topic is 4297 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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 work
int 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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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 script
RegisterObjectType("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 anything
RegisterObjectBehaviour("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 type
RegisterObjectMethod("texture", "int GetHeight()", asFUNCTION(GetHeight), asCALL_CDECL_OBJFIRST);

// A function to create the object handle is needed
RegisterGlobalFunction("texture @CreateTexture(256,256)", asFUNCTION(CreateTexture), asCALL_CDECL);

-----

// The AddRef and Release methods doesn't do anything, unless you want them to
void 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.


// AngelScript
void 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

Share this post


Link to post
Share on other sites

This topic is 4297 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this