Clarify @ vs & when registering application functions

Started by
11 comments, last by WitchLord 10 years, 7 months ago

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?

Lead Coder/Game Designer for Brutal Nature: http://BrutalNature.com

Advertisement

@ 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

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

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.

Lead Coder/Game Designer for Brutal Nature: http://BrutalNature.com

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

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

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?

Lead Coder/Game Designer for Brutal Nature: http://BrutalNature.com

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.

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

Ah k, So I will have to keep using @ for most things since & causes object copies. Great. Guess I will just have to try harder to remember when angelscript increments the ref count.

Lead Coder/Game Designer for Brutal Nature: http://BrutalNature.com

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.

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

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;
}

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?

Lead Coder/Game Designer for Brutal Nature: http://BrutalNature.com

This topic is closed to new replies.

Advertisement