code:
/**

\page doc_compile_script Compiling scripts

After \ref doc_register_api "registering the application interface" it's time to
compile the scripts that will be executed.

\section doc_compile_script_msg Message callback

Before starting the compilation, remember to have the message callback set in the
engine so that you can get more information on compilation errors than just an
error code. In fact, it is recommended to set the message callback right after
creating the script engine, as the message callback may even be helpful while
registering the application interface.

The message callback has been designed so that it doesn't output anything if there
are no errors or warnings, so when everything is ok, you shouldn't get anything from
it. But if the \ref asIScriptModule::Build "Build" method returns an error, the message
callback will have received detailed information about the error.

If desired, the application may send its own messages to the callback via the
\ref asIScriptEngine::WriteMessage "WriteMessage" method on the engine.

\code
// Implement a simple message callback function
void MessageCallback(const asSMessageInfo *msg, void *param)
{
  const char *type = "ERR ";
  if( msg->type == asMSGTYPE_WARNING )
    type = "WARN";
  else if( msg->type == asMSGTYPE_INFORMATION )
    type = "INFO";
  printf("%s (%d, %d) : %s : %s\n", msg->section, msg->row, msg->col, type, msg->message);
}

// Set the message callback when creating the engine
asIScriptEngine *engine = asCreateScriptEngine();
engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL);
\endcode

\section doc_compile_script_load Loading and compiling scripts

To build a script module you first obtain a module from the engine, then add
the script sections, and finally compile them. A compiled script module may be
composed of one or more script sections, so your application may store each
section in different files, or even generate them dynamically. It doesn't matter
in which order the script sections are added to the module, as the compiler
is able to resolve all names regardless of where they are declared in the script.

\code
// Create a new script module
asIScriptModule *mod = engine->GetModule("module", asGM_ALWAYS_CREATE);

// Load and add the script sections to the module
string script;
LoadScriptFile("script.as", script);
mod->AddScriptSection("script.as", script.c_str());

// Build the module
int r = mod->Build();
if( r < 0 )
{
  // The build failed. The message stream will have received
  // compiler errors that shows what needs to be fixed
}
\endcode

AngelScript doesn't provide built-in functions for loading script files as most
applications have their own way of loading files. However, it is quite easy to write
your own routines for loading script files, for example:

\code
// Load the entire script file into a string buffer
void LoadScriptFile(const char *fileName, string &script)
{
  // Open the file in binary mode
  FILE *f = fopen("test.as", "rb");

  // Determine the size of the file
  fseek(f, 0, SEEK_END);
  int len = ftell(f);
  fseek(f, 0, SEEK_SET);

  // Load the entire file in one call
  script.resize(len);
  fread(&script[0], len, 1, f);

  fclose(f);
}
\endcode

As AngelScript doesn't load the files itself, it also doesn't have built-in support
for including other files from within the script. However, if you look in the add-on
directory, you'll find a \ref doc_addon_build "CScriptBuilder" class that provides
this support and more. It is a helper class for loading files, perform a pre-processing pass,
and then building the module. You can a see an example of how to use the script builder
in \ref doc_hello_world.

\see \ref doc_adv_precompile

*/


code:
/**

\page doc_cpp_exceptions C++ exceptions and longjmp

\section doc_cpp_exceptions_1 Exceptions

Application functions and class methods registered with the script engine are allowed to throw C++ exceptions. The virtual machine will automatically catch any C++ exception, abort the script execution, and return control to the application.

\code
asIScriptContext *ctx = engine->CreateContext();
ctx->Prepare(engine->GetModule("test")->GetFunctionByName("func"));
int r = ctx->Execute();
if( r == asEXECUTION_EXCEPTION )
{
  string err = ctx->GetExceptionString();
  if( err == "Caught an exception from the application" )
  {
    // An application function threw an exception while being invoked from the script
    ...
  }
}
\endcode

By default the VM has no way of distinguishing between different types of exceptions and will just give a standard exception
string for all of them. If desired a \ref asIScriptEngine::SetTranslateAppExceptionCallback "callback can be registered" with
the engine to provide a translation of the exception type to a more informative exception string.

\code
void TranslateException(asIScriptContext *ctx, void* /*userParam*/)
{
  try
  {
    // Retrow the original exception so we can catch it again
    throw;
  }
  catch( std::exception &e )
  {
    // Tell the VM the type of exception that occurred
    ctx->SetException(e.what());
  }
  catch(...)
  {
    // The callback must not allow any exception to be thrown, but it is not necessary
    // to explicitly set an exception string if the default exception string is sufficient
  }
}

// Register the callback with the engine
engine->SetTranslateAppExceptionCallback(asFUNCTION(TranslateException), 0, asCALL_CDECL);
\endcode

\see \ref doc_addon_helpers "GetExceptionInfo" helper function

\note The ability to catch exceptions can be turned off by compiling the library with the AS_NO_EXCEPTIONS defined. If this is done, the application should not register any functions that may throw exceptions, as the end result will be
undefined should an exception occur.

\section doc_cpp_exceptions_2 longjmp

Some applications uses longjmp to do error handling. When performing a longjmp to a previously saved state, there is no chance for the code to do a cleanup of all that happened after the saved state. Because of that the application must not register functions that can perform a longjmp out from the function, as that can leave the virtual machine in an undefined state.

*/

repo_name: Antidote/openrpgeditor

license: mit


