code:
/**

\page doc_adv_generic_handle Registering a generic handle type

Sometimes it is useful to be able to take a reference to an object without having to
force specific implementation on the object, e.g. when providing a generic storage class
to scripts, or providing a generic messaging system.

In AngelScript there is no common denominator for all object types, the reasons for this is
that script classes and application registered classes have completely different implementation and
cannot be generalized under a single superclass.

Instead, AngelScript provides an alternative by allowing the application to register a
generic handle type. This type would be implemented according to the application's needs,
but to the script it would look like it was a generic \ref doc_script_handle "handle" that can
reference any reference type. With this the type will be able to hold objects,
\ref doc_datatypes_funcptr "functions", and \ref doc_addon_array "arrays".

To register the generic handle type, the application should follow the same principles as for a
\ref doc_register_val_type "value type", except for a few details, that will be described here.

 - The type must be registered with the additional flag \ref asOBJ_ASHANDLE. This is the flag that
   tells AngelScript that the type simulates a generic handle.

 - In order to allow assigning any handle to the type, the \ref doc_script_class_ops "opHndlAssign" method must be registered with
   a \ref doc_adv_var_type "variable parameter type", e.g. 'ref &opHndlAssign(const ?&in)'.

 - The \ref doc_script_class_ops "opEquals" method must also be registered with a \ref doc_adv_var_type in order to allow the
   is and !is operators to behave as expected for a handle, e.g. 'bool opEquals(const ?&in)'.

 - Finally the \ref doc_script_class_ops "opCast" must be registered with the signature 'void opCast(?&out)' in order
   to allow a dynamic cast to any other type.

As this is a quite useful type, with really very little need for customization, a standard add-on
with this implementation has been provided with the SDK.

\see \ref doc_addon_handle

*/


code:
/**

\page doc_adv_import Import functions

\ref doc_global_import "Importing functions" is a form of \ref doc_script_shared "sharing" code between script modules.
Unlike the <tt>shared</tt> keyword though, the <tt>import</tt> requires specific code in the application to bind the imported
functions after the script has been compiled.

This may be useful when the application wants to control specifically what can and cannot be imported.

To bind all the imported functions, without any specific treatment, the application just needs to call the
\ref asIScriptModule::BindAllImportedFunctions "BindAllImportedFunctions" method after the
\ref doc_compile_script "build" has completed.

If fine grained control is desired, then the application should use the methods
\ref asIScriptModule::GetImportedFunctionCount "GetImportedFunctionCount",
\ref asIScriptModule::GetImportedFunctionDeclaration "GetImportedFunctionDeclaration",
\ref asIScriptModule::GetImportedFunctionSourceModule "GetImportedFunctionSourceModule",
\ref asIScriptModule::GetFunctionByDecl "GetFunctionByDecl", and
\ref asIScriptModule::BindImportedFunction "BindImportedFunction", to enumerate and bind the imported functions one by one,
and raise an error in case the script tries to import a function that the application doesn't allow.

Another advantage that the import function feature has over shared entities, is that the imported functions can be unbound and
then bound to another script module if there is a need to change the sourcing module. To unbind the bound functions use the methods
\ref asIScriptModule::UnbindAllImportedFunctions "UnbindAllImportedFunctions" or \ref asIScriptModule::UnbindImportedFunction "UnbindImportedFunction".

*/

repo_name: Antidote/openrpgeditor

license: mit


code:
/**

\page doc_adv_inheritappclass Inheriting from application registered class

A script class cannot directly inherit from an application registered class,
as the script classes are not compiled into native machine code like the
application classes are.

It is however possible to emulate the inheritance by using a proxy class
to hide the underlying differences in an abstract layer. The proxy class has
two parts, one is the C++ side that the application sees, and the other is
the script side that the scripts can see and inherit from.

The following is an example implementation of such a proxy class.

\code
// On the C++ side
class FooScripted
{
public:
  // Public interface that we want the script to be able to override
  void CallMe()
  {
    // If the script side is still alive, then call the scripted function
    if( !m_isDead->Get() )
    {
      // Check that it isn't our script class instance that is makng the call, in
      // which case we do not callback to the script to avoid endless recursiveness
      asIScriptContext* ctx = asGetActiveContext();
      asIScriptFunction* func = ctx ? ctx->GetFunction(0) : 0;
      if (!func || strcmp(func->GetName(), "CallMe") != 0 || !ctx || ctx->GetThisPointer(0) != m_obj)
      {
        // Call the script function CallMe so the script can provide the overloaded behavior
        asIScriptEngine* engine = m_obj->GetEngine();
        ctx = engine->RequestContext();

        // GetMethodByDecl returns the virtual function on the script class
        // thus when calling it, the VM will execute the derived method
        ctx->Prepare(m_obj->GetObjectType()->GetMethodByDecl("void CallMe()"));
        ctx->SetObject(m_obj);
        ctx->Execute();

        engine->ReturnContext(ctx);
      }
    }
  }

  int m_value;

  // A factory function that can be used by the script side to create
  static FooScripted *Factory()
  {
    asIScriptContext *ctx = asGetActiveContext();

    // Get the function that is calling the factory so we can be certain it is the FooScript script class
    asIScriptFunction *func = ctx->GetFunction(0);
    if( func->GetObjectType() == 0 || std::string(func->GetObjectType()->GetName()) != "FooScripted" )
    {
      ctx->SetException("Invalid attempt to manually instantiate FooScript_t");
      return 0;
    }

    // Get the this pointer from the calling function so the FooScript C++
    // class can be linked with the FooScript script class
    asIScriptObject *obj = reinterpret_cast<asIScriptObject*>(ctx->GetThisPointer(0));

    return new FooScripted(obj);
  }

  // Reference counting
  void AddRef()
  {
    m_refCount++;

    // Increment also the reference counter to the script side so
    // it isn't accidentally destroyed before the C++ side
    if( !m_isDead->Get() )
      m_obj->AddRef();
  }
  void Release()
  {
    // Release the script instance too
    if( !m_isDead->Get() )
      m_obj->Release();

    if( --m_refCount == 0 ) delete this;
  }

  // Assignment operator
  FooScripted &operator=(const FooScripted &o)
  {
    // Copy only the content, not the script proxy class
    m_value = o.m_value;
    return *this;
  }

protected:

  // The constructor and destructor are indirectly called
  FooScripted(asIScriptObject *obj) : m_obj(0), m_isDead(0), m_value(0), m_refCount(1)
  {
    // Get the weak ref flag for the script object to
    // avoid holding a strong reference to the script class
    m_isDead = obj->GetWeakRefFlag();
    m_isDead->AddRef();

    m_obj = obj;
  }

  ~FooScripted()
  {
    // Release the weak ref flag
    m_isDead->Release();
  }

  // Reference count
  int m_refCount;

  // The C++ side holds a weak link to the script side to
  // avoid a circular reference between the C++ side and
  // script side
  asILockableSharedBool *m_isDead;
  asIScriptObject *m_obj;
};
\endcode

This type is registered with the engine as the following:

\code
void RegisterFooScripted(asIScriptEngine *engine)
{
  engine->RegisterObjectType("FooScripted_t", 0, asOBJ_REF);
  engine->RegisterObjectBehaviour("FooScripted_t", asBEHAVE_FACTORY, "FooScripted_t @f()", asFUNCTION(FooScripted::Factory), asCALL_CDECL);
  engine->RegisterObjectBehaviour("FooScripted_t", asBEHAVE_ADDREF, "void f()", asMETHOD(FooScripted, AddRef), asCALL_THISCALL);
  engine->RegisterObjectBehaviour("FooScripted_t", asBEHAVE_RELEASE, "void f()", asMETHOD(FooScripted, Release), asCALL_THISCALL);
  engine->RegisterObjectMethod("FooScripted_t", "FooScripted_t &opAssign(const FooScripted_t &in)", asMETHOD(FooScripted, operator=), asCALL_THISCALL);
  engine->RegisterObjectMethod("FooScripted_t", "void CallMe()", asMETHOD(FooScripted, CallMe), asCALL_THISCALL);
  engine->RegisterObjectProperty("FooScripted_t", "int m_value", asOFFSET(FooScripted, m_value));
}
\endcode

The script side is declared as \ref doc_script_shared "shared" so it can be used in all script modules.
It is also declared as \ref doc_script_class_inheritance_2 "abstract" so it cannot be instantiated by
itself, only as a parent class of another script class.

This script section should preferably be included automatically by the application in
all the modules that should be able to derive from the FooScripted class.

  // On the script side
  shared abstract class FooScripted
  {
    // Allow scripts to create instances
    FooScripted()
    {
      // Create the C++ side of the proxy
      \@m_obj = FooScripted_t();
    }

    // The copy constructor performs a deep copy
    FooScripted(const FooScripted &o)
    {
      // Create a new C++ instance and copy content
      \@m_obj = FooScripted_t();
      m_obj = o.m_obj;
    }

    // Do a deep a copy of the C++ object
    FooScripted &opAssign(const FooScripted &o)
    {
      // copy content of C++ instance
      m_obj = o.m_obj;
      return this;
    }

    // The script side forwards the call to the C++ side
    void CallMe() { m_obj.CallMe(); }

    // The C++ side property is exposed to the script through accessors
    int m_value
    {
      get { return m_obj.m_value; }
      set { m_obj.m_value = value; }
    }

    // The script class can be implicitly cast to the C++ type through the opImplCast method
    FooScripted_t \@opImplCast() { return m_obj; }

    // Hold a reference to the C++ side of the proxy
    private FooScripted_t \@m_obj;
  }

Now the scripts classes can derive from the FooScripted class
and access the properties and methods of the parent class normally.

  // Implement a script class that derives from the application class
  class FooDerived : FooScripted
  {
    void CallMe()
    {
       m_value += 1;
    }
  }

  void main()
  {
    // When newly created the m_value is 0
    FooDerived d;
    assert( d.m_value == 0 );

    // When calling the method the m_value is incremented with 1
    d.CallMe();
    assert( d.m_value == 1 );
  }

It is of course also possible to create an instance of the scripted class from
the application and access it through the FooScripted C++ proxy, thus making
it transparent from the rest of the application that the implementation is actually
in the script.

\code
FooScripted *CreateFooDerived(asIScriptEngine *engine)
{
  // Create an instance of the FooDerived script class that inherits from the FooScripted C++ class
  asIScriptObject *obj = reinterpret_cast<asIScriptObject*>(engine->CreateScriptObject(mod->GetTypeInfoByName("FooDerived")));

  // Get the pointer to the C++ side of the FooScripted class
  FooScripted *obj2 = *reinterpret_cast<FooScripted**>(obj->GetAddressOfProperty(0));

  // Increase the reference count to the C++ object, as this is what will
  // be used to control the life time of the object from the application side
  obj2->AddRef();

  // Release the reference to the script side
  obj->Release();

  return obj2;
}

void Foo(asIScriptEngine *engine)
{
  FooScripted *obj = CreateFooDerived(engine);

  // Once the object is created the application can access it normally through
  // the FooScripted pointer, without having to know that the implementation
  // is actually done in the script.

  // When newly created the m_value is 0
  assert( obj->m_value == 0 );

  // When calling the method the m_value is incremented with 1 by the script
  obj->CallMe();
  assert( obj->m_value == 1 );

  // Release the object to destroy the instance (this will also destroy the script side)
  obj->Release();
}
\endcode

*/


