code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: dictionary</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

dictionary

Note

Dictionaries are only available in the scripts if the application registers the support for them. The syntax for using dictionaries may differ for the application you're working with so consult the application's manual for more details.

The dictionary stores key-value pairs, where the key is a string, and the value can be of any type. Key-value pairs can be added or removed dynamically, making the dictionary a good general purpose container object.

  obj object;
  obj @handle;

  // Initialize with a list
  dictionary dict = {{'one', 1}, {'object', object}, {'handle', @handle}};

  // Examine and access the values through get or set methods ...
  if( dict.exists('one') )
  {
    // get returns true if the stored type is compatible with the requested type
    bool isValid = dict.get('handle', @handle);
    if( isValid )
    {
      dict.delete('object');
      dict.set('value', 1);
    }
  }

Dictionary values can also be accessed or added by using the index operator.

  // Read and modify an integer value
  int val = int(dict['value']);
  dict['value'] = val + 1;

  // Read and modify a handle to an object instance
  @handle = cast<obj>(dict['handle']);
  if( handle is null )
    @dict['handle'] = object;

Dictionaries can also be created and initialized within expressions as anonymous objects.

  // Call a function that expects a dictionary as input and no other overloads
  // In this case it is possible to inform the initialization list without explicitly giving the type
  foo({{'a', 1},{'b', 2}});

  // Call a function where there are multiple overloads expecting different
  // In this case it is necessary to explicitly define the type of the initialization list
  foo2(dictionary = {{'a', 1},{'b', 2}});

Dictionaries of dictionaries are created using anonymous objects as well.

  dictionary d2 = {{'a', dictionary = {{'aa', 1}, {'ab', 2}}},
                   {'b', dictionary = {{'ba', 1}, {'bb', 2}}}};

Supporting dictionary object

The dictionary object is a reference type, so it's possible to use handles to the dictionary object when passing it around to avoid costly copies.

Operators

= assignment

The assignment operator performs a shallow copy of the content.

[] index operator

The index operator takes a string for the key, and returns a reference to the value. If the key/value pair doesn't exist it will be inserted with a null value.

Methods

void set(const string &in key, ? &in value)

 void set(const string &in key, int64 &in value)

 void set(const string &in key, double &in value)

Sets a key/value pair in the dictionary. If the key already exists, the value will be changed.

bool get(const string &in key, ? &out value) const

 bool get(const string &in key, int64 &out value) const

 bool get(const string &in key, double &out value) const

Retrieves the value corresponding to the key. The methods return false if the key is not found, and in this case the value will maintain its default value based on the type.

array<string> @getKeys() const

This method returns an array with all of the existing keys in the dictionary. The order of the keys in the array is undefined.

bool exists(const string &in key) const

Returns true if the key exists in the dictionary.

bool delete(const string &in key)

Removes the key and the corresponding value from the dictionary. Returns false if the key wasn't found.

void deleteAll()

Removes all entries in the dictionary.

bool isEmpty() const

Returns true if the dictionary doesn't hold any entries.

uint getSize() const

Returns the number of keys in the dictionary.

Supporting dictionaryValue object

The dictionaryValue type is how the dictionary object stores the values. When accessing the values through the dictionary index operator a reference to a dictionaryValue is returned.

The dictionaryValue type itself is a value type, i.e. no handles to it can be held, but it can hold handles to other objects as well as values of any type.

Operators

= assignment

The value assignment operator should be used to copy a value into the dictionaryValue.

@= handle assignment

The handle assignment operator should be used to set the dictionaryValue to refer to an object instance.

cast<type> cast operator

The cast operator is used to dynamically cast the handle held in the dictionaryValue to the desired type. If the dictionaryValue doesn't hold a handle, or the handle is not compatible with the desired type, the cast operator will return a null handle.

type() conversion operator

The conversion operator is used to return a new value of the desired type. If no value conversion is found, an uninitialized value of the desired type is returned.

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Function handles</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Function handles

A function handle is a data type that can be dynamically set to point to a global function that has a matching function signature as that defined by the variable declaration. Function handles are commonly used for callbacks, i.e. where a piece of code must be able to call back to some code based on some conditions, but the code that needs to be called is not known at compile time.

To use function handles it is first necessary to define the function signature that will be used at the global scope or as a member of a class. Once that is done the variables can be declared using that definition.

Here's an example that shows the syntax for using function handles

  // Define a function signature for the function handle
  funcdef bool CALLBACK(int, int);

  // An example function that shows how to use this
  void main()
  {
    // Declare a function handle, and set it
    // to point to the myCompare function.
    CALLBACK @func = @myCompare;

    // The function handle can be compared with the 'is' operator
    if( func is null )
    {
      print("The function handle is null\n");
      return;
    }

    // Call the function through the handle, just as if it was a normal function
    if( func(1, 2) )
    {
      print("The function returned true\n");
    }
    else
    {
      print("The function returned false\n");
    }
  }

  // This function matches the CALLBACK definition, since it has
  // the same return type and parameter types.
  bool myCompare(int a, int b)
  {
    return a > b;
  }

Delegates