code:
/**

\page doc_debug Debugging scripts

AngelScript offers a rich interface to support the debugging of scripts. It is easy to build an embedded debugger
that can set break points, inspect/manipulate variables in functions, visualize the call stack, etc.

Observe that the CDebugMgr class used in the examples below doesn't exist. It is only used as an abstraction to
avoid having to write fictional debug routines.

\see \ref doc_addon_debugger for a standard implementation

\section doc_debug_1 Setting line breaks

In order to break at a specified line in the code the debugger can set the line callback function in the script context. The
VM will then invoke the callback for each statement executed, allowing the debugger to decide whether to proceed to the next
statement or not.

\code
// An example line callback
void DebugLineCallback(asIScriptContext *ctx, CDebugMgr *dbg)
{
  // Determine if we have reached a break point
  const char *scriptSection;
  int line = ctx->GetLineNumber(0, 0, &scriptSection);
  asIScriptFunction *function = ctx->GetFunction();

  // Now let the debugger check if a breakpoint has been set here
  if( dbg->IsBreakpoint(scriptSection, line, function) )
  {
    // A break point has been reached so the execution of the script should be suspended
    ctx->Suspend();
  }
}
\endcode

The line callback is set on the context with the following call:

\code
  // Set the line callback with the address of the debug manager as parameter
  ctx->SetLineCallback(asFUNCTION(DebugLineCallback), dbg, asCALL_CDECL);
\endcode

When the line callback suspends the execution the context's \ref asIScriptContext::Execute "Execute" function will return with
the code \ref asEXECUTION_SUSPENDED. The application can then go into a special message loop where the debug routines can be handled,
e.g. to \ref doc_debug_2 "view the call stack", \ref doc_debug_3 "examine variables", etc. Once the execution should continue, simply
call the Execute method again to resume it.

An alternative to suspending the script execution might be to start the message loop directly within the line callback, in which
case resuming the execution is done simply by returning from the line callback function. Which is the easiest to implement depends on
how you have implemented your application.

\section doc_debug_2 Viewing the call stack

The asIScriptContext exposes the call stack for viewing purposes, so that you can easily track the origin of calls. It is also possible
to \ref doc_debug_3 "print the value of variables" at each level in the callstack.

Here's an example of how the entire call stack can be printed:

\code
void PrintCallstack(asIScriptContext *ctx)
{
  // Show the call stack
  for( asUINT n = 0; n < ctx->GetCallstackSize(); n++ )
  {
    asIScriptFunction *func;
    const char *scriptSection;
    int line, column;
    func = ctx->GetFunction(n);
    line = ctx->GetLineNumber(n, &column, &scriptSection);
    printf("%s:%s:%d,%d\n", scriptSection,
                            func->GetDeclaration(),
                            line, column);
  }
}
\endcode

\section doc_debug_3 Inspecting variables

Through the context interface it is possible to inspect and even modify the value of the local variables on the
stack. This can be done for each level in the call stack, and not just the current function that is being executed.

Here is an example for how the variables may be printed:

\code
void PrintVariables(asIScriptContext *ctx, asUINT stackLevel)
{
  asIScriptEngine *engine = ctx->GetEngine();

  // First print the this pointer if this is a class method
  int typeId = ctx->GetThisTypeId(stackLevel);
  void *varPointer = ctx->GetThisPointer(stackLevel);
  if( typeId )
  {
    printf(" this = 0x%x\n", varPointer);
  }

  // Print the value of each variable, including parameters
  int numVars = ctx->GetVarCount(stackLevel);
  for( int n = 0; n < numVars; n++ )
  {
    int typeId = ctx->GetVarTypeId(n, stackLevel);
    void *varPointer = ctx->GetAddressOfVar(n, stackLevel);
    if( typeId == asTYPEID_INT32 )
    {
      printf(" %s = %d\n", ctx->GetVarDeclaration(n, stackLevel), *(int*)varPointer);
    }
    else if( typeId == asTYPEID_FLOAT )
    {
      printf(" %s = %f\n", ctx->GetVarDeclaration(n, stackLevel), *(float*)varPointer);
    }
    else if( typeId & asTYPEID_SCRIPTOBJECT )
    {
      asIScriptObject *obj = (asIScriptObject*)varPointer;
      if( obj )
        printf(" %s = {...}\n", ctx->GetVarDeclaration(n, stackLevel));
      else
        printf(" %s = <null>\n", ctx->GetVarDeclaration(n, stackLevel));
    }
    else if( typeId == engine->GetTypeIdByDecl("string") )
    {
      string *str = (string*)varPointer;
      if( str )
        printf(" %s = '%s'\n", ctx->GetVarDeclaration(n, stackLevel), str->c_str());
      else
        printf(" %s = <null>\n", ctx->GetVarDeclaration(n, stackLevel));
    }
    else
    {
      printf(" %s = {...}\n", ctx->GetVarDeclaration(n, stackLevel));
    }
  }
}
\endcode

The above code is only an example to give an idea of how it can be done. It is not complete and only
recognizes a few types. To make it useful it would have to be expanded to recognize all types, and
perhaps add some generic way of converting an object to human readable string for printing.

For script objects that conversion can be done by enumerating the members of an object through the
\ref asIScriptObject interface.

The debugger may also need to be able to inspect the global variables that the functions access. As the
global variables are stored in the module, there is the place to look for them. The \ref asIScriptModule
interface can be obtained by querying the module name from the function, and then getting the module
pointer from the engine. Once the module is determined the global variables are enumerated much the same
way as in the example above, except that the appropriate methods on the asIScriptModule interface are used
instead.

\section doc_debug_4 Debugging internally executed scripts

Some script execution is not initiated by the application, e.g. the initialization of global variables or
the call to the script class destructor when destroying objects from the garbage collector. If these
executions should be debugged, the application must set the context callback functions with a call to
\ref asIScriptEngine::SetContextCallbacks. The engine will invoke these callbacks to request a context
from the application when it will execute a script internally. The application can then
attach the debugger to the context it provides to the engine.

*/


code:
/**

\page doc_finetuning Fine tuning

Here's a few recommendations to get the most performance out of AngelScript.

\section doc_finetuning_1 Cache the functions and types

Doing searches by function declaration or name is rather time consuming and
should not be done more than once per function that will be called. The same
goes for the types that you might use it.

Also try to use the actual \ref asIScriptFunction or \ref asITypeInfo pointers
instead of the ids where possible. This will save the engine from translating the
id to the actual object.

You may use the user data in the various engine interfaces to store the cached
information. For example, store a structure with the commonly used class methods
as \ref asITypeInfo::SetUserData "user data" in the \ref asITypeInfo interface.
This way you will have quick access to the functions when they need to be called.

\section doc_finetuning_2 Reuse the context object

The context object is a heavy weight object and you should avoid allocating new
instances for each call. The object has been designed to be reused for multiple
calls.

\subsection doc_finetuning_2_1 Context pool

Ideally the application will keep a simple memory pool of allocated context
objects, where new objects are only allocated if the is no free objects in the
pool.

By using the engine's \ref asIScriptEngine::SetContextCallbacks "context callbacks",
this context pool will also be automatically available to the engine for use in
internal calls and the add-ons.

The code that wants to use a context from the pool should use the
\ref asIScriptEngine::RequestContext "RequestContext" and \ref asIScriptEngine::ReturnContext "ReturnContext" methods
instead of the \ref asIScriptEngine::CreateContext "CreateContext" method.

Here's a simple implementation of a context pool.

\code
std::vector<asIScriptContext *> pool;
asIScriptContext *RequestContextCallback(asIScriptEngine *engine, void *param)
{
  // Get a context from the pool, or create a new
  asIScriptContext *ctx = 0;
  if( pool.size() )
  {
    ctx = *pool.rbegin();
    pool.pop_back();
  }
  else
    ctx = engine->CreateContext();

  return ctx;
}

void ReturnContextToPool(asIScriptEngine *engine, asIScriptContext *ctx, void *param)
{
  pool.push_back(ctx);

  // Unprepare the context to free non-reusable resources
  ctx->Unprepare();
}
\endcode

\subsection doc_finetuning_2_2 Nested calls

Another form of reusing a context is to use nested calls.

Whenever an application registered function that is called from a script needs to
execute another script it can reuse the already active context for a nested call.
This way it is not necessary to look for an available context from a pool or allocate
a new context just for this call.

\code
void Func()
{
  // Get the active context
  asIScriptContext *ctx = asGetActiveContext();

  // Store the current context state so we can restore it later
  if( ctx && ctx->PushState() > 0 )
  {
    // Use the context normally, e.g.
    //  ctx->Prepare(...);
    //  ctx->Execute(...);

    // Once done, restore the previous state
    ctx->PopState();
  }
}
\endcode

\section doc_finetuning_3 Compile scripts without line cues

The line cues are normally placed in the bytecode between each script
statement. These are where the VM will allow the execution to be suspended, and
also where the line callback is invoked.

If you do not need to receive a callback for every statement executed in a script
then you may get a little more performance out of the script by compiling without
the line cues.

The line callback will still work and is guaranteed to be invoked at least once
per loop and every function call in the script to allow the application to interrupt
infinite loops or infinitely recursive calls.

\code
engine->SetEngineProperty(asEP_BUILD_WITHOUT_LINE_CUES, true);
\endcode

\section doc_finetuning_4 Disable thread safety

If your application only uses one thread to invoke the script engine, then it
may be worth it to compile the library without the thread safety to gain a
little more performance.

To do this, define the AS_NO_THREADS flag in the as_config.h header or in the
project settings when compiling the library.

\section doc_finetuning_5 Turn off automatic garbage collection

While garbage collection is important in long running applications, it may be of interest to
turn off the automatic garbage collection and then run the garbage collector manually in a
controlled manner. The garbage collector is incremental so you shouldn't see long stalls
while it is running, but it will consume CPU cycles that may be needed for other things.

To turn off the automatic garbage collector set the engine property \ref asEP_AUTO_GARBAGE_COLLECT to false.

\code
engine->SetEngineProperty(asEP_AUTO_GARBAGE_COLLECT, false);
\endcode

\see \ref doc_gc

\section doc_finetuning_6 Compare native calling convention versus generic calling convention

If you have specific functions that are called very frequently it may be worth comparing the performance
between binding the functions using native calling convention versus the generic calling convention. It
is not possible to generalize and say that one is always faster than the other, as it will vary depending
on the function signature and the platforms ABI complexity.

\see \ref doc_generic, \ref doc_register_func_2

*/