code:
/**

\page doc_adv_jit How to build a JIT compiler

AngelScript doesn't provide a built-in JIT compiler, instead it permits an external JIT compiler to be implemented
through a public interface.

To use JIT compilation, the scripts must be compiled with a few extra instructions that provide hints to the JIT compiler
and also entry points so that the VM will know when to pass control to the JIT compiled function. By default this is
turned off, and must thus be turned on by setting the engine property \ref asEP_INCLUDE_JIT_INSTRUCTIONS.

Two distinct versions for the JIT compiler interface is supported. By default version 1 is used, but if version 2 is desired
it must be explicitly set with \ref asIScriptEngine::SetEngineProperty using \ref asEP_JIT_INTERFACE_VERSION.

\section doc_adv_jit_v1 The JIT interface version 1

With version 1, if the application sets the \ref asIJITCompiler with \ref asIScriptEngine::SetJITCompiler "SetJITCompiler"
AngelScript will automatically invoke the \ref asIJITCompiler::CompileFunction with each new script function that is compiled or
\ref doc_adv_precompile "loaded from pre-compiled bytecode". The \ref asJITFunction that is produced will be linked with the script
function as long as the script function is valid. When the script function is destroyed AngelScript will invoke
\ref asIJITCompiler::ReleaseJITFunction for cleanup.

With this interface version there is no way for the JIT compiler to do global optimizations, as it is forced to compile the JIT
function with only the knowledge of the currently compiled script function and cannot go back to update the JIT functions afterwards.

\section doc_adv_jit_v2 The JIT interface version 2

With version 2, if the application sets the \ref asIJITCompilerV2 with \ref asIScriptEngine::SetJITCompiler "SetJITCompiler"
AngelScript will also automatically invoke the \ref asIJITCompilerV2::NewFunction with each new script function that is compiled or
\ref doc_adv_precompile "loaded from pre-compiled bytecode".

The difference is that for version 2 it is optional to provide the JIT function at this time. The JIT compiler can opt to defer the
compilation until the full script has been compiled or loaded. This will allow it to see all functions and can make global
optimizations, e.g. do inlining, etc. When the \ref asJITFunction is compiled the JIT compiler must link it with the script function using
\ref asIScriptFunction::SetJITFunction.

Should the JIT compiler not want to build a map of all script functions with the call to NewFunction it is also possible to iterate over
all existing script functions with \ref asIScriptEngine::GetLastFunctionId and \ref asIScriptEngine::GetFunctionById "GetFunctionById".

AngelScript will call \ref asIJITCompilerV2::CleanFunction any time the JIT function is replaced on the script function, or when the
script function is destroyed.

\section doc_adv_jit_3 The structure of the JIT function

The \ref asJITFunction "JIT compiled function" must follow certain rules in order to behave well with the virtual machine. The intention
is that the VM will pass the control to the JIT function, and when the execution is to be suspended the JIT function
returns the control to the VM, updating the internal state of the VM so that the VM can resume the execution when
requested. Each time the JIT function returns control to the VM it must make sure that the \ref asSVMRegisters "VM registers" and stack values
have been updated according to the code that was executed.

The byte code will have a special instruction, \ref asBC_JitEntry "JitEntry", which defines the positions where the VM
can pass the control to the JIT function. These are usually placed for every script statement, and after each instruction
that calls another function. This implies that the JIT compiled function needs to be able to start the execution at
different points based on the argument in the JitEntry instruction. The value of the argument is defined by the JIT compiler
and how it is interpreted is also up to the JIT compiler, with the exception of 0 that means that the control should not be
passed to the JIT function.

Some byte code instructions are not meant to be converted into native code. These are usually the ones that have a more
global effect on the VM, e.g. the instructions that setup a call to a new script function, or that return from a previous
instruction. When these functions are encountered, the JIT function should return the control to the VM, and then the VM
will execute the instruction.

Other byte code instructions may be partially implemented by the JIT function, for example those that can throw an exception
based on specific conditions. One such example is the instructions for divisions, if the divider is 0 the VM will set
an exception and abort the execution. For these instructions the JIT compiler should preferrably implement the condition
that doesn't throw an exception, and if an exception is to be thrown the JIT function will instead break out to the VM.

The following shows a possible structure of a JIT compiled function:

<pre>
  void jitCompiledFunc(asSVMRegisters *regs, asPWORD jitArg)
  {
    Read desired VM registers into CPU registers.
    Jump to the current position of the function based on the 'jitArg' argument.
  1:
    Execute code in block 1.
    Jump to exit if an illegal operation is done, e.g. divide by zero.
    Jump to exit if block ends with an instruction that should not be executed by JIT function.
  2:
    ...
  3:
    ...
  exit:
    Update the VM registers before returning control to VM.
    If necessary the function can invoke the methods of the context informed
    in the regs, e.g. to suspend the execution, or to set a script exception.
  }
</pre>

\section doc_adv_jit_2 Traversing the byte code

\code
int CJITCompiler::CompileFunction(asIScriptFunction *func, asJITFunction *output)
{
  bool success = StartNewCompilation();

  // Get the script byte code
  asUINT   length;
  asDWORD *byteCode = func->GetByteCode(&length);
  asDWORD *end = byteCode + length;

  while( byteCode < end )
  {
    // Determine the instruction
    asEBCInstr op = asEBCInstr(*(asBYTE*)byteCode);
    switch( op )
    {
    // Translate each byte code instruction into native code.
    // The codes that cannot be translated should return the control
    // to the VM, so that it can continue the processing. When
    // the VM encounters the next JitEntry instruction it will
    // transfer the control back to the JIT function.
    ...

    case asBC_JitEntry:
      // Update the argument for the JitEntry instruction with
      // the argument that should be sent to the jit function.
      // Remember that 0 means that the VM should not pass
      // control to the JIT function.
      asBC_PTRARG(byteCode) = DetermineJitEntryArg();
      break;
    }

    // Move to next instruction
    byteCode += asBCTypeSize[asBCInfo[op].type];
  }

  if( success )
  {
    *output = GetCompiledFunction();
    return 0;
  }

  return -1;
}
\endcode

The following macros should be used to read the arguments from the bytecode instruction.
The layout of the arguments is determined from the \ref asBCInfo array.

 - \ref asBC_DWORDARG
 - \ref asBC_INTARG
 - \ref asBC_QWORDARG
 - \ref asBC_FLOATARG
 - \ref asBC_PTRARG
 - \ref asBC_WORDARG0
 - \ref asBC_WORDARG1
 - \ref asBC_SWORDARG0
 - \ref asBC_SWORDARG1
 - \ref asBC_SWORDARG2

What each \ref asEBCInstr "byte code" instruction does is described in \ref doc_adv_jit_1, but the exact
implementation of each byte code instruction is best determined from the implementation
in the VM, i.e. the asCScriptContext::ExecuteNext method.

\page doc_adv_jit_1 Byte code instructions

This page gives a brief description of each of the byte code instructions that the virtual machine has.

 - \ref doc_adv_jit_1_1
 - \ref doc_adv_jit_1_2
 - \ref doc_adv_jit_1_3
 - \ref doc_adv_jit_1_4
 - \ref doc_adv_jit_1_5
 - \ref doc_adv_jit_1_6
 - \ref doc_adv_jit_1_7
 - \ref doc_adv_jit_1_8
 - \ref doc_adv_jit_1_9
 - \ref doc_adv_jit_1_10

\section doc_adv_jit_1_1 Object management

Perform a bitwise copy of a memory buffer to another

 - \ref asBC_COPY

Push the address and length of a string on the stack

 - \ref asBC_STR

Allocate the memory for an object and setup the VM to execute the constructor

 - \ref asBC_ALLOC

Release the memory of an object or list buffer

 - \ref asBC_FREE

Move the address in an object variable to the object register. The address in the variable is then cleared.

 - \ref asBC_LOADOBJ

Move the address from the object register to an object variable. The address in the object register is then cleared.

 - \ref asBC_STOREOBJ

Copy the object handle from one address to another. The reference count of the object is updated to reflect the copy.

 - \ref asBC_REFCPY

Copy the object handle on stack to a handle in a variable. The reference count of the object is updated to reflect the copy.

 - \ref asBC_RefCpyV

Push the pointer of an object type on the stack

 - \ref asBC_OBJTYPE

Push the type id on the stack

 - \ref asBC_TYPEID

Pop an address to a script object from the stack. If the desired cast can be made store the address in the object register.

 - \ref asBC_Cast

Push the function pointer on the stack

 - \ref asBC_FuncPtr

Load the address to a property of the object into the value register. Substitutes the sequence PshV4/8, ADDSi, PopRPtr.

 - \ref asBC_LoadThisR
 - \ref asBC_LoadRObjR

Load the address to a property of a value object into the value register. Substitutes the sequence PSF, ADDSi, PopRPtr.

 - \ref asBC_LoadVObjR

\section doc_adv_jit_1_2 Math instructions

Negate the value in the variable. The original value is overwritten.

 - \ref asBC_NEGi
 - \ref asBC_NEGf
 - \ref asBC_NEGd
 - \ref asBC_NEGi64

Perform the operation with the value of two variables and store the result in a third variable.

 - \ref asBC_ADDi
 - \ref asBC_SUBi
 - \ref asBC_MULi
 - \ref asBC_DIVi
 - \ref asBC_MODi
 - \ref asBC_POWi
 - \ref asBC_POWu

 - \ref asBC_ADDf
 - \ref asBC_SUBf
 - \ref asBC_MULf
 - \ref asBC_DIVf
 - \ref asBC_MODf
 - \ref asBC_POWf

 - \ref asBC_ADDd
 - \ref asBC_SUBd
 - \ref asBC_MULd
 - \ref asBC_DIVd
 - \ref asBC_MODd
 - \ref asBC_POWd
 - \ref asBC_POWdi

 - \ref asBC_ADDi64
 - \ref asBC_SUBi64
 - \ref asBC_MULi64
 - \ref asBC_DIVi64
 - \ref asBC_MODi64
 - \ref asBC_POWi64
 - \ref asBC_POWu64

Perform the operation with a constant value and the value of the variable. The original value is overwritten.

 - \ref asBC_ADDIi
 - \ref asBC_SUBIi
 - \ref asBC_MULIi

 - \ref asBC_ADDIf
 - \ref asBC_SUBIf
 - \ref asBC_MULIf

\section doc_adv_jit_1_3 Bitwise instructions

Perform a boolean not operation on the value in the variable. The original value is overwritten.

 - \ref asBC_NOT

Perform a bitwise complement on the value in the variable. The original value is overwritten.

 - \ref asBC_BNOT
 - \ref asBC_BNOT64

Perform the operation with the value of two variables and store the result in a third variable.

 - \ref asBC_BAND
 - \ref asBC_BOR
 - \ref asBC_BXOR

 - \ref asBC_BAND64
 - \ref asBC_BOR64
 - \ref asBC_BXOR64

 - \ref asBC_BSLL
 - \ref asBC_BSRL
 - \ref asBC_BSRA

 - \ref asBC_BSLL64
 - \ref asBC_BSRL64
 - \ref asBC_BSRA64

\section doc_adv_jit_1_4 Comparisons

Compare the value of two variables and store the result in the value register.

 - \ref asBC_CMPi
 - \ref asBC_CMPu
 - \ref asBC_CMPf
 - \ref asBC_CMPd
 - \ref asBC_CMPi64
 - \ref asBC_CMPu64
 - \ref asBC_CmpPtr

Compare the value of a variable with a constant and store the result in the value register.

 - \ref asBC_CMPIi
 - \ref asBC_CMPIu
 - \ref asBC_CMPIf

Test the value in the value register. Update the value register according to the result.

 - \ref asBC_TZ
 - \ref asBC_TNZ
 - \ref asBC_TS
 - \ref asBC_TNS
 - \ref asBC_TP
 - \ref asBC_TNP

\section doc_adv_jit_1_5 Type conversions

Convert the value in the variable. The original value is overwritten.

 - \ref asBC_iTOb
 - \ref asBC_iTOw
 - \ref asBC_sbTOi
 - \ref asBC_swTOi
 - \ref asBC_ubTOi
 - \ref asBC_uwTOi

 - \ref asBC_iTOf
 - \ref asBC_fTOi
 - \ref asBC_uTOf
 - \ref asBC_fTOu

 - \ref asBC_dTOi64
 - \ref asBC_dTOu64
 - \ref asBC_i64TOd
 - \ref asBC_u64TOd

Convert the value of a variable and store the result in another variable.

 - \ref asBC_dTOi
 - \ref asBC_dTOu
 - \ref asBC_dTOf
 - \ref asBC_iTOd
 - \ref asBC_uTOd
 - \ref asBC_fTOd

 - \ref asBC_i64TOi
 - \ref asBC_i64TOf
 - \ref asBC_u64TOf
 - \ref asBC_uTOi64
 - \ref asBC_iTOi64
 - \ref asBC_fTOi64
 - \ref asBC_fTOu64

\section doc_adv_jit_1_6 Increment and decrement

Increment or decrement the value pointed to by the address in the value register.

 - \ref asBC_INCi8
 - \ref asBC_DECi8
 - \ref asBC_INCi16
 - \ref asBC_DECi16
 - \ref asBC_INCi
 - \ref asBC_DECi
 - \ref asBC_INCi64
 - \ref asBC_DECi64
 - \ref asBC_INCf
 - \ref asBC_DECf
 - \ref asBC_INCd
 - \ref asBC_DECd

Increment or decrement the value in the variable.

 - \ref asBC_IncVi
 - \ref asBC_DecVi

\section doc_adv_jit_1_7 Flow control

Setup the VM to begin execution of the other script function

 - \ref asBC_CALL
 - \ref asBC_CALLINTF
 - \ref asBC_CALLBND
 - \ref asBC_CallPtr

Setup the VM to return to the calling function

 - \ref asBC_RET

Make an unconditional jump to a relative position

 - \ref asBC_JMP

Make a jump to a relative position depending on the value in the value register

 - \ref asBC_JZ
 - \ref asBC_JNZ
 - \ref asBC_JS
 - \ref asBC_JNS
 - \ref asBC_JP
 - \ref asBC_JNP
 - \ref asBC_JMPP
 - \ref asBC_JLowZ
 - \ref asBC_JLowNZ

Call an application registered function

 - \ref asBC_CALLSYS
 - \ref asBC_Thiscall1

Save the state and suspend execution, then return control to the application

 - \ref asBC_SUSPEND

Give control of execution to the JIT compiled function

 - \ref asBC_JitEntry

\section doc_adv_jit_1_8 Stack and data management

Push a constant value on the stack.

 - \ref asBC_PshC4
 - \ref asBC_PshC8
 - \ref asBC_PshNull

Push the stack frame pointer on the stack.

 - \ref asBC_PSF

Swap the top values on the stack.

 - \ref asBC_SwapPtr

Dereference top pointer on stack. Raises exception if pointer is null.

 - \ref asBC_RDSPtr

Add an offset to the top address on the stack. Raises exception if address is null.

 - \ref asBC_ADDSi

Push the value of a variable on the stack.

 - \ref asBC_PshV4
 - \ref asBC_PshV8
 - \ref asBC_PshVPtr

Initialize the value of a variable with a constant.

 - \ref asBC_SetV1
 - \ref asBC_SetV2
 - \ref asBC_SetV4
 - \ref asBC_SetV8
 - \ref asBC_ClrVPtr

Copy the value of one variable to another.

 - \ref asBC_CpyVtoV4
 - \ref asBC_CpyVtoV8

Validate that an expected pointer is not null.

 - \ref asBC_CHKREF
 - \ref asBC_ChkRefS
 - \ref asBC_ChkNullV
 - \ref asBC_ChkNullS

Push the variable index with the size of a pointer on the stack.

 - \ref asBC_VAR

Replace a variable index on the stack with an address.

 - \ref asBC_GETREF
 - \ref asBC_GETOBJ
 - \ref asBC_GETOBJREF

Pop and discard an address from the stack.

 - \ref asBC_PopPtr

Pop or push an address to or from the value register.

 - \ref asBC_PopRPtr
 - \ref asBC_PshRPtr

Copy a value between value register and a variable.

 - \ref asBC_CpyVtoR4
 - \ref asBC_CpyVtoR8
 - \ref asBC_CpyRtoV4
 - \ref asBC_CpyRtoV8

Copy a value from a variable to the address held in the value register

 - \ref asBC_WRTV1
 - \ref asBC_WRTV2
 - \ref asBC_WRTV4
 - \ref asBC_WRTV8

Copy a value from the address held in the value register to a variable

 - \ref asBC_RDR1
 - \ref asBC_RDR2
 - \ref asBC_RDR4
 - \ref asBC_RDR8

Load the address of the variable into the value register

 - \ref asBC_LDV

Clear the upper bytes of the value register

 - \ref asBC_ClrHi

\section doc_adv_jit_1_9 Global variables

Push the value of a global variable on the stack

 - \ref asBC_PshG4
 - \ref asBC_PshGPtr

Load the address of a global variable into the value register

 - \ref asBC_LDG

Load the address of a global variable into the value register and copy the value of the global variable to local variable

 - \ref asBC_LdGRdR4

Copy a value between local variable and global variable.

 - \ref asBC_CpyVtoG4
 - \ref asBC_CpyGtoV4

Push the address of the global variable on the stack.

 - \ref asBC_PGA

Initialize the variable of a global variable with a constant.

 - \ref asBC_SetG4

\section doc_adv_jit_1_10 Initialization list management

Allocates the memory for the initialization list buffer

- \ref asBC_AllocMem

Sets the number of elements that will be repeated afterwards

- \ref asBC_SetListSize

Sets the type of the next element

- \ref asBC_SetListType

Pushes the address of the list element on the stack

- \ref asBC_PshListElmnt

*/