It is also possible to take function handles to class methods, but in this case the class method must be bound to the object instance that will be used for the call. To do this binding is called creating a delegate, and is done by performing a construct call for the declared function definition passing the class method as the argument.

  class A
  {
    bool Cmp(int a, int b)
    {
       count++;
       return a > b;
    }
    int count = 0;
  }

  void main()
  {
    A a;

    // Create the delegate for the A::Cmp class method
    CALLBACK @func = CALLBACK(a.Cmp);

    // Call the delegate normally as if it was a global function
    if( func(1,2) )
    {
      print("The function returned true\n");
    }
    else
    {
      print("The function returned false\n");
    }

    printf("The number of comparisons performed is "+a.count+"\n");
  }

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6

repo_name: Antidote/openrpgeditor

license: mit


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Objects and handles</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Objects and handles

Objects

There are two forms of objects, reference types and value types.

Value types behave much like the primitive types, in that they are allocated on the stack and deallocated when the variable goes out of scope. Only the application can register these types, so you need to check with the application's documentation for more information about the registered types.

Reference types are allocated on the memory heap, and may outlive the initial variable that allocates them if another reference to the instance is kept. All script declared classes are reference types. Interfaces are a special form of reference types, that cannot be instantiated, but can be used to access the objects that implement the interfaces without knowing exactly what type of object it is.

  obj o;      // An object is instantiated
  o = obj();  // A temporary instance is created whose
              // value is assigned to the variable

Object handles

Object handles are a special type that can be used to hold references to other objects. When calling methods or accessing properties on a variable that is an object handle you will be accessing the actual object that the handle references, just as if it was an alias. Note that unless initialized with the handle of an object, the handle is null.

  obj o;
  obj@ a;           // a is initialized to null
  obj@ b = @o;      // b holds a reference to o

  b.ModifyMe();     // The method modifies the original object

  if( a is null )   // Verify if the object points to an object
  {
    @a = @b;        // Make a hold a reference to the same object as b
  }

Not all types allow a handle to be taken. Neither of the primitive types can have handles, and there may exist some object types that do not allow handles. Which objects allow handles or not, are up to the application that registers them.

Object handle and array type modifiers can be combined to form handles to arrays, or arrays of handles, etc.

See also

Object handles

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Primitives</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Primitives

void

void is not really a data type, more like lack of data type. It can only be used to tell the compiler that a function doesn't return any data.

bool

bool is a boolean type with only two possible values: true or false. The keywords true and false are constants of type bool that can be used as such in expressions.

Integer numbers

type	min value	max value

int8 	-128	127

int16 	-32,768	32,767

int 	-2,147,483,648	2,147,483,647

int64 	-9,223,372,036,854,775,808	9,223,372,036,854,775,807

uint8 	0	255

uint16	0	65,535

uint 	0	4,294,967,295

uint64	0	18,446,744,073,709,551,615

As the scripting engine has been optimized for 32 bit datatypes, using the smaller variants is only recommended for accessing application specified variables. For local variables it is better to use the 32 bit variant.

int32 is an alias for int, and uint32 is an alias for uint.

Real numbers

type	range of values	smallest positive value 	maximum digits

float  	+/- 3.402823466e+38  	1.175494351e-38  	6

double 	+/- 1.79769313486231e+308 	2.22507385850720e-308 	15

Note

These numbers assume the platform uses the IEEE 754 to represent floating point numbers in the CPU

Rounding errors may occur if more digits than the maximum number of digits are used.

Curiousity: Real numbers may also have the additional values of positive and negative 0 or infinite, and NaN (Not-a-Number). For float NaN is represented by the 32 bit data word 0x7fc00000.

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: ref</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

ref

Note

ref is only available in the scripts if the application registers the support for it.

The ref type works like a generic object handle. Normally a handle can only refer to objects of a specific type or those related to it, however not all object types are related, and this is where ref comes in. Being completely generic it can refer to any object type (as long as it is a reference type).

  // Two unrelated types
  class car {}
  class banana {}

  // A function that take the ref type as argument can work on both types
  void func(ref @handle)
  {
    // Cast the handle to the expected type and check which cast work
    car @c = cast<car>(handle);
    banana @b = cast<banana>(handle);
    if( c !is null )
      print('The handle refers to a car\n');
    else if( b !is null )
      print('The handle refers to a banana\n');
    else if( handle !is null )
      print('The handle refers to a different object\n');
    else
      print('The handle is null\n');
  }

  void main()
  {
    // Assigning a ref handle works the same way as ordinary handles
    ref @r = car();
    func(r);
    @r = banana();
    func(r);
  }

Supporting ref object

The ref object supports only a few operators as it is just a place holder for handles.

Operators

@= handle assignment

The handle assignment operator is used to set the object that the referred to by the ref type.

is, !is identity operator

The identity operators are used to compare the address of the object referred to by the ref type.

cast<type> cast operator

The cast operator is used to perform a dynamic cast to the desired type. If the type is not compatible with the object referred to by the ref type this will return null.

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Strings</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Strings

Note

Strings are only available in the scripts if the application registers the support for them. The syntax for using strings may differ for the application you're working with so consult the application's manual for more details.