code:
/**

\page doc_gc Garbage collection

Though AngelScript uses reference counting for memory management, there is still need for a garbage collector to
take care of the few cases where circular referencing between objects prevents the reference counter from reaching zero.
By default AngelScript automatically runs a few incremental steps of the garbage collector every time a new garbage
collected object is created, this allows the destruction of garbage in an automatic way, yet doesn't waste time or
disrupts the responsiveness of the application.

The automatic execution may not always be enough to clean up the garbage, for example, if the scripts create a lot of
garbage with circular references. In this case the application may need to manually invoke the garbage collector from
time to time. For this reason it is recommended that the application monitor the statistics for the garbage collector
and adjust the frequency of the manual calls as necessary. The statistics is obtained through a call to
\ref asIScriptEngine::GetGCStatistics "GetGCStatistics", which returns the number of objects currently known to the
garbage collector as well as the number of objects that have been destroyed and the number of object that have been
detected as garbage with circular references.

The garbage collector implemented in AngelScript is incremental, so it can be executed for short periods of time without
requiring the entire application to halt. For this reason, it is recommended that one or more calls to \ref
asIScriptEngine::GarbageCollect "GarbageCollect"(\ref asGC_ONE_STEP) is made at least once during the normal event processing.
The number of calls that should be made depends on how much garbage is created.

If the scripts produce a lot of garbage but only a low number of garbage with circular references, the application can make a
call to \ref asIScriptEngine::GarbageCollect "GarbageCollect"(\ref asGC_FULL_CYCLE | \ref asGC_DESTROY_GARBAGE), which will
only destroy the known garbage without trying to detect circular references. This call is relatively fast as the garbage
collector only has to make a trivial local check to determine if an object is garbage without circular references.

Finally, if the application goes into a state where responsiveness is not so critical, it might be a good idea to do a full
cycle on the garbage collector, thus cleaning up all garbage at once. To do this, call \ref
asIScriptEngine::GarbageCollect "GarbageCollect"(\ref asGC_FULL_CYCLE).

Should the automatic garbage collections not be desired, e.g. in critical inner loops where maximum performance is
needed, it can easily be turned off with a call to \ref asIScriptEngine::SetEngineProperty "SetEngineProperty"(\ref asEP_AUTO_GARBAGE_COLLECT, false).

\see \ref doc_memory

\section doc_gc_circcallback Callback for detected circular references

During the testing phase of your project it is wise to try to identify situations that create circular references as
these have a potential of significantly impacting the performance. While the \ref asIScriptEngine::GetGCStatistics "GetGCStatistics"
will tell you if circular references have been detected and destroyed, it will not tell you much about the actual objects involved in
the circular references. To aid in this the application can set a callback for when circular references is detected with
\ref asIScriptEngine::SetCircularRefDetectedCallback "SetCircularRefDetectedCallback".

When this callback is invoked the objects in the circular reference have not yet been destroyed, so the application can inspect
the content to get valuable hints on where and when they were created. The application must not however try to modify the
objects at this time as would lead to undefined behaviour, and possibly even application crashes.

\section doc_gc_threads Garbage collection and multi-threading

The garbage collector itself is thread safe, but in order to be able to safely use the garbage collector in a multi-threaded
environment the application must make sure all the objects that may be in the garbage collector has thread safe implementations
of \ref doc_gc_object "the GC behaviours".

\see \ref doc_reg_gcref_4

*/


code:
/**

\page doc_gc_object Garbage collected objects

Reference counting as memory management has a drawback in that it is
difficult to detect circular references when determining dead objects.
AngelScript allows the application to register types with special behaviours
to support the garbage collection for detecting circular references. These
behaviours make the class a bit more complex, but you should only have to
register them for a few types, e.g. generic container classes.

\code
// Registering the garbage collected reference type
r = engine->RegisterObjectType("ref_type", 0, asOBJ_REF | asOBJ_GC); assert( r >= 0 );
\endcode

The difference between the garbage collected and non-garbage collected
types is in the addref and release behaviours, the class constructor, and
the extra support behaviours.

\see The \ref doc_addon_dict "dictionary" add-on for an example of a garbage collected object

\section doc_reg_gcref_1 GC support behaviours

The GC determines when objects should be destroyed by counting the
references it can follow for each object. If the GC can see all references
that points to an object, it knows that the object is part of a circular
reference. If all the objects involved in that circular reference have no
outside references it means that they should be destroyed.

The process of determining the dead objects uses the first four of the
behaviours below, while the destruction of the objects is done by forcing the
release of the object's references.

\code
void CGCRef::SetGCFlag()
{
    // Set the gc flag as the high bit in the reference counter
    refCount |= 0x80000000;
}

bool CGCRef::GetGCFlag()
{
    // Return the gc flag
    return (refCount & 0x80000000) ? true : false;
}

int CGCRef::GetRefCount()
{
    // Return the reference count, without the gc flag
    return (refCount & 0x7FFFFFFF);
}

void CGCRef::EnumReferences(asIScriptEngine *engine)
{
    // Call the engine::GCEnumCallback for all references to other objects held
    engine->GCEnumCallback(myref);
}

void CGCRef::ReleaseAllReferences(asIScriptEngine *engine)
{
    // When we receive this call, we are as good as dead, but
    // the garbage collector will still hold a references to us, so we
    // cannot just delete ourself yet. Just free all references to other
    // objects that we hold
    if( myref )
    {
        myref->Release();
        myref = 0;
    }
}

// Register the GC support behaviours
r = engine->RegisterObjectBehaviour("ref_type", asBEHAVE_SETGCFLAG, "void f()", asMETHOD(CGCRef,SetGCFlag), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("ref_type", asBEHAVE_GETGCFLAG, "bool f()", asMETHOD(CGCRef,GetGCFlag), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("ref_type", asBEHAVE_GETREFCOUNT, "int f()", asMETHOD(CGCRef,GetRefCount), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("ref_type", asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(CGCRef,EnumReferences), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("ref_type", asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(CGCRef,ReleaseAllReferences), asCALL_THISCALL); assert( r >= 0 );
\endcode

\section doc_reg_gcref_2 Factory for garbage collection

Whenever a garbage collected class is created, the garbage collector must
be notified of it's existence. The easiest way of doing that is to have the
factory behaviour, or the class constructor call the
NotifyGarbageCollectorOfNewObject() method on the engine when initializing the
class.

\code
CGCRef *GCRef_Factory()
{
    // Create the object and then notify the GC of its existence
    CGCRef *obj = new CGCRef();
    asITypeInfo *type = engine->GetTypeInfoByName("gc");
    engine->NotifyGarbageCollectorOfNewObject(obj, type);
    return obj;
}
\endcode

You may want to consider caching the typeId, so that it doesn't have to be
looked up through the relatively expensive call to GetTypeIdByDecl every time
an object of this type is created.

Note, if you create objects of this type from the application side, you
must also notify the garbage collector of its existence, so it's a good idea
to make sure all code use the same way of creating objects of this type.

\section doc_reg_gcref_3 Addref and release for garbage collection

For garbage collected objects it is important to make sure the AddRef and
Release behaviours clear the GC flag. Otherwise it is possible that the GC
incorrectly determine that the object should be destroyed.

\code
void CGCRef::AddRef()
{
    // Clear the gc flag and increase the reference counter
    refCount = (refCount&0x7FFFFFFF) + 1;
}

void CGCRef::Release()
{
    // Clear the gc flag, decrease ref count and delete if it reaches 0
    refCount &= 0x7FFFFFFF;
    if( --refCount == 0 )
        delete this;
}

// Registering the addref/release behaviours
r = engine->RegisterObjectBehaviour("ref_type", asBEHAVE_ADDREF, "void f()", asMETHOD(CGCRef,AddRef), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("ref_type", asBEHAVE_RELEASE, "void f()", asMETHOD(CGCRef,Release), asCALL_THISCALL); assert( r >= 0 );
\endcode

\section doc_reg_gcref_value GC behaviours for value types

Value types are normally not thought of as being part of circular references as they themselves cannot be referenced, however
if a value type can hold a reference to a type, and then that type can have the value type as a member then a circular reference can
be established preventing the reference type from being released.

To solve these situations the value types can also be registered with some of the garbage collector behaviours.

\code
// Registering the value type with garbage collected behaviour
r = engine->RegisterObjectType("value_type", sizeof(value_type), asOBJ_VALUE | asOBJ_GC | ...); assert( r >= 0 );

// Register the garbage collector behaviours
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_ENUMREFS, "void f(int&in)", asMETHOD(value_type,EnumReferences), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectBehaviour("ref", asBEHAVE_RELEASEREFS, "void f(int&in)", asMETHOD(value_type, ReleaseReferences), asCALL_THISCALL); assert(r >= 0);
\endcode

Only the asBEHAVE_ENUMREFS and asBEHAVE_RELEASEREFS should be registered for value types. These work the same
way as for reference types, i.e. the asBEHAVE_ENUMREFS should call the engine's GCEnumCallback for all
references held, and asBEHAVE_RELEASEREFS should clear all references held.

Reference types that contain value types that have GC behaviours need to have the
asBEHAVE_ENUMREFS and asBEHAVE_RELEASEREFS behaviours adapted for this by forwarding the enum and release
call to the value type. This forward is done by calling the engine's \ref asIScriptEngine::ForwardGCEnumReferences "ForwardGCEnumReferences"
or \ref asIScriptEngine::ForwardGCReleaseReferences "ForwardGCReleaseReferences" respectively.

\code
void CGCRef2::EnumReferences(asIScriptEngine *engine)
{
    // Forward the enum call to the member value type
    engine->ForwardGCEnumReferences(valueObj, valueType);
}

void CGCRef2::ReleaseAllReferences(asIScriptEngine *engine)
{
    // When we receive this call, we are as good as dead, but
    // the garbage collector will still hold a references to us, so we
    // cannot just delete ourself yet. Just free all references to other
    // objects that we hold

    // Forward the release call to the member value type
    engine->ForwardGCReleaseReferences(valueObj, valueType);
}
\endcode

\see The \ref doc_addon_handle for a value type with GC behaviours, and the \ref doc_addon_dict for a ref type that can contain value types with GC behaviours.

\section doc_reg_gcref_4 Garbage collected objects and multi-threading

If you plan on executing scripts from multiple threads with \ref doc_adv_custom_options_engine "automatic garbage collection" turned on, or
if you plan on running the garbage collector manually from a background thread, then you must make sure that the object type behaviours
that support the garbage collector are thread-safe. Especially the ADDREF, RELEASE, and ENUMREFS behaviours have a high probability
of being invoked from multiple threads simultaneously. The RELEASEREFS behaviour will only be invoked when the Garbage Collector has
determined that the object is already dead so it is guaranteed not to be invoked by multiple threads. The others, GETREFCOUNT, SETGCFLAG,
and GETGCFLAG, are not sensitive as the garbage collector just use the information as a hint.

Making the ADDREF and RELEASE behaviours thread-safe is easy with the use of \ref asAtomicInc and \ref asAtomicDec. If the object is
static container, i.e. the memory layout of the contents cannot change, then ENUMREFS is already thread-safe, but if memory layout can
change, e.g. dynamic arrays or hash maps, then the iteration over the content in ENUMREFS must be protected so that it doesn't break
in case the memory happen to change in the middle of the iteration.

\see \ref doc_gc_threads

*/