code:
/**

\page doc_adv_multithread Multithreading

AngelScript supports multithreading, though not yet on all platforms. You can determine if multithreading
is supported on your platform by calling the \ref asGetLibraryOptions function and checking the returned
string for <code>"AS_NO_THREADS"</code>. If the identifier is in the returned string then multithreading is
not supported.

Even if you don't want or can't use multithreading, you can still write applications that execute
\ref doc_adv_concurrent "multiple scripts simultaneously".

\section doc_adv_multithread_1 Things to think about with a multithreaded environment

 - If you plan on creating engines in multiple threads, the application should call \ref asPrepareMultithread
   before the first engine is created, and \ref asUnprepareMultithread after the last engine
   has been released. This is to avoid race conditions when the engine creates the internal shared thread manager.
   If only one script engine is used, then it is not necessary to do go through these extra steps.

 - Always call \ref asThreadCleanup before terminating a thread that accesses the script engine. If this
   is not done, the memory allocated specifically for that thread will be lost until the script engine
   is freed.

 - If the application is composed of multiple application modules (dlls) then it may be necessary to
   share a single thread manager across the modules. Do this by calling \ref asGetThreadManager in the
   main module and then call \ref asPrepareMultithread on the secondary modules with the returned pointer.

 - Multiple threads may execute scripts in separate contexts. The contexts may execute scripts from the
   same module, but if the module has global variables you need to make sure the scripts perform proper
   access control so that they do not get corrupted, if multiple threads try to update them simultaneously.

 - The engine will only allow one thread to build scripts at any one time, since this is something that
   changes the internal state of the engine and cannot safely be done in multiple threads simultaneously.

 - Reference counters for objects that will be referred to by scripts in different threads must be thread safe
   in order to avoid race conditions as multiple threads attempt to update the same reference counter.
   The library provides a pair of functions to facilitate the implementation of thread safe reference counters.
   See \ref asAtomicInc and \ref asAtomicDec.

 - Resources that are shared by script modules such as registered properties and objects must be protected
   by the application for simultaneous access, as the script engine doesn't do this automatically. A read-write
   lock is provided by the library that can be used for this. See \ref asAcquireExclusiveLock,
   \ref asReleaseExclusiveLock, \ref asAcquireSharedLock, and \ref asReleaseSharedLock.

 - If you use \ref doc_adv_custom_options_engine "automatic garbage collection" (turned on by default) then
   you must make sure the behaviours registered for types to \ref doc_gc_object "support garbage collection"
   must be thread safe as the garbage collector can be invoked from any thread that is executing a script.

 - Many of the add-ons are not thread safe. Either create your own or make sure you review the add-ons you
   wish to use to guarantee thread safety.

\section doc_adv_fibers Fibers

AngelScript can be used with fibers as well. However, as fibers are not real threads you need to be careful
if multiple fibers need to execute scripts. AngelScript keeps track of active contexts by pushing and popping
the context pointers on a stack. With fibers you can easily corrupt this stack if you do not pay attention
to where and when script executions are performed.

Try to avoid switching fibers when a script is executing, instead you should \ref asIScriptContext::Suspend "suspend" the current script
execution and only switch to the other fiber when the context's \ref asIScriptContext::Execute "Execute" method returns. If you really
must switch fibers while executing a script, then make sure the second fiber initiates and concludes its own
script execution before switching back to the original fiber.

*/


