asBEHAVE_CONSTRUCT asBEHAVE_DESTRUCT asBEHAVE_ASSIGNMENT asBEHAVE_ADD_ASSIGN asBEHAVE_SUB_ASSIGN asBEHAVE_MUL_ASSIGN asBEHAVE_DIV_ASSIGN asBEHAVE_MOD_ASSIGN asBEHAVE_OR_ASSIGN asBEHAVE_AND_ASSIGN asBEHAVE_XOR_ASSIGN asBEHAVE_SLL_ASSIGN asBEHAVE_SRL_ASSIGN asBEHAVE_SRA_ASSIGN asBEHAVE_ADD asBEHAVE_SUBTRACT asBEHAVE_MULTIPLY asBEHAVE_DIVIDE asBEHAVE_MODULO asBEHAVE_EQUAL asBEHAVE_NOTEQUAL asBEHAVE_LESSTHAN asBEHAVE_GREATERTHAN asBEHAVE_LEQUAL asBEHAVE_GEQUAL asBEHAVE_LOGIC_OR asBEHAVE_LOGIC_AND asBEHAVE_BIT_OR asBEHAVE_BIT_AND asBEHAVE_BIT_XOR asBEHAVE_BIT_SLL asBEHAVE_BIT_SRL asBEHAVE_BIT_SRA asBEHAVE_INDEX asBEHAVE_NEGATE asBEHAVE_ADDREF asBEHAVE_RELEASE asBEHAVE_GETREFCOUNT asBEHAVE_SETGCFLAG asBEHAVE_GETGCFLAG asBEHAVE_ENUMREFS asBEHAVE_RELEASEREFS asBEHAVE_FACTORY asBEHAVE_VALUE_CAST
Constructor, called when variables comes into scope.
Warning: Do not register a virtual method as a constructor. The virtual function pointer table will be initialized by the constructor function, thus the virtual method will fail.
Example:
void Constructor(Object *o) { new(o) Object(); } engine->RegisterObjectBehaviour("object", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(Constructor), asCALL_DECL_OBJLAST);
For objects that should be handled by the garbage collection, to be able to automatically detect and handle circular references, the constructor must call the method NotifyGarbageCollectorOfNewObject on the engine. When doing so the gc will take a reference to the object.
Destructor, called when variable goes out of scope.
Example:
void Destructor(Object *o) { o->~Object(); } engine->RegisterObjectBehaviour("object", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(Destructor), asCALL_CDECL_OBJLAST);
Assignment '='.
The assignment behaviour should return a reference to itself. The operator parameter can have any type. If the parameter is a reference to an object of the same type as itself the function is used as a copy operator, which is important if the object needs to treat members especially, for example if the class holds pointers to resources.
If you pass parameters by &in, then it is a good idea to also make them const, as it can allow the compiler to make a few optimizations.
Example 1:
Object &Assign(Object *self, Object &other) { *self = other; return *self; } engine->RegisterObjectBehaviour("object", asBEHAVE_ASSIGNMENT, "object &f(const object &in)", asFUNCTION(Assign), asCALL_CDECL_OBJFIRST);
Example 2:
Object &Object::operator=(int val) { this->val = val; return *this; } engine->RegisterObjectBehaviour("object", asBEHAVE_ASSIGNMENT, "object &f(int)", asMETHOD(Object, operator=), asCALL_THISCALL);
Add and assign '+='.
See assignment.
Subtract and assign '-='.
See assignment.
Multiply and assign '*='.
See assignment.
Divide and assign '/='.
See assignment.
Mod and assign '%='.
See assignment.
Bitwise or and assign '|='.
See assignment.
Bitwise and and assign '&='.
See assignment.
Bitwise xor and assign '^='.
See assignment.
Shift left and assign '<<='.
See assignment.
Shift right logically and assign '>>='.
See assignment.
Shift right arithmetically and assign '>>>='.
See assignment.
Add '+'.
This is a global behaviour that takes two operands and creates a new value. The function should not return a reference and shouldn't store the input values. The operands can be any type, reference or not, but one of the operands must be a registered type.
If you pass parameters by &in, then it is a good idea to also make them const, as it can allow the compiler to make a few optimizations.
Example 1:
Object Add(Object &a, Object &b) { return a + b; } engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "object f(const object &in, const object &in)", asFUNCTION(Add), asCALL_CDECL);
Example 2:
Object Add(Object &a, int i) { return a + i; } engine->RegisterGlobalBehaviour(asBEHAVE_ADD, "object f(const object &in, int)", asFUNCTION(Add), asCALL_CDECL);
Subtract '-'.
See addition.
Multiply '*'.
See addition.
Divide '/'.
See addition.
Modulo '%'.
See addition.
Equal '=='.
Example 1:
bool Equals(Object &a, Object &b) { return a == b; } engine->RegisterGlobalBehaviour(asBEHAVE_EQUAL, "bool f(const object &in, const object &in)", asFUNCTION(Equals), asCALL_CDECL);
Example 2:
bool Equals(Object &a, int i) { return a == i; } engine->RegisterGlobalBehaviour(asBEHAVE_EQUAL, "bool f(const object &in, int)", asFUNCTION(Equals), asCALL_CDECL);
See also addition.
Not equal '!='.
See equal.
Less than '<'.
See equal.
Greater than '>'.
See equal.
Less than or equal '<='.
See equal.
Greater than or equal '>='.
See equal.
Logical or 'or'/'||'.
See addition.
Logical and 'and'/'&&'.
See addition.
Bitwise or '|'.
See addition.
Bitwise and '&'.
See addition.
Bitwise exclusive or '^'.
See addition.
Bitwise shift left logically '<<'.
See addition.
Bitwise shift right logically '>>', ie. clear left most bits.
See addition.
Bitwise shift right arithmetically '>>>', ie. set left most bits to the sign bit.
See addition.
Indexing operator []. Must be registered as a object behaviour.
This behaviour is normally used to access an element in a collection based on an index, wether it be a numerical index or some other form. The behaviour normally returns a reference to the element so that it can be altered by the script, but it is allowed to return the element by value.
You'll normally want to register two versions of this behaviour, one that allow the element to be altered, and one that return a read-only value. This is useful when having constant objects.
Example:
int *Object::operator[](uint idx) { if( idx >= collection.size() ) { asIScriptContext *ctx = asGetActiveContext(); if( ctx ) ctx->SetException("Out of range"); return 0; } return &collection[int]; } engine->RegisterObjectBehaviour("object", asBEHAVE_INDEX, "int &f(uint)", asMETHOD(Object, operator[]), asCALL_THISCALL); engine->RegisterObjectBehaviour("object", asBEHAVE_INDEX, "const int &f(uint) const", asMETHOD(Object, operator[]), asCALL_THISCALL);
Unary negate operator -. Must be registered as a object behaviour.
This behaviour should return a new object with the effect of the operation applied to it.
Example:
Object Negate(Object *self) { Object obj; obj.val = -self->val; return obj; } engine->RegisterObjectBehaviour("object", asBEHAVE_NEGATE, "object f()", asFUNCTION(Negate), asCALL_CDECL_OBJLAST);
Necessary for object handles to work. Allows the library to increase the reference counter for the object.
Example:
void Object::AddRef() { refCount++; } engine->RegisterObjectBehaviour("object", asBEHAVE_ADDREF, "void f()", asMETHOD(Object, AddRef), asCALL_THISCALL);
For objects treated by the garbage collector, the AddRef method must clear the flag set by the SetGCFlag behaviour. Example:
void Object::AddRef() { // gc flag is kept in the most significant bit refCount = (refCount & 0x80000000) + 1; }
Necessary for object handles to work. Allows the library to decrease the reference counter for the object. When the reference counter reaches zero the function should release any resources held by the object and free its memory.
Example:
void Object::Release() { if( --refCount == 0 ) delete this; } engine->RegisterObjectBehaviour("object", asBEHAVE_RELEASE, "void f()", asMETHOD(Object, Release), asCALL_THISCALL);
For objects treated by the garbage collector, the Release method must clear the flag set by the SetGCFlag behaviour.
void Object::Release() { // gc flag is kept in the most significant bit refCount = (refCount & 0x80000000) + 1; if( refCount == 0 ) delete this; }
This behaviour is called by the garbage collector, and is required to be registered for those objects that should be handled by the gc.
int Object::GetRefCount(); engine->RegisterObjectBehaviour("object", asBEHAVE_GETREFCOUNT, "int f()", asMETHOD(Object,GetRefCount), asCALL_THISCALL);
The GetRefCount() should return the ref count, which the gc will use to determine whether it can release the object or not. If the ref count is 1, then it means that the gc is the only one holding a reference to the object thus it can be released.
The behaviour may use any compatible calling convention, including asCALL_THISCALL even if AS_MAX_PORTABILITY is defined.
This behaviour is called by the garbage collector, and is required to be registered for those objects that should be handled by the gc.
void Object::SetGCFlag(); engine->RegisterObjectBehaviour("object", asBEHAVE_SETGCFLAG, "void f()", asMETHOD(Object,SetGCFlag), asCALL_THISCALL);
This method is called by the gc when it's trying to determine which objects are really dead objects and should be released. When the method is called a flag must be set for the object. If the number of references to this object changes this flag must be cleared, e.g. when the AddRef and Release behaviours are called. This flag is what tells the gc that the reference count hasn't changed for this object since it started counting the references it sees.
The behaviour may use any compatible calling convention, including asCALL_THISCALL even if AS_MAX_PORTABILITY is defined.
This behaviour is called by the garbage collector, and is required to be registered for those objects that should be handled by the gc.
bool Object::GetGCFlag(); engine->RegisterObjectBehaviour("object", asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(Object,GetGCFlag), asCALL_THISCALL);
This method should return true if the flag is still set, i.e. no calls to AddRef or Release has been made since the last SetGCFlag call.
The behaviour may use any compatible calling convention, including asCALL_THISCALL even if AS_MAX_PORTABILITY is defined.
This behaviour is called by the garbage collector, and is required to be registered for those objects that should be handled by the gc.
void Object::EnumReferences(asIScriptEngine *engine); engine->RegisterObjectBehaviour("object", asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(Object,EnumReferences), asCALL_THISCALL);
When this method is called the object should enumerate over all the references it holds and call the asIScriptEngine::GCEnumCallback method for each of them. The engine pointer is passed in as a parameter to the method to simplify the implementation. The gc will use this to follow the chain of references in order to determine which objects are dead even though the ref count may be larger than 1, i.e. circular references.
The behaviour may use any compatible calling convention, including asCALL_THISCALL even if AS_MAX_PORTABILITY is defined.
This behaviour is called by the garbage collector, and is required to be registered for those objects that should be handled by the gc.
void Object::ReleaseAllReferences(asIScriptEngine *engine); engine->RegisterObjectBehaviour("object", asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(Object,ReleaseAllReferences), asCALL_THISCALL);
When this method is called the object should enumerate over all the references it holds and release them. The engine pointer is passed in as a parameter to the method to simplify the implementation. This method is called when the gc has determined that the object is part of a group of objects with interchanging references isn't reachable from the application anymore. By releasing all of the references the circular references will be broken and the ref count brought down to 1, which is when the gc will release the final reference causing the object to be destroyed.
The behaviour may use any compatible calling convention, including asCALL_THISCALL even if AS_MAX_PORTABILITY is defined.
Factory, called when variables comes into scope.
Example:
Object *Factory() { return new Object(); } engine->RegisterObjectBehaviour("object", asBEHAVE_FACTORY, "object@ f()", asFUNCTION(Factory), asCALL_CDECL);
For objects that should be handled by the garbage collection, to be able to automatically detect and handle circular references, the constructor must call the method NotifyGarbageCollectorOfNewObject on the engine. When doing so the gc will take a reference to the object.
An object behaviour, that permits a cast operator to be registered for an object. This can allow objects to be cast to different types, including primitives.
Example:
int Object::castToInt() { return intValue; } engine->RegisterObjectBehaviour("object", asBEHAVE_VALUE_CAST, "int f()", asMETHOD(Object,castToInt), asCALL_THISCALL);