code:
/**

\page doc_generic The generic calling convention

The generic calling convention is available for those situations where the application's native calling
convention doesn't work, for example on platforms where support for native calling conventions haven't
been added yet. You can detect if native calling conventions isn't supported on your target platform by
calling the \ref asGetLibraryOptions function and checking the returned string for "AS_MAX_PORTABILITY". If the
identifier is in the returned string, then native calling conventions is not supported.

Functions implementing the generic calling conventions are always global functions (or static class methods),
that take as parameter a pointer to an asIScriptGeneric interface and returns void.

\code
// The function has been registered with signature:
//  MyIntf @func(int, float, MyIntf @+)
void MyGenericFunction(asIScriptGeneric *gen)
{
  // Extract the arguments
  int arg0              = gen->GetArgDWord(0);
  float arg1            = gen->GetArgFloat(1);
  asIScriptObject *arg2 = reinterpret_cast<asIScriptObject*>(gen->GetArgObject(2));

  // Call the real function
  asIScriptObject *ret = MyFunction(arg0, arg1, arg2);

  // Set the return value
  gen->SetReturnObject(ret);
}
\endcode

Functions using the generic calling convention can be registered anywhere the script engine is expecting
global functions or class methods (except where explicitly written otherwise).

Writing the functions for the generic calling convention requires extracting each argument from the AngelScript
stack, and then manually giving the return value back. For that reason it may be desired to use the
\ref doc_addon_autowrap "automatic wrapper functions" rather than writing the functions yourself.

\section doc_generic_1 Extracting function arguments

To extract functions arguments from the generic interface you should call one of the GetArg methods that
will return the value of the argument, or the \ref asIScriptGeneric::GetAddressOfArg "GetAddressOfArg" method.
The GetAddressOfArg method returns a pointer to the actual value. The application should then cast this pointer
to a pointer of the correct type so that the value can be read from the address.

If the function you're implementing represents a class method, the pointer to the object instance should be obtained
with a call to \ref asIScriptGeneric::GetObject "GetObject".

For arguments that receive output references, i.e. &out, the GetAddressOfArg will give an address to a valid instance of the type.
If the function does not want to return anything in these arguments it is not necessary to do anything.

The asIScriptGeneric interfaces treats the ref count the same way as in native calling conventions, i.e. the application
function is responsible to releasing any handle received as a handle (or \ref doc_obj_handle_4 "register the function with @+").

\section doc_generic_2 Returning values

To return a value from the function one of the SetReturn methods can be called to pass the value to the
generic interface. Returning primitive values is straight forward, but care must be taken when returning object types,
either by value, reference, or as object handle. Depending on the type and the function used it may be necessary to
increment the reference count, or even make a copy of the object first. Carefully read the instructions for
\ref asIScriptGeneric::SetReturnAddress "SetReturnAddress" and \ref asIScriptGeneric::SetReturnObject "SetReturnObject"
to determine what needs to be done to get the expected result.

It is also possible to use the \ref asIScriptGeneric::GetAddressOfReturnLocation "GetAddressOfReturnLocation" method to
obtain the address of the memory where the return value will be stored. The memory is not initialized, so you should
use the placement new operator to initialize this memory with a call to the constructor. This also works for primitive
types, which makes this ideal for template implementations, such as that in the \ref doc_addon_autowrap "automatic wrapper functions".

If the return type is a handle then the GetAddressOfReturnLocation will refer to a location holding a null pointer, so if the function
is to return null it is not necessary to do anything. For primitives it will be an undefined value, so if the value is important it must be set.
For objects of value types returned by value the function must initialize the return value at the location already preallocated by the
calling function, unless an exception is set with \ref asIScriptContext::SetException.

If the function is registered to return a @+, then the script engine will \ref doc_obj_handle_4 "automatically increment the ref count", just as is
done for native calling conventions.

*/


code:
/**

\page doc_good_practice Good practices

This article will try to explain some good practices, that will help you get going faster and easier find the solution when a problem occurs.

\section doc_checkretval Always check return values for registrations

When configuring the script engine you should always check the return values, at least in debug mode.
All error codes are negative so a simple assert( r >= 0 ) where r is the returned value is sufficient
to pinpoint where the configuration failed.

If a function failed during the configuration, the \ref asIScriptModule::Build "Build" method will always fail with a return code
of \ref asINVALID_CONFIGURATION. Unless you already verified the error codes for all the configuration
calls, it will not be possible to determine what the error was.

\code
// Verifying the return code with an assert is simple and won't pollute the code
r = engine->RegisterGlobalFunction("void func()", asFUNCTION(func), asCALL_CDECL); assert( r >= 0 );
\endcode

assert() can safely be used with engine registrations, since the engine will set the internal state
to invalid configuration if a function fails. Even in release mode the failure is discovered when
a script is built.

\section doc_usemsgcallbck Use the message callback to receive detailed error messages

The return code from the register functions, \ref asIScriptModule::Build "Build", and
\ref asIScriptModule::CompileFunction "CompileFunction", can only tell you that something was wrong,
not what it was. To help identify the exact problem the message callback should be used. The script
library will then send messages explaining the error or warning in clear text.

See \ref doc_compile_script_msg for more information on the message callback.

\section doc_checkexceptions Always verify return value after executing script function

The VM can provide detailed information on any exception that occur in the script, for
example in which function and line of code the problem occurred. It is also possible to
enumerate the callstack and even the local variables.

See \ref doc_call_script_4

*/