code:
/**

\page doc_adv_namespace Using namespaces

Namespaces can be used to group related functions and other entities together. Doing so avoids
potential conflicts with other entities that happen to use the same name, but is otherwise unrelated.

Namespaces can be used in the application registered interface, as well as in the \ref doc_global_namespace "scripts".

\section doc_adv_namespace_reg Registering the interface with namespaces

To register a function, or other entity in a specific namespace, the application should first call
the method \ref asIScriptEngine::SetDefaultNamespace "SetDefaultNamespace" to define the desired namespace.
After that the registration follows the normal procedure as described in the \ref doc_register_api_topic
"chapter on registering the interface".

\code
void RegisterInNamespace(asIScriptEngine *engine)
{
  int r;

  // Register the type and function in the namespace
  r = engine->SetDefaultNamespace("myspace"); assert( r >= 0 );
  r = engine->RegisterObjectType("mytype", 0, asOBJ_REF); assert( r >= 0 );
  r = engine->RegisterGlobalFunction("void myfunc()", asFUNCTION(myfunc), asCALL_CDECL); assert( r >= 0 );
}
\endcode

If desired nested namespaces can also be used by separating them with the scoping token, ::, e.g.
SetDefaultNamespace("outer::inner");

\section doc_adv_namespace_enum Finding entities in namespaces

As namespaces allow multiple declarations with the same signature, it is necessary to specify in
which namespace a search for an entity is to be done. This is also done with the SetDefaultNamespace
method. This applies to both the \ref asIScriptEngine::SetDefaultNamespace "engine" and the
\ref asIScriptModule::SetDefaultNamespace "module" interfaces.

\code
void FindFuncInNamespace(asIScriptModule *module)
{
  int r;

  // Look for the function in the namespace, i.e. myspace::myfunc
  r = module->SetDefaultNamespace("myspace"); assert( r >= 0 );
  asIScriptFunction *func1 = module->GetFunctionByName("myfunc");

  // When searching for a matching declaration the default namespace is also
  // used unless an explicit namespace is given in the declaration itself.
  asIScriptFunction *funcA = module->GetFunctionByDecl("void myfunc()");
  asIScriptFunction *funcB = module->GetFunctionByDecl("void myspace::myfunc()");

  assert( funcA == funcB );
}
\endcode

*/


code:
/**

\page doc_adv_precompile Pre-compiled byte code

Sometimes it may be useful to use pre-compiled bytecode instead of re-building the
scripts every time a script is loaded. This can for example reduce load times, or
if scripts are transferred over the net, it can reduce the transfer time for large scripts.

To save already compiled code you should call the \ref asIScriptModule::SaveByteCode "SaveByteCode"
method on the \ref asIScriptModule, passing in a pointer to the object that implements the \ref
asIBinaryStream interface. The script module will then push all the bytecode and related data onto
this object with the \ref asIBinaryStream::Write "Write" method.

When loading the pre-compiled bytecode you should first get an instance of the \ref asIScriptModule,
just as if compiling a new script. Instead of calling AddScriptSection followed by Build you will
call the \ref asIScriptModule::LoadByteCode "LoadByteCode" method, passing it a pointer to the binary
stream object. The script module will then pull all the bytecode and related data from that object with
the \ref asIBinaryStream::Read "Read" method to reconstruct the script module.

Here's a very simple example of how to implement the \ref asIBinaryStream interface:

\code
class CBytecodeStream : public asIBinaryStream
{
public:
  CBytecodeStream(FILE *fp) : f(fp) {}

  void Write(const void *ptr, asUINT size)
  {
    if( size == 0 ) return;
    fwrite(ptr, size, 1, f);
  }
  void Read(void *ptr, asUINT size)
  {
    if( size == 0 ) return;
    fread(ptr, size, 1, f);
  }

protected:
  FILE *f;
};
\endcode

\see \ref doc_samples_asbuild

\section doc_adv_precompile_1 Things to remember

 - All the objects, methods, properties, etc, used when compiling the bytecode must also be registered
   when loading the precompiled bytecode, otherwise the load will fail when not finding the correct entity.

 - The script engine doesn't perform validation of the pre-compiled bytecode, so the application is
   responsible for authenticating the source. If this authentication isn't performed by the application
   you'll have potential security risks in your application as the bytecode may have been manually
   manipulated to perform otherwise illegal tasks.

 - If the application that compiles the script code is separate from the application that will execute
   them, then you may register the functions and methods with null pointers so you don't need to
   actually implement all of them. Object properties must be registered with different offsets so that
   they can be differentiated by the bytecode loader. You should also set the engine property \ref asEP_INIT_GLOBAL_VARS_AFTER_BUILD
   to false with \ref asIScriptEngine::SetEngineProperty, so the script engine doesn't attempt to initialize
   the global variables after the script has been built. The \ref doc_addon_helpers "helper add-on" has a
   couple of functions to facilitate building an offline compiler.

 - If the application is not going to compile scripts from source code, but only load pre-compiled scripts,
   then it may be beneficial to compile the library with the AS_NO_COMPILER define so as to reduce the size
   of the executable.

 - To reduce the size of the saved bytecode you can strip the debug information from the code. This will skip
   saving information that is not necessary for executing the scripts, such as the name of script sections,
   line numbers, and the name and type of local variables.

 - If the scripts use \ref doc_script_shared "shared entities" then the size of the saved bytecode can be further
   reduced if the entities are declared as \ref doc_script_shared_external "external". To allow the offline compiler
   to compile scripts with external shared entities, the offline compiler must first build another module with all the
   shared entities that should be allowed to be declared as external.

 - The saved bytecode is platform independent with only a couple of exceptions that is unlikely to affect
   application developers. The exceptions are 1) difference in size of primitive types (e.g. bool on older
   Mac PPC platforms) and 2) CPU floating point representation (i.e. IEEE 754 versus non-IEEE 754). Differences
   in pointer size (32bit vs 64bit), CPU endianess, different size of registered types and offsets of registered
   properties are all handled to provide platform independence.

 - The saved bytecode is not guaranteed to be compatible for different versions of the AngelScript library so
   make sure you use the same library version when saving the bytecode that will be used when loading it.

*/


code:
/**

\page doc_adv_reflection Reflection

While the script language doesn't offer built-in functionality for reflection, the application
interface do provide all the necessary methods to enumerate everything within the scripts.

The article on \ref doc_debug "debugging" shows a little of these interfaces with the focus
on debugging rather than reflection. The article on \ref doc_adv_dynamic_build "dynamic compilations"
shows another aspect where scripts may be partially modified at runtime.

The following will do an overview of the available methods for enumerating the various entities in
a script.

\section doc_adv_reflection_vars Enumerating variables and properties

Global variables in a script module are enumerated with the interface \ref asIScriptModule.
Specifically the methods \ref asIScriptModule::GetGlobalVarCount "GetGlobalVarCount" and
\ref asIScriptModule::GetGlobalVar "GetGlobalVar". \ref asIScriptModule::GetGlobalVarIndexByName "GetGlobalVarIndexByName" and
\ref asIScriptModule::GetGlobalVarIndexByDecl "GetGlobalVarIndexByDecl" can be used if the name and/or
declaration of the desired variable is known before hand. To inspect or even modify the value
of the global variable the method \ref asIScriptModule::GetAddressOfGlobalVar "GetAddressOfGlobalVar"
should be used.

The engine interface \ref asIScriptEngine has a similar set of methods for enumerating application
registered global properties, i.e. \ref asIScriptEngine::GetGlobalPropertyCount "GetGlobalPropertyCount",
\ref asIScriptEngine::GetGlobalPropertyByIndex "GetGlobalPropertyByIndex",
\ref asIScriptEngine::GetGlobalPropertyIndexByName "GetGlobalPropertyIndexByName", and
\ref asIScriptEngine::GetGlobalPropertyIndexByDecl "GetGlobalPropertyIndexByDecl".

Member properties of classes are accessed through the \ref asIScriptObject interface for live
object instances, and \ref asITypeInfo interface for inspecting the class declarations without any
live object instance.

Local variables within functions can also be enumerated as long as the script has been compiled with
debug information. These are then enumerated through the \ref asIScriptFunction interface for inspecting
the declarations, and directly through \ref asIScriptContext for inspecting and/or modifying them on the
stack.

\section doc_adv_reflection_funcs Enumerating functions and methods

Global functions in a script are enumerated with the interface \ref asIScriptModule, using the methods
\ref asIScriptModule::GetFunctionCount "GetFunctionCount", \ref asIScriptModule::GetFunctionByIndex "GetFunctionByIndex",
\ref asIScriptModule::GetFunctionByName "GetFunctionByName", and \ref asIScriptModule::GetFunctionByDecl "GetFunctionByDecl".

The engine interface \ref asIScriptEngine also exposes methods for enumerating application registered functions in a similar manner.

To enumerate methods of classes the interface \ref asITypeInfo should be used.

\section doc_adv_reflection_types Enumerating types

\ref asIScriptModule is of course used to enumerate the types declared in the scripts too. The methods
\ref asIScriptModule::GetObjectTypeCount "GetObjectTypeCount", \ref asIScriptModule::GetObjectTypeByIndex "GetObjectTypeByIndex", and
\ref asIScriptModule::GetTypeInfoByName "GetTypeInfoByName" are for enumerating classes and interfaces. The methods
\ref asIScriptModule::GetEnumCount "GetEnumCount" and \ref asIScriptModule::GetEnumByIndex "GetEnumByIndex" are
for enumerating enums.

The \ref asIScriptEngine interface has near identical methods for enumerating the application registered types.

Many of the above methods return values called type ids that describes the type of the respective variable, property, or function argument.
In many cases the type id can be directly inspected as a bitfield to get necessary information on the what the type is. The lower bits
are just a sequence number where the first 12 numbers represents the built-in primitives, and anything higher represents either application
registered types or script declared types. The higher bits indicate if the type represents a primitive, object, or handle. Use the flags
in \ref asETypeIdFlags to do the necessary verifications on the type id.

For type ids that represent object types it may be necessary to obtain the \ref asITypeInfo instance to get further information
on what the type is. The method \ref asIScriptEngine::GetTypeInfoById "GetTypeInfoById" is used to do this translate from type id
to \ref asITypeInfo.

*/


