AngelScript
Registering a scoped reference type

Some C++ value types have special requirements for the memory where they are located, e.g. specific alignment needs, or memory pooling. Since AngelScript doesn't provide that much control over where and how value types are allocated, they must be registered as reference types. In this case you'd register the type as a scoped reference type.

A scoped reference type will have the life time controlled by the scope of the variable that instanciate it, i.e. as soon as the variable goes out of scope the instance is destroyed. This means that the type doesn't permit handles to be taken for the type.

A scoped reference type requires only that the release behaviour is registered. The addref behaviour is not permitted. If the factory behaviour is not registered the script will not be able to instanciate objects of this type, but it can still receive them as parameters from the application.

Since no handles can be taken for the object type, there is no need to keep track of the number of references held to the object. This means that the release behaviour should simply destroy and deallocate the object as soon as it's called.

scoped *Scoped_Factory()
{
return new scoped;
}
void Scoped_Release(scoped *s)
{
if( s ) delete s;
}
// Registering a scoped reference type
r = engine->RegisterObjectType("scoped", 0, asOBJ_REF | asOBJ_SCOPED); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("scoped", asBEHAVE_FACTORY, "scoped @f()", asFUNCTION(Scoped_Factory), asCALL_CDECL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("scoped", asBEHAVE_RELEASE, "void f()", asFUNCTION(Scoped_Release), asCALL_CDECL_OBJLAST); assert( r >= 0 );

Unfortunately any function that either takes or returns the type by value in C++ must be wrapped in order to permit AngelScript to manage the life time of the values.

Here's an example of a function that takes a value and returns another and the corresponding wrapper.

scoped Foo(scoped a)
{
scoped b;
return b;
}
scoped *Foo_wrapper(const scoped &a)
{
return new scoped(Foo(a));
}
// Registering the function
r = engine->RegisterGlobalFunction("scoped @Foo(const scoped &in)", asFUNCTION(Foo_wrapper), asCALL_CDECL); assert( r >= 0 );

Observe how the function is registered to return the scoped value by handle even though the scoped types really don't support handles. This is done because AngelScript will call Release on the returned instance after it is done with the value it received.

See also
Registering a reference type
asOBJ_SCOPED
@ asOBJ_SCOPED
The life time of objects of this type are controlled by the scope of the variable....
Definition: angelscript.h:260
asBEHAVE_FACTORY
@ asBEHAVE_FACTORY
Factory.
Definition: angelscript.h:362
asBEHAVE_RELEASE
@ asBEHAVE_RELEASE
Release.
Definition: angelscript.h:368
asCALL_CDECL_OBJLAST
@ asCALL_CDECL_OBJLAST
A cdecl function that takes the object pointer as the last parameter.
Definition: angelscript.h:234
asIScriptEngine::RegisterObjectType
virtual int RegisterObjectType(const char *obj, int byteSize, asDWORD flags)=0
Registers a new object type.
asOBJ_REF
@ asOBJ_REF
A reference type.
Definition: angelscript.h:250
asIScriptEngine::RegisterObjectBehaviour
virtual int RegisterObjectBehaviour(const char *obj, asEBehaviours behaviour, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *auxiliary=0, int compositeOffset=0, bool isCompositeIndirect=false)=0
Registers a behaviour for the object type.
asIScriptEngine::RegisterGlobalFunction
virtual int RegisterGlobalFunction(const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *auxiliary=0)=0
Registers a global function.
asFUNCTION
#define asFUNCTION(f)
Returns an asSFuncPtr representing the function specified by the name.
Definition: angelscript.h:675
asCALL_CDECL
@ asCALL_CDECL
A cdecl function.
Definition: angelscript.h:226