code:
/**

\page doc_hello_world Your first script

This tutorial will show you the basics on how to configure the engine, compile a script, and then
execute it. The code in this article is not complete, it only contains the relevant parts to explain
the basic structure for using the script library. For complete source codes see the \ref doc_samples "samples"
that come with the SDK.

In this tutorial a couple of add-ons are used to make the code easier. You are not required to use
these in your own application, but they will most likely let you get your project up and running
faster. You'll want to take a look at the rest of the \ref doc_addon "add-ons" later on to see what
else may be useful for you.

\code
// Include the definitions of the script library and the add-ons we'll use.
// The project settings may need to be configured to let the compiler where
// to find these headers. Don't forget to add the source modules for the
// add-ons to your project as well so that they will be compiled into the
// application.
#include <angelscript.h>
#include <scriptstdstring/scriptstdstring.h>
#include <scriptbuilder/scriptbuilder.h>
\endcode

Being an embedded scripting library there isn't much that AngelScript allows the scripts
to do by themselves, so the first thing the application must do is to \ref doc_register_api "register the interface"
that the script will have to interact with the application. The interface may consist of
functions, variables, and even complete classes.

Pay special attention to how the \ref doc_compile_script_msg "message callback" is registered right after the engine
is created. The message callback is used by the engine to give human readable error messages
when something isn't working as it should, e.g. a registration is done incorrectly, or a script
has an error that fails to compile. While you still need to verify the return codes, the message
callback can give you valuable information that will let you figure out what is wrong without
much effort.

\code
// Create the script engine
asIScriptEngine *engine = asCreateScriptEngine();

// Set the message callback to receive information on errors in human readable form.
int r = engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL); assert( r >= 0 );

// AngelScript doesn't have a built-in string type, as there is no definite standard
// string type for C++ applications. Every developer is free to register its own string type.
// The SDK do however provide a standard add-on for registering a string type, so it's not
// necessary to implement the registration yourself if you don't want to.
RegisterStdString(engine);

// Register the function that we want the scripts to call
r = engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_CDECL); assert( r >= 0 );
\endcode

After the engine has been configured, the next step is to compile the scripts that should be executed.

The following is our script that will call the registered <tt>print</tt> function to write <tt>Hello world</tt> on the
standard output stream. Let's say it's stored in the file <tt>test.as</tt>.

<pre>
  void main()
  {
    print("Hello world\n");
  }
</pre>

Here's the code for loading the script file and compiling it. The AngelScript engine itself doesn't have
access to the filesystem so the loading the files has to be done by the application. Here we're going to use
the \ref doc_addon_build "script builder" add-on, which does the loading of the script files, and some preprocessing, such as
handling \#include directives.

\code
// The CScriptBuilder helper is an add-on that loads the file,
// performs a pre-processing pass if necessary, and then tells
// the engine to build a script module.
CScriptBuilder builder;
int r = builder.StartNewModule(engine, "MyModule");
if( r < 0 )
{
  // If the code fails here it is usually because there
  // is no more memory to allocate the module
  printf("Unrecoverable error while starting a new module.\n");
  return;
}
r = builder.AddSectionFromFile("test.as");
if( r < 0 )
{
  // The builder wasn't able to load the file. Maybe the file
  // has been removed, or the wrong name was given, or some
  // preprocessing commands are incorrectly written.
  printf("Please correct the errors in the script and try again.\n");
  return;
}
r = builder.BuildModule();
if( r < 0 )
{
  // An error occurred. Instruct the script writer to fix the
  // compilation errors that were listed in the output stream.
  printf("Please correct the errors in the script and try again.\n");
  return;
}
\endcode

The last step is to identify the function that is to be called, and set up a context
for executing it.

\code
// Find the function that is to be called.
asIScriptModule *mod = engine->GetModule("MyModule");
asIScriptFunction *func = mod->GetFunctionByDecl("void main()");
if( func == 0 )
{
  // The function couldn't be found. Instruct the script writer
  // to include the expected function in the script.
  printf("The script must have the function 'void main()'. Please add it and try again.\n");
  return;
}

// Create our context, prepare it, and then execute
asIScriptContext *ctx = engine->CreateContext();
ctx->Prepare(func);
int r = ctx->Execute();
if( r != asEXECUTION_FINISHED )
{
  // The execution didn't complete as expected. Determine what happened.
  if( r == asEXECUTION_EXCEPTION )
  {
    // An exception occurred, let the script writer know what happened so it can be corrected.
    printf("An exception '%s' occurred. Please correct the code and try again.\n", ctx->GetExceptionString());
  }
}
\endcode

The exception handling above is very basic. The application may also obtain information about line number,
function, call stack, and even values of local and global variables if wanted.

Don't forget to clean up after you're done with the engine.

\code
// Clean up
ctx->Release();
engine->ShutDownAndRelease();
\endcode

\section doc_hello_world_1 Helper functions

The print function is implemented as a very simple wrapper on the printf function.

\code
// Print the script string to the standard output stream
void print(string &msg)
{
  printf("%s", msg.c_str());
}
\endcode

\see \ref doc_compile_script_msg, \ref doc_addon_build, \ref doc_addon_std_string, \ref doc_samples

*/


code:
/**

\page doc_license License

\section doc_lic_1 AngelCode Scripting Library
Copyright © 2003-2024 Andreas Jönsson

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.

Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:

The origin of this software must not be misrepresented; you
     must not claim that you wrote the original software. If you use
     this software in a product, an acknowledgment in the product
     documentation would be appreciated but is not required.

Altered source versions must be plainly marked as such, and
     must not be misrepresented as being the original software.

This notice may not be removed or altered from any source
     distribution.

*/


code:
/**

\mainpage Introduction

\image html aslogo.png

Version 2.37.0

\ref doc_overview "AngelScript" is a \ref doc_license "free, open source", flexible, and cross-platform scripting library meant to be
embedded in applications. The purpose is to provide an easy to use library that is powerful, but that isn't weighed
down by a large amount of rarely used features.

Development of AngelScript begun in February, 2003, with the first public release on March 28th, 2003, with only the most basic
of functionality. Ever since that day the world has seen frequent releases with new features and improvements. The author is still
dedicated to the continued improvement and growth of this library.

The official site for the library is http://www.angelcode.com/angelscript.

\page main_topics Developer manual

 - \subpage doc_license
 - \subpage doc_start
 - \subpage doc_understanding_as
 - \subpage doc_register_api_topic
 - \subpage doc_compile_script
 - \subpage doc_call_script_func
 - \subpage doc_use_script_class
 - \subpage doc_callbacks
 - \subpage doc_advanced
 - \subpage doc_samples
 - \subpage doc_addon

\page doc_start Getting started

 - \subpage doc_overview
 - \subpage doc_compile_lib
 - \subpage doc_hello_world
 - \subpage doc_good_practice

\page doc_register_api_topic Registering the application interface

 - \subpage doc_register_api
 - \subpage doc_register_func
 - \subpage doc_register_prop
 - \subpage doc_register_type
 - \subpage doc_advanced_api

\page doc_advanced_api Advanced application interface

 - \subpage doc_strings
 - \subpage doc_arrays
 - \subpage doc_gc_object
 - \subpage doc_generic
 - \subpage doc_adv_generic_handle
 - \subpage doc_adv_scoped_type
 - \subpage doc_adv_single_ref_type
 - \subpage doc_adv_class_hierarchy
 - \subpage doc_adv_var_type
 - \subpage doc_adv_template
 - \subpage doc_adv_weakref
 - \subpage doc_cpp_exceptions

\todo Write a page on registering function templates
\todo Write a page on registering function with variadic

\page doc_advanced Advanced topics

 - \subpage doc_debug
 - \subpage doc_adv_timeout
 - \subpage doc_gc
 - \subpage doc_adv_multithread
 - \subpage doc_adv_concurrent
 - \subpage doc_adv_coroutine
 - \subpage doc_adv_import
 - \subpage doc_adv_dynamic_build
 - \subpage doc_adv_precompile
 - \subpage doc_finetuning
 - \subpage doc_adv_access_mask
 - \subpage doc_adv_namespace
 - \subpage doc_adv_dynamic_config
 - \subpage doc_adv_custom_options
 - \subpage doc_adv_reflection
 - \subpage doc_serialization
 - \subpage doc_adv_inheritappclass
 - \subpage doc_adv_jit_topic

\page doc_adv_jit_topic JIT compilation

 - \subpage doc_adv_jit
 - \subpage doc_adv_jit_1

\page doc_script The script language

This is the reference documentation for the AngelScript scripting language.

 - \subpage doc_script_global
 - \subpage doc_script_statements
 - \subpage doc_expressions
 - \subpage doc_datatypes
 - \subpage doc_script_func
 - \subpage doc_script_class
 - \subpage doc_script_handle
 - \subpage doc_script_shared
 - \subpage doc_operator_precedence
 - \subpage doc_reserved_keywords
 - \subpage doc_script_bnf
 - \subpage doc_script_stdlib

\page doc_script_global Global entities

All global declarations share the same namespace so their names may not
conflict. This includes extended data types and built-in functions registered
by the host application. Also, all declarations are visible to all, e.g. a
function to be called does not have to be declared above the function that calls
it.

 - \subpage doc_global_func
 - \subpage doc_global_variable
 - \subpage doc_global_virtprop
 - \subpage doc_global_class
 - \subpage doc_global_interface
 - \subpage doc_script_mixin
 - \subpage doc_global_enums
 - \subpage doc_global_funcdef
 - \subpage doc_global_typedef
 - \subpage doc_global_namespace
 - \subpage doc_global_import

\page doc_global_func Functions

\ref doc_script_func "Global functions" provide the mean to implement
routines that should operate on some input and produce a result.

  void foo()
  {
    // Do something
  }

\page doc_script_func Functions

Functions are declared globally, and consists of a signature where the types of the arguments and the return value
is defined, and a body where the implementation is declared.

- \subpage doc_script_func_decl
- \subpage doc_script_func_ref
- \subpage doc_script_func_retref
- \subpage doc_script_func_overload
- \subpage doc_script_func_defarg
- \subpage doc_script_anonfunc

\page doc_global_class Script classes

\ref doc_script_class "Script classes" are normally used to group together functions with values that will be
operated upon by those functions. Multiple instances of a class can exists where each instance has different values.

  class Foo
  {
    void bar() { value++; }
    int value;
  }

\page doc_script_class Script classes

Script classes are declared globally and provides an
easy way of grouping properties and methods into logical units. The syntax
for classes is similar to C++ and Java.

 - \subpage doc_script_class_desc
 - \subpage doc_script_class_construct
 - \subpage doc_script_class_memberinit
 - \subpage doc_script_class_destruct
 - \subpage doc_script_class_methods
 - \subpage doc_script_class_inheritance
 - \subpage doc_script_class_private
 - \subpage doc_script_class_ops
 - \subpage doc_script_class_prop

*/