code:
/**

\page doc_adv_scoped_type 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.

\code
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 );
\endcode

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.

\code
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 );
\endcode

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 \ref doc_reg_basicref

*/


code:
/**

\page doc_adv_single_ref_type Registering a single-reference type

A variant of the uninstanciable reference types is the single-reference
type. This is a type that have only 1 reference accessing it, i.e. the script
cannot store any extra references to the object during execution. The script
is forced to use the reference it receives from the application at the moment
the application passes it on to the script.

The reference can be passed to the script through a property, either global
or a class member, or it can be returned from an application registered
function or class method.

The script engine will not permit declaration of functions that take this
type as a parameter, neither as a reference nor as a handle. If that was allowed
it would mean that a reference to the instance is placed on the stack, which
in turn means that it is no longer a single-reference type.

\code
// Registering the type so that it cannot be instanciated
// by the script, nor allow scripts to store references to the type
r = engine->RegisterObjectType("single", 0, asOBJ_REF | asOBJ_NOHANDLE); assert( r >= 0 );
\endcode

This sort of type is most useful when you want to have complete control over
references to an object, for example so that the application can destroy and
recreate objects of the type without having to worry about potential references
held by scripts. This allows the application to control when a script has access
to an object and it's members.

\see \ref doc_reg_basicref

*/


code:
/**

\page doc_adv_template Template types

\todo reference \ref doc_callbacks and show how to register child template func def and example how to use it.

A template type in AngelScript works similarly to how templates work in C++. The scripts
will be able to instantiate different forms of the template type by specifying which subtype
that should be used. The methods for the instance will then be adapted to this subtype, so
that the correct handling of parameters and return types will be applied.

The implementation of the template type is not a C++ template though, instead it must
be implemented as a generic class that can determine what to do dynamically at runtime based
on the subtype for which it was instantiated. This is obviously a lot less efficient than
having specific implementations for each type, and for that reason AngelScript permits the
application to register a template specialization where the extra performance is needed.

This gives the best of both worlds, performance where the subtype is known before hand, and
support for all other types that cannot be pre-determined.

\section doc_adv_template_1 Registering the template type

Template types can be either \ref doc_reg_basicref "reference types" or \ref doc_register_val_type "value types".
Both are registered in a similar manner with only a few differences.

The name of the type is formed by the name of the template type plus the name of the subtype with angle brackets.
Multiple subtypes can be informed, separated by comma. The type flag asOBJ_TEMPLATE must used to tell AngelScript
that it is a template type that is being registered.

\code
// Register the template type as a garbage collected reference type
r = engine->RegisterObjectType("myTemplate<class T>", 0, asOBJ_REF | asOBJ_GC | asOBJ_TEMPLATE); assert( r >= 0 );

// Register another template type as a value type
r = engine->RegisterObjectType("myValueTemplate<class T>", sizeof(MyValueTempl), asOBJ_VALUE | asOBJ_TEMPLATE | asGetTypeTraits<MyValueTempl>()); assert( r >= 0 );
\endcode

The template type doesn't have to be \ref doc_gc_object "garbage collected", but since you may not know
which subtypes it will be instantiated for, it is usually best to implement that support.

When registering the behaviours, methods, and properties for the template type the type is identified
with the name and subtype within angle brackets, but without the class token, e.g. <tt>myTemplate<T></tt>.
The sub type is identified by just the name of the subtype as it was declared in the call to RegisterObjectType.

The factory/construct behaviour for the template type is also different. In order for the implementation to know
which subtype it is instantiated for, the factory/constructor receives the \ref asITypeInfo of the template instance
as a hidden first parameter. When registering the factory/constructor this hidden parameter is reflected in the declaration,
for example as <tt>int &in</tt>.

\code
// Register the factory behaviour
r = engine->RegisterObjectBehaviour("myTemplate<T>", asBEHAVE_FACTORY, "myTemplate<T>@ f(int&in)", asFUNCTIONPR(myTemplateFactory, (asITypeInfo*), myTemplate*), asCALL_CDECL); assert( r >= 0 );

// Register the construct behaviour
r = engine->RegisterObjectBehaviour("myValueTemplate<T>", asBEHAVE_CONSTRUCT, "void f(int&in)", asFUNCTIONPR(myValueTemplConstructor, (asITypeInfo*, void*), void), asCALL_CDECL_OBJLAST); assert( r >= 0 );
\endcode

The list factory/constructor, used to instantiate objects with initialization lists, is registered in the same way, i.e.:

\code
// Register the list factory behaviour
r = engine->RegisterObjectBehaviour("myTemplate<T>", asBEHAVE_LIST_FACTORY, "myTemplate<T>@ f(int&in, uint)", asFUNCTIONPR(myTemplateListFactory, (asITypeInfo*, unsigned int), myTemplate*), asCALL_CDECL); assert( r >= 0 );

// Register the list constructor behaviour
r = engine->RegisterObjectBehaviour("myValueTemplate<T>", asBEHAVE_LIST_CONSTRUCT, "void f(int&in, uint)", asFUNCTIONPR(myValueTemplListConstruct, (asITypeInfo*, unsigned int, void*), void), asCALL_CDECL_OBJLAST); assert( r >= 0 );
\endcode

Remember that since the subtype must be determined dynamically at runtime, it is not possible to declare
functions to receive the subtype by value, nor to return it by value. Instead you'll have to design the
methods and behaviours to take the type by reference. It is possible to use object handles, but then
the script engine won't be able to instantiate the template type for primitives and other values types.

The same goes for object properties. Templates can have properties just like any other class, but the
properties must not be of the template subtype, since it is not known at the time of registration the size
of this type.

\see \ref doc_addon_array

\subsection doc_adv_template_1_1 On subtype replacement for template instances

When a template type is instanced in a declaration, e.g. a variable, the compiler enumerates all the members
of the template type to verify if any subtype is used which requires replacement. In most cases the replacement
is a direct one-to-one mapping, but in cases where the subtype is used as a const parameter reference, then
an additional instruction may be needed to get the expected behaviour.

The following shows a method registered to take the subtype T as a const ref.

\code
r = engine->RegisterObjectMethod("array<T>", "int find(const T&in value) const", ...);
\endcode

If this template is instantiated with a handle as a subtype, e.g. <tt>array<Obj\@></tt>, then the method will become:

  int find(Obj \@const &in value) const

This means that that the parameter takes the handle to a non-read only Obj. The actual handle cannot be
modified, but the object the handle refers to can still be modified by the method. This in turn makes it
impossible for a script to call the method if the handle the script has is read only.

To allow the application developer to say that the method should allow handles to read only objects, a special
keyword <tt>if_handle_then_const</tt> should be used.

\code
r = engine->RegisterObjectMethod("array<T>", "int find(const T&in if_handle_then_const value) const", ...);
\endcode

Now this becomes:

  int find(const Obj \@const &in value) const

This means that the parameter takes a const handle to a read only Obj, i.e. both the handle itself and the
object instance it refers to cannot be modified by the method. Now the script will be able to call the method
both with read only handles and non-read only handles.

\section doc_adv_template_4 Validating template instantiations at compile time

In order to avoid unnecessary runtime validations of invalid template instantiations, the application
should preferably register the \ref asBEHAVE_TEMPLATE_CALLBACK behaviour. This is a special behaviour function
that the script engine will invoke every time a new template instance type is generated. The callback
function can then perform necessary validations to verify if the type can be handled, and if not tell
the engine that the instance isn't supported.

The callback function must be a global function that receives an asITypeInfo pointer, and should return
a boolean. If the template instance is valid the return value should be true.

The function should also take a second parameter with an output reference to a boolean. This parameter
should be set to true by the function if the template instance should not be garbage collected, which will
make AngelScript clear the asOBJ_GC flag for the object type. If the template
instance cannot form any circular references, then it doesn't need to be garbage collected, which reduces
the work that has to be done by the garbage collector.

\code
// Register the template callback
// Observe that the asITypeInfo pointer argument is represented by the int reference
r = engine->RegisterObjectBehaviour("myTemplate<T>", asBEHAVE_TEMPLATE_CALLBACK, "bool f(int &in, bool&out)", asFUNCTION(myTemplateCallback), asCALL_CDECL); assert( r >= 0 );
\endcode

Here's an example callback function:

\code
bool myTemplateCallback(asITypeInfo *ot, bool &dontGarbageCollect)
{
  // This template will only support primitive types
  int typeId = ot->GetSubTypeId();
  if( typeId & asTYPEID_MASK_OBJECT )
  {
    // The script is attempting to instantiate the
    // template with an object type, this is not allowed.
    return false;
  }

  // Tell AngelScript that this instance doesn't require garbage collection
  dontGarbageCollect = true;

  // Primitive types are allowed
  return true;
}
\endcode

\section doc_adv_template_2 Template specializations

When registering a template specialization you override the template instance that AngelScript would normally
do when compiling a declaration with the template type. This allow the application to register a completely
different object with its own implementation for template specializations. Obviously it is recommended that
the template specialization is registered so that to the script writer it is transparent, i.e. try to avoid
having different method names or behaviours for the template type and template specializations.

With the exception of the type name, a template specialization is registered exactly like a \ref doc_register_type "normal type".
The template specialization must be registered in the same namespace as the template itself.

\code
// Register a template specialization for the float subtype
r = engine->RegisterObjectType("myTemplate<float>", 0, asOBJ_REF); assert( r >= 0 );

// Register the factory (there are no hidden parameters for specializations)
r = engine->RegisterObjectBehaviour("myTemplate<float>", asBEHAVE_FACTORY, "myTemplate<float>@ f()", asFUNCTIONPR(myTemplateFloatFactory, (), myTemplateFloat*), asCALL_CDECL); assert( r >= 0 );
\endcode

*/


