Sign in to follow this  
BlackMoons

Clarify @ vs & when registering application functions

Recommended Posts

Hi. I was wondering if I could get a little clarification on exactly what the difference between registering a function with & vs @?

 

Ie:

scriptEngine->RegisterObjectMethod("class", "void function(sometype &)", asMETHOD(class,function), asCALL_THISCALL);

scriptEngine->RegisterObjectMethod("class", "void function(sometype @)", asMETHOD(class,function), asCALL_THISCALL);

 

Just from messing around, It seems @ increments the object ref count for you while & does not (is that correct?) But @ works on types that don't have ref counting behavior too. Can you use @in or @out? or is @ always inout?

 

Should I be using & or @ in general? Or does that depend on if its a value or reference type?

Share this post


Link to post
Share on other sites

@ is called handle. & is called reference. To the script writer the difference is subtle, but the main difference is that @ can be null and can be reassigned after initialization.

 

On a lower level @ will always increment the reference counter, while & will not. Though with & AngelScript will often keep a hidden handle to the object to increment the reference counter anyway in order to guarantee that the object stays alive for the duration of the scope of the &.

 

@ can only be used with reference types that support handles.

 

in, out, and inout directives can only be used with parameter references, e.g. &in, &out, &inout. &inout is the same as &. With &in any changes to the referred-to-value will not be seen by the calling functions. With &out the initial value will be a default value.

 

Related articles in the manual:

Regards,

Andreas

Share this post


Link to post
Share on other sites

Hm, So does &in and &out make a copy of the object when the object is a reference type? Or does that only apply to value types?

 

Or does &in/&out only make a copy of the *handle* and let you modify the handle when you pass a reference type?

 

I guess I should switch to &out for most of the pointers I pass out of angelscript? Since I don't want the user to be able to pass a NULL out (most of the time) and its kinda annoying having the ref counter incremented automatically on me. (Having a 'remove' function release it twice looks odd, as well as having add functions that shouldn't increment the ref)

 

Any performance issues with &out instead of @ ?

 

Most of these are pointers to functions too. I would assume they can't self delete till the module is released anyway, but I guess its better to use refs properly everywhere instead of depending on outside behavior to keep things valid.

Share this post


Link to post
Share on other sites

&in/&out will make a copy of the value/object the reference refers to regardless of the type being a value type or reference type. @&in or @&out will make a copy of the handle only.

 

You can consider the following translation

 

AngelScript    C++

&in                   & (where the parameter is not meant to be modified, even though it is not const)

const &in          const &

&out                 & or * (where the parameter is used as output parameter only)

& or &inout       & or * (where the parameter is used to pass an object that will be modified)

@                     *

@&out              ** or *& (i.e. where the function will create a new object and return it)

const @            const *

 

There is no specific performance benefit with one or the other, except possibly with the use of const &in, which in most cases will allow AngelScript to pass a reference to the true object without making a copy of it.

Share this post


Link to post
Share on other sites

Ok, So if I want to pass a handle to a script function, from script to an application function, then I should be using @&in when registering the application function? or @?

 

Whats the difference between @&in and @?

 

Will the C++ function side be foo(bar**var){} with @&in?

 

The thing is I also have pointers to C++ classes passed to angelscript as ref types that I pass back out to my C++ application and must point to the same object when they come out. So I guess that rules out using &in and &out?

Share this post


Link to post
Share on other sites

If you want to pass a handle to a function (whether it is a script function or application function) then you'll most likely want to use @, which translates to * in C++.

 

If you want the function to return a handle in a parameter then you'll want to use @&out, which translates to ** (or *&) in C++.

 

I can't think of any reason to use @&in. It would also translate to ** or *& in C++, but this form in C++ is only usually only used for output and not input.

 

References that must refer to the original object, i.e. to allow the function to modify the object must not use &in or &out.

Share this post


Link to post
Share on other sites

Hmm. I think you're misunderstanding things a bit.

 

& doesn't cause copies. Only &in and &out. When you use & without in or out, then AngelScript will send a reference to the true object. This only works for reference types though.

Share this post


Link to post
Share on other sites

By the way, if you want to use & with out 'in' or 'out', you can set this:

 

script_engine->SetEngineProperty(asEP_ALLOW_UNSAFE_REFERENCES, true);

 

and this code, in scripts, will be walid

void SomeFunct( float &f ){
    f = 10;
}

Share this post


Link to post
Share on other sites

Oh. I thought that & would still cause a copy when passing from angelscript to C++, when asEP_ALLOW_UNSAFE_REFERENCES was false.

 

Thanks for clearing that up.

 

Is it just when passing to angelscript that & makes a copy of the object if asEP_ALLOW_UNSAFE_REFERENCES is false?

Edited by BlackMoons

Share this post


Link to post
Share on other sites

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