code:
/**

\page doc_memory Memory management

This article will explain the memory management in AngelScript in detail.
It's probably more detail than most developers need to know, but some may want
to know exactly how it works in order to evaluate AngelScript better.

\section doc_memory_1 Overview of the memory management

AngelScript uses a hybrid method with both reference counting and garbage
collection, where reference counting is the main method and the garbage
collection is only for backup when circular references needs to be resolved.

This design was chosen because reference counting is the easiest way of
passing objects between script engine and application while still keeping
track of live objects. If pure garbage collection was used, the script engine
would have to know about the entire memory space of the application where
script objects could be stored, otherwise it wouldn't be able to know if the
objects are still alive or not.

The garbage collector is only used for those object types that have a
possibility of forming a circular reference with itself or other objects, e.g.
objects that have a member variable as a handle to the same type as itself.
Whenever such an object is created, the garbage collector is informed so that
it can keep track of the object.

The garbage collector can be executed automatically by the engine, but the
application may also choose to do it manually to have better control over when
it is done. The garbage collector is incremental, so it can be executed in
small steps throughout the application execution without halting the rest of the
processing for longer periods.

\see \ref doc_gc

\section doc_memory_2 Reference counting algorithm

All built-in script objects are automatically reference counted, and the
application just need to make sure to call the AddRef and Release methods
appropriately if it is storing any references to the objects outside the
script engine.

Application registered objects may or may not be reference counted. Those
that should be reference counted must implement the ADDREF and RELEASE
behaviours so that AngelScript can notify the objects of the changes to the
reference count. The application needs to keep track of the reference counter
itself and free the memory when there are no more references to the object.
This is usually done by having an integer member variable in the object
structure itself to hold the reference count. It can also be implemented with
a separate structure for holding the reference counter, but it adds extra
overhead as the reference counter must be searched for with each change.

\see \ref doc_register_type

\section doc_memory_3 Garbage collector algorithm

The garbage collector, used to handle the scenarios where reference counting
isn't enough, uses the following algorithm.

Destroy garbage: Free all objects with only one reference. This
    reference is held by the GC itself so therefore it is known that nobody
    else is referencing the object.

Clear counters: Clear the GC counter for the remaining objects.
    This counter will be used to count the references to the object reachable
    from the GC. At the same time the objects are also flagged, so that we can
    detect if the references change while the garbage collector is running.
    This flag is automatically cleared when incrementing or decrementing the
    reference counter.

Count GC references: For each of the objects in the GC, tell it to
    increment the GC counter for all objects it holds references to. This is
    only done for objects still flagged, because if the flag is no longer set
    we know it has been referenced by the application, thus it is considered
    alive along with all objects it holds references to.

Mark live objects: Build a list of all objects in the GC that are
    not flagged or that doesn't have the GC count equal to the reference
    counter. These are objects that are considered alive. For each of the
    objects in the list, add all of the references in the object to the list
    as well, unless they are already in the list. As the list is traversed it
    will grow with new objects, these objects will also have their references
    added to the list. This way we're following the chain of references so
    we're gathering all objects that are alive.

Verify unmarked objects: Make one more pass over the list of
    objects in the GC to see if any of the objects that were not marked as
    alive has had the flag cleared, if it has then the run the 'mark live
    objects' step again.

Break circular references: All objects that have not been marked as
    alive by this time are involved in unreachable circular references and must be
    destroyed. The objects are destroyed by telling the objects to release the
    references they hold, thus breaking the circular references. When all
    circular references have been broken, the entire GC routine is restarted
    which will free the objects. If there were no dead objects, then the GC
    is finished.

All of the steps are incremental, i.e. they can be interrupted to allow the
application and scripts to execute before continuing the garbage collection.
Step 1 can also be executed individually at any time during the cycle, this
permits to free up memory for objects that are not involved in cyclic memory
without having to wait for the detection cycle to complete.

The GC also has a notion of new and old generations. All new objects are placed in
the new generation. In this generation, only trivial garbage collection is done, i.e.
the 'destroy garbage' step above. Once the objects in the new generation have
survived a few iterations without being destroyed, they are moved to the old
generation. In the old generation the full garbage collection algorithm is executed.

This division of new and old generations help reduce the work done by the GC to
detect circular references, and thus improve the performance of the application.

\see \ref doc_gc_object

\section doc_memory_4 Memory heap

By default AngelScript uses the memory heap accessed through the standard
malloc and free global functions when allocating memory. Usually this means
that AngelScript shares the memory heap with the application, though if
the AngelScript library is compiled as a DLL or a shared object the heap may
actually be separate from the application heap.

Some applications need extra control over the memory heap that the standard
C/C++ library doesn't provide. This is common with video games for consoles,
that have limited memory and cannot afford loosing space due to fragmentation
or many small allocations. AngelScript aids these applications as well as it
is possible to register custom memory allocation routines with the library,
giving the application exact control over the memory used by AngelScript.

\see \ref asSetGlobalMemoryFunctions

*/


code:
/**

\page doc_module Script modules

Each \ref asIScriptModule "module" is an independent unit with it's own scope of script functions, global
variables, and classes. All scripts executed from a module will work on the same global variables contained
within that module. In this sense a module can be thought of as a shared library that is loaded into an
application.

\section doc_module_single_vs_multi Single module versus multiple modules

Whether it is better to use a single module with all the script code, or multiple modules with smaller and more
specialized scripts, depends on the needs of the application.

A single module can be easier to implement, as all script code is in the same scope and can interact with full
freedom. On the other hand the entire script must be compiled together, making it more difficult to exchange
parts of the script or load only the logic that is needed at the moment.

With multiple modules an application can also \ref doc_adv_access_mask "expose different interfaces" to scripts
with different tasks, e.g. a script that controls the graphical user interface in an application should perhaps
not have access to the same interface used by the script that controls the artificial intelligence, and vice versa.

Multiple modules can also use the same script code, in this case they will be completely distinct, each with
their own set of global variables, functions, and types, even though the same source code was used. There may be
valid reasons for using this in an application, but usually it is better to use a single module with \ref doc_script_class "script classes".
The bytecode, functions, and types will then be shared, and the variables that should be distinct for each instance
should be declared as class members.

\section doc_module_exchange Exchanging information between modules

While modules are independent, it may sometimes be necessary to exchange information between them. This can
be accomplished in many different ways. One way is through \ref asIScriptModule::BindImportedFunction "function binding",
where one module imports functions from another module and call those directly. Another way is with \ref doc_script_shared
"shared script entities", where handles to objects or functions can be exchanged between the modules. A third alternative
is through messaging or proxy functions exposed by the application.

All of these alternatives require a little code from the application, as one module doesn't automatically
see another without the application's knowledge.

*/