code:
/**

\page doc_adv_timeout Timeout long running scripts

To prevent long running scripts to freeze the application it may be necessary
to add a way to timeout the execution. This article presents two different
ways to do so.

\section doc_adv_timeout_1 With the line callback

The line callback feature can be used to perform some special treatment
during execution of the scripts. The callback is called for every script
statement, which makes it possible to verify if the script has
executed for too long time and if so suspend the execution to be resumed at
a later time.

Before calling the context's \ref asIScriptContext::Execute "Execute" method,
set the callback function like so:

\code
int ExecuteScriptWithTimeOut(asIScriptContext *ctx)
{
  // Define the timeout as 1 second
  DWORD timeOut = timeGetTime() + 1000;

  // Set up the line callback that will timout the script
  ctx->SetLineCallback(asFUNCTION(LineCallback), &timeOut, asCALL_CDECL);

  // Execute the script
  int status = ctx->Execute();

  // If the status is asEXECUTION_SUSPENDED the script can
  // be resumed by calling this function again.
  return status;
}

// The line callback function is called by the VM for each statement that is executed
void LineCallback(asIScriptContext *ctx, DWORD *timeOut)
{
  // If the time out is reached we suspend the script
  if( *timeOut < timeGetTime() )
    ctx->Suspend();
}
\endcode

Take a look at the sample \ref doc_samples_events to
see this working.

Observe that if the script is compiled with \ref asEP_BUILD_WITHOUT_LINE_CUES, the line
callback will be invoked less frequently, though it is guaranteed to be invoked at least
for every loop or function call.

\section doc_adv_timeout_2 With a secondary thread

A second thread can be set up to suspend the execution after the timeout. This thread
can then be put to sleep so that it doesn't impact performance during the execution.
When the thread wakes up it should call the context's \ref asIScriptContext::Suspend "Suspend" method.

The below shows some possible code for doing this. Note that the code for setting up
the thread is fictive, as this is different for each target OS.

\code
// The variables that are shared between the threads
asIScriptContext *threadCtx;
int threadId;

// This function will be executed in the secondary thread
void SuspendThread()
{
  // Put the thread to sleep until the timeout (1 second)
  Sleep(1000);

  // When we wake-up we call the context's Suspend method
  ctx->Suspend();
}

// This function sets up the timeout thread and executes the script
int ExecuteScriptWithTimeOut(asIScriptContext *ctx)
{
  // Set the shared context pointer before creating the thread
  threadCtx = ctx;

  // Create the thread that will immediately go to sleep
  threadId = CreateThread(SuspendThread);

  // Execute the script
  int status = ctx->Execute();

  // Destroy the secondary thread before releasing the context
  DestroyThread(threadId);

  // Clear the global variables
  threadId = 0;
  threadCtx = 0;

  // If the status is asEXECUTION_SUSPENDED the script can
  // be resumed by calling this function again.

  return status;
}
\endcode

Observe that this way of doing it is safe even if the AngelScript library has been
built without \ref doc_adv_multithread "multithread support".
*/


code:
/**

\page doc_adv_var_type The variable parameter type

\todo reference \ref doc_typeid

The application can register functions that take a reference to a variable
type, which means that the function can receive a reference to a variable of
any type. This is useful when making generic containers.

When a function is registered with this special parameter type, the
function will receive both the reference and an extra argument with the type
id of the variable type. The reference refers to the actual value that the
caller sent, i.e. if the expression is an object handle then the reference
will refer to the handle, not the actual object.

\code
// An example usage with a native function
engine->RegisterGlobalFunction("void func_c(?&in)", asFUNCTION(func_c), asCALL_CDECL);

void func_c(void *ref, int typeId)
{
    // Do something with the reference

    // The type of the reference is determined through the type id
}

// An example usage with a generic function
engine->RegisterGlobalFunction("void func_g(?&in)", asFUNCTION(func_g), asCALL_GENERIC);

void func_g(asIScriptGeneric *gen)
{
    void *ref = gen->GetArgAddress(0);
    int typeId = gen->GetArgTypeId(0);

    func_c(ref, typeId);
}
\endcode

The variable type can also be used with out references, but not
with inout references. Currently it can only be used with global
functions, object constructors, and object methods. It cannot be used with
other behaviours and operators.

The variable type is not available within scripts, so it can only be used
to register application functions.

\see \ref doc_addon_any and \ref doc_addon_dict for examples

\section doc_adv_var_type_1 Variable conversion operators

The variable parameter type can also be used in special versions of \ref doc_script_class_conv "the opConv and opCast"
operator overloads. This is especially useful for generic container types that need to
be able to hold any type of content.

 - void opCast(?&out)
 - void opConv(?&out)

\see \ref doc_addon_handle and \ref doc_addon_dict for examples

*/


code:
/**

\page doc_adv_weakref Weak references

Even though AngelScript uses a \ref doc_gc "garbage collector" to resolve cyclic references weak references
may still come in handy. Weak references are especifically useful in scenarios were an object wants to be
able to access other objects, but do not want to kept them alive longer than necessary.

AngelScript supports weak references with the use of shared booleans. The code that wants to keep a weak
reference to an object should obtain the weakref flag from that object, which is a shared boolean, and before
using the pointer to the object it should check if this flag has been set to indicate that the object is no
longer alive.

Script classes automatically supports weak references without the script writing having to do anything.
Application registered types on the other hand must register the behaviour \ref asBEHAVE_GET_WEAKREF_FLAG
and implement the logic to set the flag upon destroying the object.

The following code shows how to do a thread safe implementation:

\code
class MyClass
{
public:
  MyClass() { refCount = 1; weakRefFlag = 0; }
  void AddRef() { asAtomicInc(refCount); }
  void Release()
  {
    // If the weak ref flag exists it is because someone held a weak ref
    // and that someone may add a reference to the object at any time. It
    // is ok to check the existance of the weakRefFlag without locking here
    // because if the refCount is 1 then no other thread is currently
    // creating the weakRefFlag.
    if( refCount == 1 && weakRefFlag )
    {
      // Set the flag to tell others that the object is no longer alive
      // We must do this before decreasing the refCount to 0 so we don't
      // end up with a race condition between this thread attempting to
      // destroy the object and the other that temporary added a strong
      // ref from the weak ref.
      weakRefFlag->Set(true);
    }

    if( asAtomicDec(refCount) == 0 )
      delete this;
  }
  asILockableSharedBool *GetWeakRefFlag()
  {
    if( !weakRefFlag )
    {
      // Lock globally so no other thread can attempt
      // to create a shared bool at the same time
      asAcquireExclusiveLock();

      // Make sure another thread didn't create the
      // flag while we waited for the lock
      if( !weakRefFlag )
        weakRefFlag = asCreateLockableSharedBool();

      asReleaseExclusiveLock();
    }

    return weakRefFlag;
  }

  static MyClass *Factory() { return new MyClass(); }

protected:
  ~MyClass()
  {
    // Release the weak reference flag that may still
    // be accessed by the code that holds a weak reference
    if( weakRefFlag )
      weakRefFlag->Release();
  }

  int refCount;
  asILockableSharedBool *weakRefFlag;
};
\endcode

The \ref asBEHAVE_GET_WEAKREF_FLAG behaviour for this class is registered like this:

\code
engine->RegisterObjectType("MyClass", 0, asOBJ_REF);
engine->RegisterObjectBehaviour("MyClass", asBEHAVE_ADDREF, "void f()", asMETHOD(MyClass, AddRef), asCALL_THISCALL);
engine->RegisterObjectBehaviour("MyClass", asBEHAVE_RELEASE, "void f()", asMETHOD(MyClass, Release), asCALL_THISCALL);
engine->RegisterObjectBehaviour("MyClass", asBEHAVE_GET_WEAKREF_FLAG, "int &f()", asMETHOD(MyClass, GetWeakRefFlag), asCALL_THISCALL);
\endcode

The script language doesn't have a built-in syntax for weak references. Instead a standard
\ref doc_addon_weakref "weakref add-on" has been implemented to provide this for the applications
that wants to provide this support in the scripts.

*/


code:
/**

\page doc_arrays Custom array type

Like the \ref doc_strings "string type", AngelScript doesn't have a built-in
dynamic array type. Instead the application developers that wishes to allow
dynamic arrays in the scripts should register this in the way that is best
suited for the application. To save time a readily usable add-on is provided
with a fully implemented \ref doc_addon_array "dynamic array type".

If you wish to create your own array type, you'll need to understand how
\ref doc_adv_template "template types" work. A template type is a special form
of registering a type that the engine can then use to instanciate the true
types based on the desired sub-types. This allow a single type registration to
cover all possible array types that the script may need, instead of the
application having to register a specific type for each type of array.

Of course, a generic type like this will have a drawback in performance due to
runtime checks to determine the actual type, so the application should consider
registering \ref doc_adv_template_2 "template specializations" of the most
common array types. This will allow the best optimizations for those types, and
will also permit better interaction with the application as the template
specialization can better match the actual array types that the application
uses.

*/