Strings hold an array of bytes or 16bit words depending on the application settings. Normally they are used to store text but can really store any kind of binary data.

There are two types of string constants supported in the AngelScript language, the normal quoted string, and the documentation strings, called heredoc strings.

The normal strings are written between double quotation marks ("</code>) or single quotation marks (<code>'</code>).
Inside the constant strings some escape sequences can be used to write exact
byte values that might not be possible to write in your normal editor.

<table cellspacing=0 cellpadding=0 border=0>
<tr><td width=100 valign=top><b>sequence</b></td>
<td valign=top width=100><b>value</b></td>
<td valign=top><b>description</b></td></tr>

<tr><td width=80 valign=top><code>\\0</code>&nbsp;  </td>
<td valign=top width=50>0</td>
<td valign=top>null character</td></tr>
<tr><td width=80 valign=top><code>\\\\</code>&nbsp;  </td>
<td valign=top width=50>92</td>
<td valign=top>back-slash</td></tr>
<tr><td width=80 valign=top><code>\\'</code>&nbsp;  </td>
<td valign=top width=50>39</td>
<td valign=top>single quotation mark (apostrophe)</td></tr>
<tr><td width=80 valign=top><code>\\"</code>&nbsp;  </td>
<td valign=top width=50>34</td>
<td valign=top>double quotation mark</td></tr>
<tr><td width=80 valign=top><code>\\n</code>&nbsp;  </td>
<td valign=top width=50>10</td>
<td valign=top>new line feed</td></tr>
<tr><td width=80 valign=top><code>\\r</code>&nbsp;  </td>
<td valign=top width=50>13</td>
<td valign=top>carriage return</td></tr>
<tr><td width=80 valign=top><code>\\t</code>&nbsp;  </td>
<td valign=top width=50>9</td>
<td valign=top>tab character</td></tr>
<tr><td width=80 valign=top><code>\\xFFFF</code>&nbsp;</td>
<td valign=top width=50>0xFFFF</td>
<td valign=top>FFFF should be exchanged for a 1 to 4 digit hexadecimal number representing the value wanted. If the application uses 8bit strings then only values up to 255 is accepted.</td></tr>
<tr><td width=80 valign=top><code>\\uFFFF</code>&nbsp;</td>
<td valign=top width=50>0xFFFF</td>
<td valign=top>FFFF should be exchanged for the hexadecimal number representing the unicode code point</td></tr>
<tr><td width=80 valign=top><code>\\UFFFFFFFF</code>&nbsp;</td>
<td valign=top width=50>0xFFFFFFFF</td>
<td valign=top>FFFFFFFF should be exchanged for the hexadecimal number representing the unicode code point</td></tr>
</table>

<pre>
  string str1 = "This is a string with "escape sequences" .";
  string str2 = 'If single quotes are used then double quotes can be included without "escape sequences".';
</pre>

The heredoc strings are designed for inclusion of large portions of text
without processing of escape sequences. A heredoc string is surrounded by
triple double-quotation marks (<code>"""), and can span multiple lines of code. If the characters following the start of the string until the first linebreak only contains white space, it is automatically removed by the compiler. Likewise if the characters following the last line break until the end of the string only contains white space this is also removed.

  string str = """
  This is some text without "escape sequences". This is some text.
  This is some text. This is some text. This is some text. This is
  some text. This is some text. This is some text. This is some
  text. This is some text. This is some text. This is some text.
  This is some text.
  """;

If more than one string constants are written in sequence with only whitespace or comments between them the compiler will concatenate them into one constant.

  string str = "First line.\n"
               "Second line.\n"
               "Third line.\n";

The escape sequences \u and \U will add the specified unicode code point as a UTF-8 or UTF-16 encoded sequence depending on the application settings. Only valid unicode 5.1 code points are accepted, i.e. code points between U+D800 and U+DFFF (reserved for surrogate pairs) or above U+10FFFF are not accepted.

See also

string

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: weakref</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

weakref

Note

weakref is only available in the scripts if the application registers the support for it.

An object handle will keep the object it refers to alive as long as the handle itself exists. A weakref object can be used in place of the handle where the reference to the object is needed but the object shouldn't be kept alive.

  class MyClass {}
  MyClass @obj1 = MyClass();

  // Keep a weakref to the object
  weakref<MyClass> r1(obj1);

  // Keep a weakref to a readonly object
  const_weakref<MyClass> r2(obj1);

  // As long as there is a strong reference to the object,
  // the weakref will be able to return a handle to the object
  MyClass @obj2 = r1.get();
  assert( obj2 !is null );

  // After all strong references are removed the
  // weakref will only return null
  @obj1 = null;
  @obj2 = null;

  const MyClass @obj3 = r2.get();
  assert( obj3 is null );

Supporting weakref object

Constructors

weakref<T>()

 weakref<T>(T@) explicit

 const_weakref<T>()

 const_weakref<T>(const T@) explicit

Operators

@= handle assignment

The handle assignment operator is used to set the object that the referred to by the ref type.

= value assignment

The value assignment operator is used when one weakref object is copied to another.

is, !is identity operator

The identity operators are used to compare the address of the object referred to by the ref type.

cast<type> implicit cast operator

The implicit cast operator is used to cast the weak ref type to strong reference of the type. If the object referred to by the weakref is already dead this operator will return null.

Methods

T@ get() const

This does the exact same thing as the implicit cast operator. It is just a more explicit way of writing it.

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Debugging scripts</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

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 also

Debugger for a standard implementation

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.

// 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();

  }

}

asIScriptContext

The interface to the virtual machine.

Definition: angelscript.h:2735

asIScriptContext::GetFunction

virtual asIScriptFunction * GetFunction(asUINT stackLevel=0)=0

Returns the function at the specified callstack level.

asIScriptContext::Suspend

virtual int Suspend()=0

Suspends the execution, which can then be resumed by calling Execute again.

asIScriptContext::GetLineNumber

virtual int GetLineNumber(asUINT stackLevel=0, int *column=0, const char **sectionName=0)=0

Returns the line number at the specified callstack level.

asIScriptFunction

The interface for a script function description.

Definition: angelscript.h:4000

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

// Set the line callback with the address of the debug manager as parameter

ctx->SetLineCallback(asFUNCTION(DebugLineCallback), dbg, asCALL_CDECL);

asCALL_CDECL

@ asCALL_CDECL

A cdecl function.

Definition: angelscript.h:230

asFUNCTION

#define asFUNCTION(f)

Returns an asSFuncPtr representing the function specified by the name.

Definition: angelscript.h:685

asIScriptContext::SetLineCallback

virtual int SetLineCallback(asSFuncPtr callback, void *obj, int callConv)=0

Sets a line callback function. The function will be called for each executed script statement.

When the line callback suspends the execution the context's Execute function will return with the code asEXECUTION_SUSPENDED. The application can then go into a special message loop where the debug routines can be handled, e.g. to view the call stack, 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.

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 print the value of variables at each level in the callstack.

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

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

  }

}

asUINT

unsigned int asUINT

32 bit unsigned integer

Definition: angelscript.h:610

asIScriptContext::GetCallstackSize

virtual asUINT GetCallstackSize() const =0

Returns the size of the callstack, i.e. the number of functions that have yet to complete.

asIScriptFunction::GetDeclaration

virtual const char * GetDeclaration(bool includeObjectName=true, bool includeNamespace=false, bool includeParamNames=false) const =0

Returns the function declaration.

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:

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

    }

  }

}

asTYPEID_SCRIPTOBJECT

@ asTYPEID_SCRIPTOBJECT

The bit that shows if the type is a script class.

Definition: angelscript.h:502

asTYPEID_FLOAT

@ asTYPEID_FLOAT

The type id for float.

Definition: angelscript.h:490

asTYPEID_INT32

@ asTYPEID_INT32

The type id for int.

Definition: angelscript.h:478

asIScriptContext::GetAddressOfVar

virtual void * GetAddressOfVar(asUINT varIndex, asUINT stackLevel=0, bool dontDereference=false, bool returnAddressOfUnitializedObjects=false)=0

Returns a pointer to a local variable at the specified callstack level.

asIScriptContext::GetThisPointer

virtual void * GetThisPointer(asUINT stackLevel=0)=0

Returns a pointer to the object, if a class method is being executed.

asIScriptContext::GetVarCount

virtual int GetVarCount(asUINT stackLevel=0)=0

Returns the number of local variables at the specified callstack level.

asIScriptContext::GetThisTypeId

virtual int GetThisTypeId(asUINT stackLevel=0)=0

Returns the type id of the object, if a class method is being executed.

asIScriptContext::GetEngine

virtual asIScriptEngine * GetEngine() const =0

Returns a pointer to the engine.

asIScriptContext::GetVarDeclaration

virtual const char * GetVarDeclaration(asUINT varIndex, asUINT stackLevel=0, bool includeNamespace=false)=0

Returns the declaration of a local variable at the specified callstack level.

asIScriptContext::GetVarTypeId

virtual int GetVarTypeId(asUINT varIndex, asUINT stackLevel=0)=0

Returns the type id of a local variable at the specified callstack level.

asIScriptEngine

The engine interface.

Definition: angelscript.h:1102

asIScriptEngine::GetTypeIdByDecl

virtual int GetTypeIdByDecl(const char *decl) const =0

Returns a type id by declaration.

asIScriptObject

The interface for an instance of a script object.

Definition: angelscript.h:3590

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

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

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Expressions</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Expressions

Assignments

Function call

Math operators

Bitwise operators

Compound assignments

Logic operators

Equality comparison operators

Relational comparison operators

Identity comparison operators

Increment operators

Indexing operator

Conditional expression

Member access

Handle-of

Parenthesis

Scope resolution

Type conversions

Anonymous objects

Assignments

  lvalue = rvalue;

lvalue must be an expression that evaluates to a memory location where the expression value can be stored, e.g. a variable. An assignment evaluates to the same value and type of the data stored. The right hand expression is always computed before the left.

Function call

  func();
  func(arg);
  func(arg1, arg2);
  lvalue = func();

Functions are called to perform an action, and possibly return a value that can be used in further operations. If a function takes more than one argument, the argument expressions are evaluated in the reverse order, i.e. the last argument is evaluated first.

Some functions are declared with output reference parameters to return multiple values. When calling such functions the output parameter must be given as an expression that can be assigned with the returned value. If the additional output value won't be used use the special argument 'void' to tell the compiler that.

  // This function returns a value in the output parameter
  void func(int &out outputValue)
  {
    outputValue = 42;
  }

  // Call the function with a valid lvalue expression to receive the output value
  int value;
  func(value);

  // Call the function with 'void' argument to ignore the output value
  func(void);

Arguments can also be named and passed to a specific argument independent of the order the parameters were declared in. No positional arguments may follow any named arguments.

  void func(int flagA = false, int flagB = false, int flagC = false) {}

  // Call the function, setting only a subset of its parameters
  func(flagC: true);
  func(flagB: true, flagA: true);

Math operators

  c = -(a + b);

operator	description	left hand	right hand	result

+ 	unary positive 	  	NUM 	NUM

- 	unary negative 	  	NUM 	NUM

+ 	addition 	NUM 	NUM 	NUM

- 	subtraction 	NUM 	NUM 	NUM

* 	multiplication 	NUM 	NUM 	NUM

/ 	division 	NUM 	NUM 	NUM

% 	modulos 	NUM 	NUM 	NUM

** 	exponent 	NUM 	NUM 	NUM

Plus and minus can be used as unary operators as well. NUM can be exchanged for any numeric type, e.g. int or float. Both terms of the dual operations will be implicitly converted to have the same type. The result is always the same type as the original terms. One exception is unary negative which is not available for uint.

Bitwise operators

  c = ~(a | b);

operator 	description 	left hand	right hand	result

~ 	bitwise complement 	  	NUM 	NUM

& 	bitwise and 	NUM 	NUM 	NUM

| 	bitwise or 	NUM 	NUM 	NUM

^ 	bitwise xor 	NUM 	NUM 	NUM

<< 	left shift 	NUM 	NUM 	NUM

>> 	right shift 	NUM 	NUM 	NUM

>>>	arithmetic right shift	NUM 	NUM 	NUM

All except ~ are dual operators.

Both operands will be converted to integers while keeping the sign of the original type before the operation. The resulting type will be the same as the left hand operand.

Compound assignments

  lvalue += rvalue;
  lvalue = lvalue + rvalue;

A compound assignment is a combination of an operator followed by the assignment. The two expressions above means practically the same thing. Except that first one is more efficient in that the lvalue is only evaluated once, which can make a difference if the lvalue is complex expression in itself.

Available operators: += -= *= /= %= **= &= |= ^= <<= >>= >>>=

Logic operators

  if( a and b or not c )
  {
    // ... do something
  }

operator 	description 	left hand 	right hand	result

not	logical not 	  	bool	bool

and	logical and 	bool	bool	bool

or 	logical or 	bool	bool	bool

xor	logical exclusive or	bool	bool	bool

Boolean operators only evaluate necessary terms. For example in expression a and b, b is only evaluated if a is true.

Each of the logic operators can be written as symbols as well, i.e. || for or, && for and, ^^ for xor, and ! for not.

Equality comparison operators

  if( a == b )
  {
    // ... do something
  }

The operators == and != are used to compare two values to determine if they are equal or not equal, respectively. The result of this operation is always a boolean value.

Relational comparison operators

  if( a > b )
  {
    // ... do something
  }

The operators <, >, <=, and >= are used to compare two values to determine their relationship. The result is always a boolean value.

Identity comparison operators

  if( a is null )
  {
    // ... do something
  }
  else if( a is b )
  {
    // ... do something
  }

The operators is and !is are used to compare the identity of two objects, i.e. to determine if the two are the same object or not. These operators are only valid for reference types as they compare the address of two objects. The result is always a boolean value.

Increment operators

  // The following means a = i; i = i + 1;
  a = i++;

  // The following means i = i - 1; b = i;
  b = --i;

These operators can be placed either before or after an lvalue to increment/decrement its value either before or after the value is used in the expression. The value is always incremented or decremented with 1.

Indexing operator

  arr[i] = 1;

This operator is used to access an element contained within the object. Depending on the object type, the expression between the [] needs to be of different types.

Conditional expression

  choose ? a : b;

If the value of choose is true then the expression returns a otherwise it will return b.

Both a and b must be of the same type. If they are not, the compiler will attempt an implicit conversion by following the principle of least cost, i.e. the expression that will be converted is the one that cost less to convert. This cost is determined the same way as is done for matching arguments in function calls.

If the conversion doesn't work, or the conversion of either expression cost the same, then the compiler will give an error.

The conditional expression can be used as an lvalue, i.e. on the left value of an assignment expression, if both a and b are lvalues of the same type.

  int a, b;
  (expr ? a : b) = 42;

Member access

  object.property = 1;
  object.method();

object must be an expression resulting in a data type that have members. property is the name of a member variable that can be read/set directly. method is the name of a member method that can be called on the object.

Handle-of

  // Make handle reference the object instance
  @handle = @object;

  // Clear the handle and release the object it references
  @handle = null;

Object handles are references to an object. More than one handle can reference the same object, and only when no more handles reference an object is the object destroyed.

The members of the object that the handle references are accessed the same way through the handle as if accessed directly through the object variable, i.e. with . operator.

See also

Object handles

Parenthesis

  a = c * (a + b);
  if( (a or b) and c )
  {
    // ... do something
  }

Parenthesis are used to group expressions when the operator precedence does not give the desired order of evaluation.

Scope resolution

  int value;
  void function()
  {
    int value;       // local variable overloads the global variable
    ::value = value; // use scope resolution operator to refer to the global variable
  }

The scope resolution operator :: can be used to access variables or functions from another scope when the name is overloaded by a local variable or function. Write the scope name on the left (or blank for the global scope) and the name of the variable/function on the right.

See also

Namespaces

Type conversions

  // implicitly convert the clss handle to a intf handle
  intf @a = @clss();

  // explicitly convert the intf handle to a clss handle
  clss @b = cast<clss>(a);

Object handles can be converted to other object handles with the cast operator. If the cast is valid, i.e. the true object implements the class or interface being requested, the operator returns a valid handle. If the cast is not valid, the cast returns a null handle.

The above is called a reference cast, and only works for types that support object handles. In this case the handle still refers to the same object, it is just exposed through a different interface.

Types that do not support object handles can be converted with a value cast instead. In this case a new value is constructed, or in case of objects a new instance of the object is created.

  // implicit value cast
  int a = 1.0f;

  // explicit value cast
  float b = float(a)/2;

In most cases an explicit cast is not necessary for primitive types, however, as the compiler is usually able to do an implicit cast to the correct type.

Anonymous objects

Anonymous objects, i.e. objects that are created without being declared as variables, can be instantiated in expressions by calling invoking the object's constructor as if it was a function. Both reference types and value types can be created like this.

  // Call the function with a new object of the type MyClass
  func(MyClass(1,2,3));

For types that support it, the anonymous objects can also be initialized with initialization lists.

  // Call the function with a dictionary, explicitly informing the type of the initialization list
  func(dictionary = {{'banana',1}, {'apple',2}, {'orange',3}});

  // When there is only one possible type that support initialization lists it is possible
  // to omit the type and let the compiler implicitly determine it based on the use
  funcExpectsAnArrayOfInts({1,2,3,4});

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Fine tuning</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Fine tuning

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

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 asIScriptFunction or 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 user data in the asITypeInfo interface. This way you will have quick access to the functions when they need to be called.

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.

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 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 RequestContext and ReturnContext methods instead of the CreateContext method.

Here's a simple implementation of a context pool.

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();

}

asIScriptContext

The interface to the virtual machine.

Definition: angelscript.h:2735

asIScriptContext::Unprepare

virtual int Unprepare()=0

Frees resources held by the context.

asIScriptEngine

The engine interface.

Definition: angelscript.h:1102

asIScriptEngine::CreateContext

virtual asIScriptContext * CreateContext()=0

Creates a new script context.

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.

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();

  }

}

asIScriptContext::PopState

virtual int PopState()=0

Restores the state to resume previous script execution.

asIScriptContext::PushState

virtual int PushState()=0

Backups the current state to prepare the context for a nested call.

asGetActiveContext

AS_API asIScriptContext * asGetActiveContext()

Returns the currently active context.

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.

engine->SetEngineProperty(asEP_BUILD_WITHOUT_LINE_CUES, true);

asEP_BUILD_WITHOUT_LINE_CUES

@ asEP_BUILD_WITHOUT_LINE_CUES

Remove SUSPEND instructions between each statement. Default: false.

Definition: angelscript.h:170

asIScriptEngine::SetEngineProperty

virtual int SetEngineProperty(asEEngineProp property, asPWORD value)=0

Dynamically change some engine properties.

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.

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 asEP_AUTO_GARBAGE_COLLECT to false.

engine->SetEngineProperty(asEP_AUTO_GARBAGE_COLLECT, false);

asEP_AUTO_GARBAGE_COLLECT

@ asEP_AUTO_GARBAGE_COLLECT

Enable or disable automatic garbage collection. Default: true.

Definition: angelscript.h:186

See also

Garbage collection

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 also

The generic calling convention, Calling convention

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Garbage collection</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

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 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 GarbageCollect(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 GarbageCollect(asGC_FULL_CYCLE | 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 GarbageCollect(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 SetEngineProperty(asEP_AUTO_GARBAGE_COLLECT, false).

See also

Memory management

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

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 the GC behaviours.

See also

Garbage collected objects and multi-threading

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Garbage collected objects</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

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.

// Registering the garbage collected reference type

r = engine->RegisterObjectType("ref_type", 0, asOBJ_REF | asOBJ_GC); assert( r >= 0 );

asOBJ_REF

@ asOBJ_REF

A reference type.

Definition: angelscript.h:254

asOBJ_GC

@ asOBJ_GC

A garbage collected type. Only valid for reference types.

Definition: angelscript.h:258

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 also

The dictionary add-on for an example of a garbage collected object

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.

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

asCALL_THISCALL

@ asCALL_THISCALL

A thiscall class method.

Definition: angelscript.h:236

asMETHOD

#define asMETHOD(c, m)

Returns an asSFuncPtr representing the class method specified by class and method name.

Definition: angelscript.h:750

asBEHAVE_ENUMREFS

@ asBEHAVE_ENUMREFS

(GC) Enumerate held references

Definition: angelscript.h:389

asBEHAVE_RELEASEREFS

@ asBEHAVE_RELEASEREFS

(GC) Release all references

Definition: angelscript.h:391

asBEHAVE_SETGCFLAG

@ asBEHAVE_SETGCFLAG

(GC) Set GC flag

Definition: angelscript.h:385

asBEHAVE_GETGCFLAG

@ asBEHAVE_GETGCFLAG

(GC) Get GC flag

Definition: angelscript.h:387

asBEHAVE_GETREFCOUNT

@ asBEHAVE_GETREFCOUNT

(GC) Get reference count

Definition: angelscript.h:383

asIScriptEngine

The engine interface.

Definition: angelscript.h:1102

asIScriptEngine::GCEnumCallback

virtual void GCEnumCallback(void *reference)=0

Used by the garbage collector to enumerate all references held by an object.

asIScriptEngine::RegisterObjectBehaviour

virtual int RegisterObjectBehaviour(const char *obj, asEBehaviours behaviour, const char *declaration, const asSFuncPtr &funcPointer, asDWORD callConv, void *auxiliary=0, int compositeOffset=0, bool isCompositeIndirect=false)=0

Registers a behaviour for the object type.

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.

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;

}

asIScriptEngine::NotifyGarbageCollectorOfNewObject

virtual int NotifyGarbageCollectorOfNewObject(void *obj, asITypeInfo *type)=0

Notify the garbage collector of a new object that needs to be managed.

asIScriptEngine::GetTypeInfoByName

virtual asITypeInfo * GetTypeInfoByName(const char *name) const =0

Returns the type interface by name.

asITypeInfo

The interface for describing types This interface is used to describe the types in the script engine.

Definition: angelscript.h:3704

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.

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.

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

asBEHAVE_ADDREF

@ asBEHAVE_ADDREF

AddRef.

Definition: angelscript.h:370

asBEHAVE_RELEASE

@ asBEHAVE_RELEASE

Release.

Definition: angelscript.h:372

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.

// 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);

asOBJ_VALUE

@ asOBJ_VALUE

A value type.

Definition: angelscript.h:256

asIScriptEngine::RegisterObjectType

virtual int RegisterObjectType(const char *obj, int byteSize, asDWORD flags)=0

Registers a new object type.

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 ForwardGCEnumReferences or ForwardGCReleaseReferences respectively.

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

}

asIScriptEngine::ForwardGCReleaseReferences

virtual void ForwardGCReleaseReferences(void *ref, asITypeInfo *type)=0

Used to forward GC callback to held value types that may contain references.

asIScriptEngine::ForwardGCEnumReferences

virtual void ForwardGCEnumReferences(void *ref, asITypeInfo *type)=0

Used to forward GC callback to held value types that may contain references.

See also

The ref object for a value type with GC behaviours, and the dictionary object for a ref type that can contain value types with GC behaviours.

Garbage collected objects and multi-threading

If you plan on executing scripts from multiple threads with 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 asAtomicInc and 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 also

Garbage collection and multi-threading

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: The generic calling convention</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

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

// 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);

}

asIScriptGeneric

The interface for the generic calling convention.

Definition: angelscript.h:3419

asIScriptGeneric::GetArgFloat

virtual float GetArgFloat(asUINT arg)=0

Returns the value of a float argument.

asIScriptGeneric::SetReturnObject

virtual int SetReturnObject(void *obj)=0

Sets the object return value.

asIScriptGeneric::GetArgDWord

virtual asDWORD GetArgDWord(asUINT arg)=0

Returns the value of a 32-bit integer argument.

asIScriptGeneric::GetArgObject

virtual void * GetArgObject(asUINT arg)=0

Returns a pointer to the object in a object argument.

asIScriptObject

The interface for an instance of a script object.

Definition: angelscript.h:3590

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 automatic wrapper functions rather than writing the functions yourself.

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

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 register the function with +).

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 SetReturnAddress and SetReturnObject to determine what needs to be done to get the expected result.

It is also possible to use the 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 automatic wrapper functions.

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

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Script classes</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Script classes

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

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Enums</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Enums

Enums are a convenient way of registering a family of integer constants that may be used throughout the script as named literals instead of numeric constants. Using enums often help improve the readability of the code, as the named literal normally explains what the intention is without the reader having to look up what a numeric value means in the manual.

Even though enums list the valid values, you cannot rely on a variable of the enum type to only contain values from the declared list. Always have a default action in case the variable holds an unexpected value.

The enum values are declared by listing them in an enum statement. Unless a specific value is given for an enum constant it will take the value of the previous constant + 1. The first constant will receive the value 0, unless otherwise specified.

  enum MyEnum
  {
    eValue0,
    eValue2 = 2,
    eValue3,
    eValue200 = eValue2 * 100
  }

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Functions</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Functions

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

  void foo()
  {
    // Do something
  }

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Funcdefs</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Funcdefs

Funcdefs are used to define a function signature that will be used to store pointers to functions with matching signatures. With this a function pointer can be created, which is able to store dynamic pointers that can be invoked at a later time as a normal function call.

  // Define a function signature for the function pointer
  funcdef bool CALLBACK(int, int);

See also

Function handles for more information on how to use this

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Imports</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Imports

Sometimes it may be useful to load script modules dynamically without having to recompile the main script, but still let the modules interact with each other. In that case the script may import functions from another module. This declaration is written using the import keyword, followed by the function signature, and then specifying which module to import from.

This allows the script to be compiled using these imported functions, without them actually being available at compile time. The application can then bind the functions at a later time, and even unbind them again.

If a script is calling an imported function that has not yet been bound the script will be aborted with a script exception.

  import void MyFunction(int a, int b) from "Another module";

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Interfaces</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Interfaces

An interface works like a contract, the classes that implements an interface are guaranteed to implement the methods declared in the interface. This allows for the use of polymorphism in that a function can specify that it wants an object handle to an object that implements a certain interface. The function can then call the methods on this interface without having to know the exact type of the object that it is working with.

  // The interface declaration
  interface MyInterface
  {
    void DoSomething();
  }

  // A class that implements the interface MyInterface
  class MyClass : MyInterface
  {
    void DoSomething()
    {
      // Do something
    }
  }

A class can implement multiple interfaces; Simply list all the interfaces separated by a comma.

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Namespaces</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Namespaces

Namespaces can be used to organize large projects in logical units that may be easier to remember. When using namespaces it is also not necessary to worry about using names for entities that may exist in a different part of the project under a different namespace.

  namespace A
  {
    // Entities in a namespace see each other normally.
    void function() { variable++; }
    int variable;
  }

  namespace B
  {
    // Entities in different namespaces don't immediately see each other and
    // can reuse the same name without causing name conflicts. By using the
    // scoping operator the entity from the desired namespace can be explicitly
    // informed.
    void function() { A::function(); }
  }

Observe that in order to refer to an entity from a different namespace the scoping operator must be used, unless it is a parent namespace in which case it is only necessary if the child namespace declare the same entity.

  int var;
  namespace Parent
  {
    int var;
    namespace Child
    {
      int var;
      void func()
      {
        // Accessing variable in parent namespace requires
        // specifying the scope if an entity in a child namespace
        // uses the same name
        var = Parent::var;

        // To access variables in global scope the scoping
        // operator without any name should be used
        Parent::var = ::var;
      }
    }
  }

  void func()
  {
    // Access variable in a nested namespace requires
    // fully qualified scope specifier
    int var = Parent::Child::var;
  }

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Typedefs</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Typedefs

Typedefs are used to define aliases for other types.

Currently a typedef can only be used to define an alias for primitive types, but a future version will have more complete support for all kinds of types.

  typedef float  real32;
  typedef double real64;

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Variables</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Variables

Global variables may be declared in the scripts, which will then be shared between all contexts accessing the script module.

Variables declared globally like this are accessible from all functions. The value of the variables are initialized at compile time and any changes are maintained between calls. If a global variable holds a memory resource, e.g. a string, its memory is released when the module is discarded or the script engine is reset.

  int MyValue = 0;
  const uint Flag1 = 0x01;

Variables of primitive types are initialized before variables of non-primitive types. This allows class constructors to access other global variables already with their correct initial value. The exception is if the other global variable also is of a non-primitive type, in which case there is no guarantee which variable is initialized first, which may lead to null-pointer exceptions being thrown during initialization.

Be careful with calling functions that may access global variables from within the initialization expression of global variables. While the compiler tries to initialize the global variables in the order they are needed, there is no guarantee that it will always succeed. Should a function access a global variable that has not yet been initialized you will get unpredictable behaviour or a null-pointer exception.

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Virtual properties</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

Virtual properties

Virtual properties is a property with special behaviour for reading and writing to it. These can be declared globally, but are most usually found as members of classes.

  int prop
  {
    get { return SomeValue(); }
    set { UpdateValue(value); }
  }

See also

Property accessors

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6


code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Good practices</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="navtree.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

AngelScript

          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Loading...

Searching...

No Matches

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.

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 Build method will always fail with a return code of 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.

// 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 );

asCALL_CDECL

@ asCALL_CDECL

A cdecl function.

Definition: angelscript.h:230

asFUNCTION

#define asFUNCTION(f)

Returns an asSFuncPtr representing the function specified by the name.

Definition: angelscript.h:685

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.

Use the message callback to receive detailed error messages

The return code from the register functions, Build, and 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 Message callback for more information on the message callback.

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 Exception handling

Generated on Sun May 21 2023 10:12:40 for AngelScript by  1.9.6