code:
/**

\page doc_obj_handle Object handles to the application

In AngelScript an object handle is a reference counted pointer to an object. In the scripts
they are used to pass the objects around by reference instead of by value. Depending on how
an application type is registered the type will support handles.

\see \ref doc_register_type, \ref doc_script_handle in the script language

\section doc_obj_handle_3 Managing the reference counter in functions

Whenever the object handle is passed by value from the application to the script engine,
or vice versa its reference should be accounted for. This means that the application must
release any object handles it receives as parameters when it no longer needs them, it also
means that the application must increase the reference counter for any object handle being
returned to the script engine. This also applies to the \ref doc_generic
"generic calling convention".

A function that creates an object and returns it to the script engine might look like this:

\code
// Registered as "obj@ CreateObject()"
obj *CreateObject()
{
  // The constructor already initializes the ref count to 1
  return new obj();
}
\endcode

A function that receives an object handle from the script and stores it in a global variable might look like this:

\code
// Registered as "void StoreObject(obj@)"
obj *o = 0;
void StoreObject(obj *newO)
{
  // Release the old object handle
  if( o ) o->Release();

  // Store the new object handle
  o = newO;
}
\endcode

A function that retrieves a previously stored object handle might look like this:

\code
// Registered as "obj@ RetrieveObject()"
obj *RetrieveObject()
{
  // Increase the reference counter to account for the returned handle
  if( o ) o->AddRef();

  // It is ok to return null if there is no previous handle stored
  return o;
}
\endcode

A function that receives an object handle in the parameter, but doesn't store it looks like this:

\code
// Registered as "void DoSomething(obj@)"
void DoSomething(obj *o)
{
  // When finished with the object it must be released
  if( o ) o->Release();
}
\endcode

\section doc_obj_handle_4 Auto handles can make it easier

The application can use auto handles (\@+) to alleviate some of the work of managing the reference counter.
When registering the function or method with AngelScript, add a plus sign to the object handles that
AngelScript should automatically manage. For parameters AngelScript will then release the reference after
the function returns, and for the return value AngelScript will increase the reference on the returned
pointer. The reference for the returned value is increased before the parameters are released, so it is
possible to have the function return one of the parameters.

\code
// Registered as "obj@+ ChooseObj(obj@+, obj@+)"
obj *ChooseObj(obj *a, obj *b)
{
  // Because of the auto handles AngelScript will
  // automatically manage the reference counters
  return some_condition ? a : b;
}
\endcode

The auto handles works the same way for the \ref doc_generic "generic calling convention".

*/


code:
/**

\page doc_overview Overview

AngelScript is structured around an \ref asIScriptEngine "engine" where the application should
\ref doc_register_api "register" the \ref doc_register_func "functions", \ref doc_register_prop "properties", and even \ref doc_register_type "types",
that the scripts will be able to use. The scripts are then compiled into \ref doc_module "modules",
where the application may have one or more modules, depending on the need of the application. The application can also expose
a different interface to each module through the use of \ref doc_adv_access_mask "access profiles".
This is especially useful when the application works with multiple types of scripts, e.g. GUI, AI control, etc.

As the scripts are compiled into bytecode AngelScript also provides a virtual machine, also known
as a \ref asIScriptContext "script context", for \ref doc_call_script_func "executing" the bytecode. The application can have any number of
script context at the same time, though most applications will probably only need one. The contexts support
\ref asIScriptContext::Suspend "suspending" the execution and then resuming it, so the application can easily
implement features such as \ref doc_adv_concurrent "concurrent scripts" and \ref doc_adv_coroutine "co-routines".
The script context also provides an interface for extracting run-time information, useful for \ref doc_debug "debugging" scripts.

The \ref doc_script "script language" is based on the well known syntax of C++ and more modern languages such as Java, C#, and D.
Anyone with some knowledge of those languages, or other script languages with similar syntax, such as Javascript and ActionScript,
should feel right at home with AngelScript. Contrary to most script languages, AngelScript is a strongly typed language, which
permits faster execution of the code and smoother interaction with the host application as there will be less need for runtime
evaluation of the true type of values.

The \ref doc_memory "memory management" in AngelScript is based on reference counting with an incremental \ref doc_gc "garbage collector"
for detecting and freeing objects with circular references. This provides for a controlled environment without application freezes as the
garbage collector steps in to free up memory.

*/


code:
/**

\page doc_register_api What can be registered

AngelScript requires the application developer to register the interface
that the scripts should use to interact with anything outside the script itself.

It's possible to register \ref doc_register_func "global functions" and
\ref doc_register_prop "global properties" that can be used directly by the
scripts.

For more complex scripts it may be useful to register new \ref doc_register_type "object types"
to complement the built-in data types.

AngelScript doesn't have a \ref doc_strings "built-in string type" as there is no de-facto standard for string types
in C++. Instead AngelScript permits the application to register its own preferred string type, and
a \ref asIScriptEngine::RegisterStringFactory "string factory" that the script engine will use
to instanciate the strings.

There is also no default \ref doc_arrays "built-in array type" as this too is something that most developers may want to have
their own version of. The array type is registered as a \ref doc_adv_template "template", which is then set as the
\ref asIScriptEngine::RegisterDefaultArrayType "default array type". A standard \ref doc_addon_array "array add-on" is
provided for those that do not want to implement their own array type.

\ref asIScriptEngine::RegisterInterface "Class interfaces" can be registered if you want
to guarantee that script classes implement a specific set of class methods. Interfaces can
be easier to use when working with script classes from the application, but they are not
necessary as the application can easily enumerate available methods and properties even
without the interfaces.

\ref asIScriptEngine::RegisterFuncdef "Function definitions" can be registered when you wish to allow the script
to pass function pointers to the application, e.g. to implement callback routines.

\ref asIScriptEngine::RegisterEnum "Enumeration types" and
\ref asIScriptEngine::RegisterTypedef "typedefs" can also be registered to improve readability of the scripts.

*/