code:
/**

\page doc_as_vs_cpp_types Datatypes in AngelScript and C++

\section doc_as_vs_cpp_types_1 Primitives

Primitives in AngelScript have direct matches in C++.

AngelScript	C++	Size (bits)

void  	void              	0

int8  	signed char       	8

int16 	signed short      	16

int   	signed int (*)    	32

int64 	signed int64_t    	64

uint8 	unsigned char     	8

uint16	unsigned short    	16

uint  	unsigned int (*)  	32

uint64	unsigned uint64_t 	64

float 	float             	32

double	double            	64

bool  	bool              	8 (**)

(*) An int can actually be of varying size on different platforms in C++, but most commonly it is 32 bits long.
    AngelScript will always assume 32 bits though.

(**) On 32 bit PowerPC platforms the bool type commonly have the size of 32 bit,
     when compiled on such platforms AngelScript also uses 32 bits for the bool type

\section doc_as_vs_cpp_types_5 Strings

AngelScript expects the application to register its own \ref doc_strings "string type",
so the string types should match perfectly.

The char* string type that is so convenient in C++ is however very difficult to use
in a scripted environment where you do not have full control over how it is used. For that
reason it is recommended that you wrap any functions that use the char* string type so
that the string is properly converted to an object that can be safely handled by both
the application and the script engine, e.g. std::string or another class of your preference.

\section doc_as_vs_cpp_types_2 Arrays

AngelScript also expects the application to register the type that should be used for
\ref doc_arrays "dynamic arrays". Normally this is done by registering the \ref doc_addon_array add-on, but
the application is free to do it differently.

It is also possible to have different object types for different array types, so the
application can match the array type exactly with the types used in C++.

\section doc_as_vs_cpp_types_3 Object handles

The AngelScript object handles are reference counted pointers to objects.
This means that for object handles to work, the object must have some way of
counting references, for example an AddRef/Release method pair.

When AngelScript passes an object handle by value to a function it
increases the reference count to count for the argument instance, thus the
function is responsible for releasing the reference once it is finished with
it. In the same manner AngelScript expects any handle returned from a function
to already have the reference accounted for.

However, when registering functions/methods with AngelScript the
application can tell the library that it should automatically take care of
releasing the handle references once a function return, likewise for returned
handles. This is done by adding a + sign to the \@ type modifier. When doing
this an object handle can be safely passed to a C++ function that expects a
normal pointer, but don't release it afterwards.

The syntax for using object handles in AngelScript is similar to C++ references, except the handles can be null and can be reassigned.

AngelScript handle	C++ pointer	C++ reference

obj \@m_obj;	obj *m_obj = nullptr;	n/a

obj \@m_obj = aReference;	obj *m_obj = aReference;	obj &m_obj = *aReference;

m_obj = aValue;	*m_obj = aValue;	m_obj = aValue;

\@m_obj = aReference;	m_obj = aReference;	n/a

m_obj.callMe();	m_obj->callMe();	m_obj.callMe()

\see \ref doc_obj_handle

\section doc_as_vc_cpp_types_5 Script classes and interfaces

All script classes and interfaces are seen as the \ref asIScriptObject type by
the application. The \ref asIScriptObject interface has methods to determine
the actual type of the script class or interface, as well as to interact with the
actual object instance.

\see \ref doc_use_script_class

\section doc_as_vc_cpp_types_6 Function pointers

All script function pointers are seen as the \ref asIScriptFunction type by
the application. The \ref asIScriptFunction type has methods to obtain the name
of the function and the parameter and return types, etc.

\section doc_as_vs_cpp_types_4 Parameter references

Because AngelScript needs to guarantee validity of pointers at all times,
it doesn't always pass references to the true object to the function
parameter. Instead it creates a copy of the object, whose reference is passed
to the function, and if the reference is marked to return a value, the clone
is copied back to the original object (if it still exists) once the function
returns.

Because of this, AngelScript's parameter references are mostly compatible
with C++ references, or pointers, except that the address normally shouldn't be
stored for later use, since the object may be destroyed once the function returns.

If it is necessary to store the address of the object, then object handles
should be used instead.

Reference	Description

&in	A copy of the value is always taken and the
reference to the copy is passed to the function. For script functions this is not
useful, but it is maintained for compatibility with application registered functions.

const &in	If the life time of the value can be
guaranteed to be valid during the execution of the function, the reference to the
true object is passed to the function, otherwise a copy is made.

&out	A reference to an uninitialized value is passed
to the function. When the function returns the value is copied to the true reference.
The argument expression is evaluated only after the function call. This is the best
way to have functions return multiple values.

const &out	Useless as the function wouldn't be able
to modify the value.

&inout	The true reference is always passed to the
function. Only objects that support object handles can be used with this type
as they can always be guaranteed to stay alive during the call.

const &inout	The referred to object will be read-only.

If the application wants parameter references that work like they do in C++,
then this can be allowed by \ref doc_adv_custom_options_lang_mod "setting an engine property".

*/


code:
/**

\page doc_call_script_func Calling a script function

\section doc_call_script_1 Preparing context and executing the function

Normally a script function is executed in a few steps:

Prepare the context

Set the function arguments

Execute the function

Retrieve the return value

The code for this might look something like this:

\code
// Get a script context instance. Usually you'll want to reuse a previously
// created instance to avoid the overhead of allocating the instance with
// each call.
asIScriptContext *ctx = engine->CreateContext();

// Obtain the function from the module. This should preferrably
// be cached if the same function is called multiple times.
asIScriptFunction *func = engine->GetModule(module_name)->GetFunctionByDecl(function_declaration);

// Prepare() must be called to allow the context to prepare the stack
ctx->Prepare(func);

// Set the function arguments
ctx->SetArgDWord(...);

int r = ctx->Execute();
if( r == asEXECUTION_FINISHED )
{
  // The return value is only valid if the execution finished successfully
  asDWORD ret = ctx->GetReturnDWord();
}

// Release the context when you're done with it
ctx->Release();
\endcode

If your application allows the execution to be suspended, either by using
the callback function or registering a function that allow the script to
manually suspend the execution, then the execution function may return
before finishing with the return code asEXECUTION_SUSPENDED. In that case you
can later resume the execution by simply calling the execution function again.

Note that the return value retrieved with GetReturnValue() is only valid
if the script function returned successfully, i.e. if Execute() returned
asEXECUTION_FINISHED.

\section doc_call_script_2 Passing and returning primitives

When calling script functions that take arguments, the values of these
arguments must be set after the call to Prepare() and before Execute().
The arguments are set using a group of SetArg methods:

\code
int SetArgDWord(int arg, asDWORD value);
int SetArgQWord(int arg, asQWORD value);
int SetArgFloat(int arg, float value);
int SetArgDouble(int arg, double value);
int SetArgByte(int arg, asBYTE value);
int SetArgWord(int arg, asWORD value);
\endcode

arg is the argument number, where the first argument is on 0, the second
on 1, and so on. value is the value of the argument. What method to use is
determined by the type of the parameter. For primitive types you can use any of these.
If the parameter type is a reference to a primitive type it is recommended to use the
SetArgAddress() method and pass the pointer as the value. For non-primitive types the
method SetArgObject() should be used, which will be described in the next section.

\code
// The context has been prepared for a script
// function with the following signature:
// int function(int, double, bool, int &out)

// Put the arguments on the context stack, starting with the first one
ctx->SetArgDWord(0, 1);
ctx->SetArgDouble(1, 3.141592);
ctx->SetArgByte(2, true);
int val;
ctx->SetArgAddress(3, &val);
\endcode

Once the script function has been executed the return value is retrieved in
a similar way using the group of GetReturn methods:

\code
asDWORD GetReturnDWord();
asQWORD GetReturnQWord();
float   GetReturnFloat();
double  GetReturnDouble();
asBYTE  GetReturnByte();
asWORD  GetReturnWord();
\endcode

Note that you must make sure the returned value is in fact valid, for
example if the script function was interrupted by a script exception the value
would not be valid. You do this by verifying the return code from Execute() or
GetState(), where the return code should be asEXECUTION_FINISHED.

\section doc_call_script_3 Passing and returning objects

Passing registered object types to a script function is done in a similar
way to how primitive types are passed. The function to use is SetArgObject():

\code
int SetArgObject(int arg, void *object);
\endcode

arg is the argument number, just like the other SetArg methods.
object is a pointer to the object you wish to pass.

This same method is used both for parameters passed by value and for those
passed by reference. The library will automatically make a copy of the object
if the parameter is defined to be passed by value.

\code
// The complex object we wish to pass to the script function
CObject obj;

// Pass the object to the function
ctx->SetArgObject(0, &obj);
\endcode

Getting an object returned by a script function is done in a similar way, using
GetReturnObject():

\code
void *GetReturnObject();
\endcode

This method will return a pointer to the object returned by the script function.
The library will still hold a reference to the object, which will only be freed as
the context is released.

\code
// The object where we want to store the return value
CObject obj;

// Execute the function
int r = ctx->Execute();
if( r == asEXECUTION_FINISHED )
{
  // Get a pointer to the returned object and copy it to our object
  obj = *(CObject*)ctx->GetReturnObject();
}
\endcode

It is important to make a copy of the returned object, or if it is managed by
reference counting add a reference to it. If this is not done the pointer obtained
with GetReturnObject() will be invalidated as the context is released, or reused for
another script function call.

\section doc_call_script_4 Exception handling

If the script performs an illegal action, e.g. calling a method on a null handle, then
the script engine will throw a script exception. The virtual machine will then abort
the execution and the \ref asIScriptContext::Execute "Execute" method will return with the value
\ref asEXECUTION_EXCEPTION.

At this time it is possible to obtain information about the exception through the
\ref asIScriptContext's methods. Example:

\code
void PrintExceptionInfo(asIScriptContext *ctx)
{
  asIScriptEngine *engine = ctx->GetEngine();

  // Determine the exception that occurred
  printf("desc: %s\n", ctx->GetExceptionString());

  // Determine the function where the exception occurred
  const asIScriptFunction *function = ctx->GetExceptionFunction();
  printf("func: %s\n", function->GetDeclaration());
  printf("modl: %s\n", function->GetModuleName());
  printf("sect: %s\n", function->GetScriptSectionName());

  // Determine the line number where the exception occurred
  printf("line: %d\n", ctx->GetExceptionLineNumber());
}
\endcode

If desired, it is also possible to \ref asIScriptContext::SetExceptionCallback "register a callback function"
that will be called at the moment the exception occurred, before the \ref asIScriptContext::Execute "Execute" method returns.
The exception callback can then use \ref asIScriptContext::WillExceptionBeCaught "WillExceptionBeCaught" to determine if the exception will be \ref try
"caught within the script" or if it will abort the execution.

\see \ref doc_debug for information on examining the callstack, and \ref doc_addon_helpers "GetExceptionInfo" for a helper function to get information on exceptions.

*/