code:
/**

\page doc_register_func Registering a function

This article aims to explain the way functions are registered with AngelScript, and some of the
differences between C++ and AngelScript that the developer needs to be aware of in order to be
successful in registering the application interface that the scripts will use. The principles
learned here are used in several locations, such as \ref asIScriptEngine::RegisterGlobalFunction
"RegisterGlobalFunction", \ref asIScriptEngine::RegisterObjectMethod "RegisterObjectMethod", \ref
asIScriptEngine::RegisterObjectBehaviour "RegisterObjectBehaviour", etc.

\section doc_register_func_1 How to get the address of the application function or method

The macros \ref asFUNCTION, \ref asFUNCTIONPR, \ref asMETHOD, and \ref asMETHODPR
have been implemented to facilitate the task of getting the function pointer and
passing them on to the script engine.

The asFUNCTION takes the function name as the parameter, which works for all global
functions that do not have any overloads. If you use overloads, i.e. multiple functions
with the same name but with different parameters, then you need to use asFUNCTIONPR instead.
This macro takes as parameter the function name, parameter list, and return type, so that
the C++ compiler can resolve exactly which overloaded function to take the address of.

\code
// Global function
void globalFunc();
r = engine->RegisterGlobalFunction("void globalFunc()", asFUNCTION(globalFunc), asCALL_CDECL); assert( r >= 0 );

// Overloaded global functions
void globalFunc2(int);
void globalFunc2(float);
r = engine->RegisterGlobalFunction("void globalFunc2(int)", asFUNCTIONPR(globalFunc2, (int), void), asCALL_CDECL); assert( r >= 0 );
\endcode

The same goes for asMETHOD and asMETHODPR. The difference between these and asFUNCTION/asFUNCTIONPR
is that the former take the class name as well as parameter.

\code
class Object
{
  // Class method
  void method();

  // Overloaded method
  void method2(int input);
  void method2(int input, int &output);

  // Const method
  int getAttr(int) const;
};

// Registering the class method
r = engine->RegisterObjectMethod("object", "void method()", asMETHOD(Object,method), asCALL_THISCALL); assert( r >= 0 );

// Registering the overloaded methods
r = engine->RegisterObjectMethod("object", "void method2(int)", asMETHODPR(Object, method2, (int), void), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod("object", "void method2(int, int &out)", asMETHODPR(Object, method2, (int, int&), void), asCALL_THISCALL); assert( r >= 0 );

// Registering a const method
r = engine->RegisterObjectMethod("object", "int getAttr(int) const", asMETHODPR(Object, getAttr, (int) const, int), asCALL_THISCALL); assert( r >= 0 );
\endcode

\note asMETHOD doesn't work well for classes with multiple inheritances. On some compilers the method pointer ends up referring to the wrong base class due to a limitation in the C++ compiler. The solution then is to use the asMETHODPR macro.

It is possible to register a class method to be called from the script as if it was a global function. This is commonly done when exposing a singleton
to the script interface, as the singleton's methods then look like ordinary global functions. When this is done the application must have a reference to
the object at the time of the registration and the application must guarantee that the object is alive until it is no longer possible for the scripts
to call the method.

\code
class MySingleton
{
  // Class method to be called from script as if a global function
  void MyGlobalFunc(int arg1, int arg2);
};

MySingleton single;

// Registering the singleton's method as if a global function
r = engine->RegisterGlobalFunction("void MyGlobalFunc(int, int)", asMETHOD(MySingleton, MyGlobalFunc), asCALL_THISCALL_ASGLOBAL, &single); assert( r >= 0 );
\endcode

\section doc_register_func_2 Calling convention

AngelScript accepts most common calling conventions that C++ uses, i.e. cdecl, stdcall, and thiscall. There is also a
generic calling convention that can be used for example when native calling conventions are not supported on the target platform.

All functions and behaviours must be registered with the \ref asCALL_CDECL, \ref asCALL_STDCALL, \ref asCALL_THISCALL, or
\ref asCALL_GENERIC flags to tell AngelScript which calling convention the application function uses. The special conventions
\ref asCALL_CDECL_OBJLAST and \ref asCALL_CDECL_OBJFIRST can also be used wherever asCALL_THISCALL is accepted, in order to
simulate a class method through a global function. Functor objects can also be used to emulate global functions with the
convention \ref asCALL_THISCALL_ASGLOBAL, or class methods with the conventions \ref asCALL_THISCALL_OBJFIRST and \ref asCALL_THISCALL_OBJLAST.

If the incorrect calling convention is given on the registration you'll very likely see the application crash with
a stack corruption whenever the script engine calls the function. cdecl is the default calling convention for all global
functions in C++ programs, so if in doubt try with asCALL_CDECL first. The calling convention only differs from cdecl if the
function is explicitly declared to use a different convention, or if you've set the compiler options to default to another
convention.

For class methods there is only the thiscall convention, except when the method is static, as those methods are in truth global
functions in the class namespace. Normal methods, virtual methods, and methods for classes with multiple inheritance are all
registered the same way, with asCALL_THISCALL.

Classes with \ref doc_register_func_4 "virtual inheritance are not supported natively", and for these it will be necessary
to create wrapper functions. These wrapper functions can either be implemented manually, or the template based automatic
wrappers from the \ref doc_addon_autowrap "add-on" can be used.

\see \ref doc_generic

\section doc_register_func_3 A little on type differences

AngelScript supports most of the same types that C++ has, but there are differences that you'll need to know when registering
functions, methods, and behaviours. Make sure you read and understand the article \ref doc_as_vs_cpp_types.

When registering functions that take references, you must make sure to inform the correct keyword that informs the intention of
the data in the reference. For example, a parameter reference that is meant to be used as input should have the keyword 'in'
defined after the & character, and an output reference should have the keyword 'out'. \ref doc_reg_basicref "Reference types"
can be passed as both input and output references, in which case the keyword 'inout' can be used, or simply no keyword at all.
\ref doc_register_val_type "Value types" on the other hand cannot use 'inout' references, as AngelScript cannot guarantee that
the reference will be valid during the whole execution of the function.

When registering functions that take pointers, you need to determine what the pointer represents. If the pointer
is to a value type though, then it can only be registered as a reference. If the pointer is to a reference type, then it can
be registered as an \ref doc_obj_handle "object handle", or as a plain reference. If you choose to use the object handle then
you need to pay attention to the reference counter in the type so you don't get problems with memory leaks or crashes due to
objects being destroyed too early.

\section doc_register_func_4 Virtual inheritance is not supported

Registering class methods for classes with virtual inheritance is not supported due to the high complexity involved with them.
Each compiler implements the method pointers for these classes differently, and keeping the code portable would be very difficult.
This is not a great loss though, as classes with virtual inheritance are relatively rare, and it is easy to write simple proxy
functions where the classes to exist.

\code
class A { void SomeMethodA(); };
class B : virtual A {};
class C : virtual A {};
class D : public B, public C {};

// Need a proxy function for registering SomeMethodA for class D
void D_SomeMethodA_proxy(D *d)
{
  // The C++ compiler will resolve the virtual method for us
  d->SomeMethodA();
}

// Register the global function as if it was a class method,
// but with calling convention asCALL_CDECL_OBJLAST
engine->RegisterObjectMethod("D", "void SomeMethodA()", asFUNCTION(D_SomeMethodA_proxy), asCALL_CDECL_OBJLAST);
\endcode

If you have a lot of classes with virtual inheritance, you should probably think about writing a template proxy function, so
you don't have to manually write all the proxy functions.

*/


code:
/**

\page doc_register_prop Registering global properties

By registering global properties with the script engine you can allow the scripts to
inspect and/or modify variables within the application directly, without the need to
write special functions to do this.

To register the property, you just need to call the \ref asIScriptEngine::RegisterGlobalProperty
"RegisterGlobalProperty" method, passing the declaration and a pointer to the property.
Remember that the registered property must stay alive as long as its registration is
valid in the engine.

Make sure you give the correct pointer to AngelScript. The pointer should be to value that the
declaration refers to, i.e. if the declaration is an integer then the pointer should be to the
integer value, if the declaration is an object handle then the pointer should be to the pointer
to the object, etc. Unfortunately there is no way for AngelScript to validate that the pointer
is correct, so if the wrong pointer is given, you will only detect it at runtime when seeing
unexpected behaviours from the application.

\code
// Variables that should be accessible through the script.
int      g_number       = 0;
CObject *g_object       = 0;
Vector3  g_vector       = {0,0,0};
bool     g_readOnlyFlag = false;

// A function to register the global properties.
void RegisterProperties(asIScriptEngine *engine)
{
    int r;

    // Register a primitive property that can be read and written to from the script.
    r = engine->RegisterGlobalProperty("int g_number", &g_number); assert( r >= 0 );

    // Register variable where the script can store a handle to a CObject type.
    // Assumes that the CObject type has been registered with the engine already as a reference type.
    r = engine->RegisterGlobalProperty("CObject @g_object", &g_object); assert( r >= 0 );

    // Register a 3D vector variable.
    // Assumes that the Vector3 type has been registered already as a value type.
    r = engine->RegisterGlobalProperty("Vector3 g_vector", &g_vector); assert( r >= 0 );

    // Register a boolean flag that can be read, but not modified by the script.
    r = engine->RegisterGlobalProperty("const bool g_readOnlyFlag", &g_readOnlyFlag); assert( r >= 0 );
}
\endcode

It is also possible to expose properties through \ref doc_script_class_prop "property accessors", which are a pair of functions
with the prefixes 'get_' and 'set_' and the function decorator 'property' for getting and setting the property value. These functions
should be registered with \ref doc_register_func "RegisterGlobalFunction". This is especially useful when the offset of the property
cannot be determined, or if the type of the property is not registered in the script and some translation must occur, i.e. from
<tt>char*</tt> to <tt>string</tt>.

\note The behaviour of virtual properties can be customized with the engine property \ref doc_adv_custom_options_lang_mod "asEP_PROPERTY_ACCESSOR_MODE".

\see \ref doc_register_type

*/