code:
/**

\page doc_callbacks Funcdefs and script callback functions

\ref doc_global_funcdef "Funcdefs" are used to define a function signature for callbacks. This funcdef is then
used to declare variables or function parameters that can hold handles to functions of matching signature.

The application can also \ref asIScriptEngine::RegisterFuncdef "register funcdefs" as part of the application
interface if the intention is for the script to set callbacks that will be called from the application. Once
this is done, the application can receive the function handles as an asIScriptFunction pointer which can
then be \ref doc_call_script_func "executed" normally.

\section doc_callbacks_example An example

Let's say the application needs to allow the script to set a callback that will then be called at some event. To
do this the application would first register the funcdef that defines the signature of the callback. Then it needs
to register the function that will be used to set the callback from the script.

\code
  // Register a simple funcdef for the callback
  engine->RegisterFuncdef("void CallbackFunc()");

  // Register a function for setting the callback
  engine->RegisterGlobalFunction("void SetCallback(CallbackFunc @cb)", asFUNCTION(SetCallback), asCALL_CDECL);
\endcode

With this interface, the script would be able to inform the callback like this:

<pre>
  void main()
  {
    // Tell the application what script function to call
    SetCallback(MyCallback);
  }

  // The signature matches the registered CallbackFunc funcdef
  void MyCallback()
  {
    ...
  }
</pre>

The implementation for the SetCallback function might look something like this.

\code
  // The callback is a script function.
  // Don't forget to release this before cleaning up the engine.
  asIScriptFunction *callback = 0;

  void SetCallback(asIScriptFunction *cb)
  {
    // Release the previous callback, if any
    if( callback )
      callback->Release();

    // Store the received handle for later use
    callback = cb;

    // Do not release the received script function
    // until it won't be used any more
  }
\endcode

To call the actual callback when it is time, the application uses the script context just
like for any other \ref doc_call_script_func "call to a script function".

\section doc_callbacks_delegate Delegates

Of course, callbacks can be used with \ref doc_datatypes_funcptr "delegates" as well. Delegates
are special function objects that holds a reference to an object and the method it should call
on it. If this is exactly how the application should treat them, then the above example will
work exactly the same and the application never needs to worry about whether the callback
is actually a global function or a delegate object.

Sometimes however, it may be beneficial to break up the delegate, and have the application store
the actual object and method separately, for example if the application should use a
\ref doc_adv_weakref "weak reference" to avoid keeping the object alive longer than desired.
The following shows how to retrieve the internals of the delegate:

\code
  // The callback, and accompanying object, if the callback is a class method
  asIScriptFunction *callback           = 0;
  void              *callbackObject     = 0;
  asITypeInfo       *callbackObjectType = 0;

  void SetCallback(asIScriptFunction *cb)
  {
    // Release the previous callback, if any
    if( callback )
      callback->Release();
    if( callbackObject )
      engine->ReleaseScriptObject(callbackObject, callbackObjectType);
    callback           = 0;
    callbackObject     = 0;
    callbackObjectType = 0;

    if( cb && cb->GetFuncType() == asFUNC_DELEGATE )
    {
      callbackObject     = cb->GetDelegateObject();
      callbackObjectType = cb->GetDelegateObjectType();
      callback           = cb->GetDelegateFunction();

      // Hold on to the object and method
      engine->AddRefScriptObject(callbackObject, callbackObjectType);
      callback->AddRef();

      // Release the delegate, since it won't be used anymore
      cb->Release();
    }
    else
    {
      // Store the received handle for later use
      callback = cb;

      // Do not release the received script function
      // until it won't be used any more
    }
  }
\endcode

\note Although delegates use the asIScriptFunction interface, they are not actual functions. Because of this they are not owned by any module, i.e. \ref asIScriptFunction::GetModule "GetModule" will always return null. Likewise they do not have a specific function id, i.e. \ref asIScriptFunction::GetId "GetId" will return 0.

*/


code:
/**

\page doc_compile_lib Compile the library

In the sdk/angelscript/projects directory you'll find project files for many of the popular compilers.
However, these project files are not always up to date with the latest version of the library. If you get
any compiler or linker errors please make sure the project file include all the files in the
sdk/angelscript/source directory, and that the project settings are set according to this article.

If you don't find a project file for your compiler, you can easily create your own project by adding
all the files in the sdk/angelscript/source directory, and configuring the project apropriately. If you
have a new compiler/target that hasn't been used with AngelScript before, you may need to edit the
as_config.h file to make sure the library is compiled properly.

\see \ref doc_compile_platforms

\section doc_compile_lib_1 Set compile time options

The code tries to contain compiler differences in as few places as possible. The header as_config.h
was created for that purpose. There you will find some \#defines that allow different compilers
to work. You'll probably not have to change this file, but if you're using a compiler not
previously used and you're getting compiler errors it might be worth it to take a look at
this file.

There are also a couple of other \#defines used in the code to alter the compilation. When
compiling the library you might want to define ANGELSCRIPT_EXPORT so that library functions
are exported. If you include the library source code directly in your application project you
shouldn't have to define this flag.

If AS_DEPRECATED is defined then some backwards compatibility is maintained, this can help
you do the upgrade to the latest version a little more smoothly. There is no guarantee that
the backwards compatibility will be maintained though so try to remove use of deprecated functions
as soon as possible.

\section doc_compile_lib_2 Linking with the library

There are four ways of compiling and linking with AngelScript in order to use it. I
recommend linking with a static library. Note that all four ways are interchangable with
only a small change in your code, i.e a defined flag before including the header file, and
possibly a routine for manually loading the dll. The rest of your code should look exactly
the same for each of the alternatives.

\subsection doc_compile_lib_2_1 1. Include library source files in project

You can take the source files for AngelScript and include them directly in your own
project. The advantage of this is that you can be sure that the same compiler options are
used for the library and the host applications, e.g. multi-threaded or single-threaded CRT.
The disadvantage is that your project will be poluted with the library files.

The files that need to use the library should include the %angelscript.h header with no
need for any special settings.

\code
// Include the library interface
#include "angelscript.h"

// ... Start using the library
\endcode

\subsection doc_compile_lib_2_2 2. Compile a static library and link into project

The most recommended way is to compile a static library that your project will link with.
When compiling the static library you have to make sure that the correct compiler settings
are used so that you don't get conflicts in linkage with the CRT functions. This happens
if you for example compile the library with dynamically linked multi-threaded CRT and your
application with statically linked single-threaded CRT. (For Visual C++ you'll find these
settings under Project -> Settings -> C/C++ -> Category: Code Generation)

To use the library you only need to include the %angelscript.h header file.

\code
// Include the library interface
#include "angelscript.h"

// ... Start using the library
\endcode

\subsection doc_compile_lib_2_3 3. Compile a dynamically loaded library with an import library

With Microsoft Visual C++ it is possible to compile a dynamically loaded library with an
import library. The import library will then take care of the work needed to load the dll
and bind the functions. A possible disadvantage of this method is that you are not able to
give any user-friendly error messages in case loading the library fails.

To use the library you'll have to define ANGELSCRIPT_DLL_LIBRARY_IMPORT before including
the %angelscript.h header file.

\code
// Include the library interface
#define ANGELSCRIPT_DLL_LIBRARY_IMPORT
#include "angelscript.h"

// ... Start using the library
\endcode

\subsection doc_compile_lib_2_4 4. Load the dynamically loaded library manually

If you want to use a dll, e.g. to share code between applications, I recommend loading the
library manually as you can treat any failures to load or bind functions graciously.

To use manually loaded dll, you should define ANGELSCRIPT_DLL_MANUAL_IMPORT before including
the %angelscript.h header file. This will insure that the header file doesn't declare the
function prototypes, as you will most likely want to use these names for the function pointers.

\code
// Include the library interface
#define ANGELSCRIPT_DLL_MANUAL_IMPORT
#include "angelscript.h"

// Declare the function pointers
typedef asIScriptEngine * AS_CALL t_asCreateScriptEngine(int);
t_asCreateScriptEngine *asCreateScriptEngine = 0;

// ... Declare the rest of the functions

// Load the dll and bind the functions (error handling left out for clarity)
HMODULE dll = LoadLibrary("angelscript.dll");
asCreateScriptEngine = (t_asCreateScriptEngine*)GetProcAddress(dll, "_asCreateScriptEngine");

// ... Bind the other functions

// ... Start using the library
\endcode

\section doc_compile_platforms Considerations for specific platforms

As mentioned before, for most platforms the compilation of the library is as easy as including all
source files and compiling them. However, on some platforms specific actions needs to be performed
to compile the library correctly.

\subsection doc_compile_win64 Windows 64bit

The MSVC compiler doesn't support inline assembler for the x86 64bit CPU family. To support this platform a
separate assembler file has been created: as_callfunc_x64_msvc_asm.asm.

To compile this file it is necessary to configure a custom build command with the following:

\code
ml64.exe /c  /nologo /Fo$(OutDir)\as_callfunc_x64_msvc_asm.obj /W3 /Zi /Ta $(InputDir)\$(InputFileName)
\endcode

\subsection doc_compile_msvc_sdk Microsoft Visual C++

While AngelScript doesn't use Microsoft's language extensions you may still face trouble compiling the library
if you disable the language extensions. This is because Microsoft's own SDK may have code that relies on the
language extensions, e.g. in version 6.0a you might get compiler errors due to the existance of $ in the macro
definitions in the specstrings.h header from the Platform SDK. This particular problem was fixed by Microsoft
in version 6.1 of their SDK, but there may be others so it might just easier to leave the language extensions
turned on.

\subsection doc_compile_gnuc GNUC based compilers

In order to properly intergrate with C++ without the need for wrappers AngelScript uses a lot of pointer casts.
Unfortunately it is not possible to always guarantee strict aliasing because of this, so on GNUC based compilers
it is necessary to disable compiler optimizations that assume strict aliasing.

Use the following compiler argument to disable this:

\code
-fno-strict-aliasing
\endcode

\subsection doc_compile_pocketpc Pocket PC with ARM CPU

The MSVC compiler doesn't support inline assembler for the ARM CPU, so a separate assembler file has been
written with this code: as_callfunc_arm_msvc.asm.

In order to compile this file properly it is necessary to configure a custom build command with the following:

\code
armasm -g $(InputPath)
\endcode

\subsection doc_compile_marmalade Marmalade

Marmalade is a cross platform SDK created with mobile devices in mind. It functions by abstracting the underlying OS
with its own C runtime library even though it uses the common C++ compilers, e.g. MSVC on Windows, and GNUC on Linux and Mac.

When compiling AngelScript with Marmalade for iOS and Android scons must be used in order to properly
compile the native ARM assembler routines. For Windows Phone you should be able to use MSVC normally.

\section doc_compile_size Size of the library

The size of the library depends on many different factors, such as compiler brand, compiler flags, and also what features
of AngelScript that are included. However, to give an idea of how much space the library will take up on the disk and memory
I've compiled the \ref doc_samples_asrun "asrun sample" in a few different ways and noted down the size.

Options	Size of binary on disk

32 bit / multithreaded dll / optimize for speed
Without including AngelScript	14KB

32 bit / multithreaded dll / optimize for speed
Using AngelScript and add-ons	796KB

32 bit / multithreaded dll / optimize for speed
AngelScript without compiler (AS_NO_COMPILER) and add-ons	453KB

32 bit / multithreaded static / optimize for speed
Using AngelScript but without add-ons	867KB

32 bit / multithreaded static / optimize for speed
Using AngelScript and add-ons	1015KB

64 bit / multithreaded static / optimize for speed
Using AngelScript and add-ons	1336KB

32 bit / multithreaded static / optimize for size
Using AngelScript and add-ons	797KB

32 bit / multithreaded dll / optimize for size
Using AngelScript and add-ons	582KB

Based on this we can draw the conclusion that the engine and VM takes up about 300KB when optimized for speed,
the compiler adds another 350KB, and the add-ons yet another 150KB.

\note These tests were made with MSVC 2012 and version 2.30.2 of the library.

*/