Angelscript/docs/manual/doc_gc_object.html

252 lines
32 KiB
HTML
Raw Permalink Normal View History

2021-04-12 18:25:02 +00:00
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.18"/>
<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"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="aslogo_small.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">AngelScript
</div>
</td>
<td> <div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.18 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('doc_gc_object.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="PageDoc"><div class="header">
<div class="headertitle">
<div class="title">Garbage collected objects </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>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.</p>
<div class="fragment"><div class="line"><span class="comment">// Registering the garbage collected reference type</span></div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a29c6c087c8c5b5cdb6271cfd161cc5a6">RegisterObjectType</a>(<span class="stringliteral">&quot;ref_type&quot;</span>, 0, <a class="code" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861">asOBJ_REF</a> | <a class="code" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aacc1d835f9c25043cef86026a4aa6a470">asOBJ_GC</a>); assert( r &gt;= 0 );</div>
</div><!-- fragment --><p>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.</p>
<dl class="section see"><dt>See also</dt><dd>The <a class="el" href="doc_addon_dict.html">dictionary</a> add-on for an example of a garbage collected object</dd></dl>
<h1><a class="anchor" id="doc_reg_gcref_1"></a>
GC support behaviours</h1>
<p>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.</p>
<p>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.</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> CGCRef::SetGCFlag()</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// Set the gc flag as the high bit in the reference counter</span></div>
<div class="line"> refCount |= 0x80000000;</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">bool</span> CGCRef::GetGCFlag()</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// Return the gc flag</span></div>
<div class="line"> <span class="keywordflow">return</span> (refCount &amp; 0x80000000) ? true : <span class="keyword">false</span>;</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> CGCRef::GetRefCount()</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// Return the reference count, without the gc flag</span></div>
<div class="line"> <span class="keywordflow">return</span> (refCount &amp; 0x7FFFFFFF);</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> CGCRef::EnumReferences(<a class="code" href="classas_i_script_engine.html">asIScriptEngine</a> *engine)</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// Call the engine::GCEnumCallback for all references to other objects held</span></div>
<div class="line"> engine-&gt;<a class="code" href="classas_i_script_engine.html#a58ceeafd780dea3543e0ede4106199fd">GCEnumCallback</a>(myref);</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> CGCRef::ReleaseAllReferences(<a class="code" href="classas_i_script_engine.html">asIScriptEngine</a> *engine)</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// When we receive this call, we are as good as dead, but</span></div>
<div class="line"> <span class="comment">// the garbage collector will still hold a references to us, so we</span></div>
<div class="line"> <span class="comment">// cannot just delete ourself yet. Just free all references to other</span></div>
<div class="line"> <span class="comment">// objects that we hold</span></div>
<div class="line"> <span class="keywordflow">if</span>( myref )</div>
<div class="line"> {</div>
<div class="line"> myref-&gt;Release();</div>
<div class="line"> myref = 0;</div>
<div class="line"> }</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Register the GC support behaviours</span></div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;ref_type&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5aadbad474a338c3a0fe6e90df679bb2e6">asBEHAVE_SETGCFLAG</a>, <span class="stringliteral">&quot;void f()&quot;</span>, <a class="code" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>(CGCRef,SetGCFlag), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>); assert( r &gt;= 0 );</div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;ref_type&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5abfce2539609e667f15b24bbc8551c7b7">asBEHAVE_GETGCFLAG</a>, <span class="stringliteral">&quot;bool f()&quot;</span>, <a class="code" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>(CGCRef,GetGCFlag), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>); assert( r &gt;= 0 );</div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;ref_type&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5af998529f8ea1e54567997b8fb2867640">asBEHAVE_GETREFCOUNT</a>, <span class="stringliteral">&quot;int f()&quot;</span>, <a class="code" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>(CGCRef,GetRefCount), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>); assert( r &gt;= 0 );</div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;ref_type&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a08ccf78a37567b5dd192ff5d95c6667b">asBEHAVE_ENUMREFS</a>, <span class="stringliteral">&quot;void f(int&amp;in)&quot;</span>, <a class="code" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>(CGCRef,EnumReferences), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>); assert( r &gt;= 0 );</div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;ref_type&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a4275ebe0b4852f2d4a10d4d9db333fe9">asBEHAVE_RELEASEREFS</a>, <span class="stringliteral">&quot;void f(int&amp;in)&quot;</span>, <a class="code" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>(CGCRef,ReleaseAllReferences), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>); assert( r &gt;= 0 );</div>
</div><!-- fragment --><h1><a class="anchor" id="doc_reg_gcref_2"></a>
Factory for garbage collection</h1>
<p>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 <code>NotifyGarbageCollectorOfNewObject()</code> method on the engine when initializing the class.</p>
<div class="fragment"><div class="line">CGCRef *GCRef_Factory()</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// Create the object and then notify the GC of its existence</span></div>
<div class="line"> CGCRef *obj = <span class="keyword">new</span> CGCRef();</div>
<div class="line"> <a class="code" href="classas_i_type_info.html">asITypeInfo</a> *type = engine-&gt;<a class="code" href="classas_i_script_engine.html#aea2583b8aa724779b7c37df8b7fa437b">GetTypeInfoByName</a>(<span class="stringliteral">&quot;gc&quot;</span>);</div>
<div class="line"> engine-&gt;<a class="code" href="classas_i_script_engine.html#a52a7644b48cbc771e33db5070814f6df">NotifyGarbageCollectorOfNewObject</a>(obj, type);</div>
<div class="line"> <span class="keywordflow">return</span> obj;</div>
<div class="line">}</div>
</div><!-- fragment --><p>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.</p>
<p>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.</p>
<h1><a class="anchor" id="doc_reg_gcref_3"></a>
Addref and release for garbage collection</h1>
<p>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.</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> CGCRef::AddRef()</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// Clear the gc flag and increase the reference counter</span></div>
<div class="line"> refCount = (refCount&amp;0x7FFFFFFF) + 1;</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> CGCRef::Release()</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// Clear the gc flag, decrease ref count and delete if it reaches 0</span></div>
<div class="line"> refCount &amp;= 0x7FFFFFFF;</div>
<div class="line"> <span class="keywordflow">if</span>( --refCount == 0 )</div>
<div class="line"> <span class="keyword">delete</span> <span class="keyword">this</span>;</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Registering the addref/release behaviours</span></div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;ref_type&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a1dfa5b72ad69a7bf70636d4fcb1b1d84">asBEHAVE_ADDREF</a>, <span class="stringliteral">&quot;void f()&quot;</span>, <a class="code" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>(CGCRef,AddRef), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>); assert( r &gt;= 0 );</div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;ref_type&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a7134ce13c81967191af401a1e5170a0c">asBEHAVE_RELEASE</a>, <span class="stringliteral">&quot;void f()&quot;</span>, <a class="code" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>(CGCRef,Release), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>); assert( r &gt;= 0 );</div>
</div><!-- fragment --><h1><a class="anchor" id="doc_reg_gcref_value"></a>
GC behaviours for value types</h1>
<p>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.</p>
<p>To solve these situations the value types can also be registered with some of the garbage collector behaviours.</p>
<div class="fragment"><div class="line"><span class="comment">// Registering the value type with garbage collected behaviour</span></div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a29c6c087c8c5b5cdb6271cfd161cc5a6">RegisterObjectType</a>(<span class="stringliteral">&quot;value_type&quot;</span>, <span class="keyword">sizeof</span>(value_type), <a class="code" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9fc16a8ac0f30f9ff9c6568e0b7be91d">asOBJ_VALUE</a> | <a class="code" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aacc1d835f9c25043cef86026a4aa6a470">asOBJ_GC</a> | ...); assert( r &gt;= 0 );</div>
<div class="line"> </div>
<div class="line"><span class="comment">// Register the garbage collector behaviours</span></div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;ref&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a08ccf78a37567b5dd192ff5d95c6667b">asBEHAVE_ENUMREFS</a>, <span class="stringliteral">&quot;void f(int&amp;in)&quot;</span>, <a class="code" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>(value_type,EnumReferences), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>); assert(r &gt;= 0);</div>
<div class="line">r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;ref&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a4275ebe0b4852f2d4a10d4d9db333fe9">asBEHAVE_RELEASEREFS</a>, <span class="stringliteral">&quot;void f(int&amp;in)&quot;</span>, <a class="code" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>(value_type, ReleaseReferences), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>); assert(r &gt;= 0);</div>
</div><!-- fragment --><p>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.</p>
<p>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 <a class="el" href="classas_i_script_engine.html#abe95ce0e45d914fec478fa112a7bb8dd">ForwardGCEnumReferences</a> or <a class="el" href="classas_i_script_engine.html#a60cdec608a18f6ebc0aebe29a143183f">ForwardGCReleaseReferences</a> respectively.</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> CGCRef2::EnumReferences(<a class="code" href="classas_i_script_engine.html">asIScriptEngine</a> *engine)</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// Forward the enum call to the member value type</span></div>
<div class="line"> engine-&gt;<a class="code" href="classas_i_script_engine.html#abe95ce0e45d914fec478fa112a7bb8dd">ForwardGCEnumReferences</a>(valueObj, valueType);</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> CGCRef2::ReleaseAllReferences(<a class="code" href="classas_i_script_engine.html">asIScriptEngine</a> *engine)</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// When we receive this call, we are as good as dead, but</span></div>
<div class="line"> <span class="comment">// the garbage collector will still hold a references to us, so we</span></div>
<div class="line"> <span class="comment">// cannot just delete ourself yet. Just free all references to other</span></div>
<div class="line"> <span class="comment">// objects that we hold</span></div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Forward the release call to the member value type</span></div>
<div class="line"> engine-&gt;<a class="code" href="classas_i_script_engine.html#a60cdec608a18f6ebc0aebe29a143183f">ForwardGCReleaseReferences</a>(valueObj, valueType);</div>
<div class="line">}</div>
</div><!-- fragment --><dl class="section see"><dt>See also</dt><dd>The <a class="el" href="doc_addon_handle.html">ref object</a> for a value type with GC behaviours, and the <a class="el" href="doc_addon_dict.html">dictionary object</a> for a ref type that can contain value types with GC behaviours.</dd></dl>
<h1><a class="anchor" id="doc_reg_gcref_4"></a>
Garbage collected objects and multi-threading</h1>
<p>If you plan on executing scripts from multiple threads with <a class="el" href="doc_adv_custom_options.html#doc_adv_custom_options_engine">automatic garbage collection</a> 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.</p>
<p>Making the ADDREF and RELEASE behaviours thread-safe is easy with the use of <a class="el" href="group__api__multithread__functions.html#gaf0074d581ac2edd06e63e56e4be52c8e">asAtomicInc</a> and <a class="el" href="group__api__multithread__functions.html#ga0565bcb53be170dd85ae27a5b6f2b828">asAtomicDec</a>. 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.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="doc_gc.html#doc_gc_threads">Garbage collection and multi-threading</a> </dd></dl>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5a7134ce13c81967191af401a1e5170a0c"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a7134ce13c81967191af401a1e5170a0c">asBEHAVE_RELEASE</a></div><div class="ttdeci">@ asBEHAVE_RELEASE</div><div class="ttdoc">Release.</div><div class="ttdef"><b>Definition:</b> angelscript.h:368</div></div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5aadbad474a338c3a0fe6e90df679bb2e6"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5aadbad474a338c3a0fe6e90df679bb2e6">asBEHAVE_SETGCFLAG</a></div><div class="ttdeci">@ asBEHAVE_SETGCFLAG</div><div class="ttdoc">(GC) Set GC flag</div><div class="ttdef"><b>Definition:</b> angelscript.h:381</div></div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5a4275ebe0b4852f2d4a10d4d9db333fe9"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a4275ebe0b4852f2d4a10d4d9db333fe9">asBEHAVE_RELEASEREFS</a></div><div class="ttdeci">@ asBEHAVE_RELEASEREFS</div><div class="ttdoc">(GC) Release all references</div><div class="ttdef"><b>Definition:</b> angelscript.h:387</div></div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5a08ccf78a37567b5dd192ff5d95c6667b"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a08ccf78a37567b5dd192ff5d95c6667b">asBEHAVE_ENUMREFS</a></div><div class="ttdeci">@ asBEHAVE_ENUMREFS</div><div class="ttdoc">(GC) Enumerate held references</div><div class="ttdef"><b>Definition:</b> angelscript.h:385</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_aea2583b8aa724779b7c37df8b7fa437b"><div class="ttname"><a href="classas_i_script_engine.html#aea2583b8aa724779b7c37df8b7fa437b">asIScriptEngine::GetTypeInfoByName</a></div><div class="ttdeci">virtual asITypeInfo * GetTypeInfoByName(const char *name) const =0</div><div class="ttdoc">Returns the type interface by name.</div></div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5af998529f8ea1e54567997b8fb2867640"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5af998529f8ea1e54567997b8fb2867640">asBEHAVE_GETREFCOUNT</a></div><div class="ttdeci">@ asBEHAVE_GETREFCOUNT</div><div class="ttdoc">(GC) Get reference count</div><div class="ttdef"><b>Definition:</b> angelscript.h:379</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_a60cdec608a18f6ebc0aebe29a143183f"><div class="ttname"><a href="classas_i_script_engine.html#a60cdec608a18f6ebc0aebe29a143183f">asIScriptEngine::ForwardGCReleaseReferences</a></div><div class="ttdeci">virtual void ForwardGCReleaseReferences(void *ref, asITypeInfo *type)=0</div><div class="ttdoc">Used to forward GC callback to held value types that may contain references.</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_a29c6c087c8c5b5cdb6271cfd161cc5a6"><div class="ttname"><a href="classas_i_script_engine.html#a29c6c087c8c5b5cdb6271cfd161cc5a6">asIScriptEngine::RegisterObjectType</a></div><div class="ttdeci">virtual int RegisterObjectType(const char *obj, int byteSize, asDWORD flags)=0</div><div class="ttdoc">Registers a new object type.</div></div>
<div class="ttc" id="aangelscript_8h_html_a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861"><div class="ttname"><a href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861">asOBJ_REF</a></div><div class="ttdeci">@ asOBJ_REF</div><div class="ttdoc">A reference type.</div><div class="ttdef"><b>Definition:</b> angelscript.h:250</div></div>
<div class="ttc" id="aclassas_i_script_engine_html"><div class="ttname"><a href="classas_i_script_engine.html">asIScriptEngine</a></div><div class="ttdoc">The engine interface.</div><div class="ttdef"><b>Definition:</b> angelscript.h:1092</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_a9f122dd87394f3a83ac766ea19f37317"><div class="ttname"><a href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">asIScriptEngine::RegisterObjectBehaviour</a></div><div class="ttdeci">virtual int RegisterObjectBehaviour(const char *obj, asEBehaviours behaviour, const char *declaration, const asSFuncPtr &amp;funcPointer, asDWORD callConv, void *auxiliary=0, int compositeOffset=0, bool isCompositeIndirect=false)=0</div><div class="ttdoc">Registers a behaviour for the object type.</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_a58ceeafd780dea3543e0ede4106199fd"><div class="ttname"><a href="classas_i_script_engine.html#a58ceeafd780dea3543e0ede4106199fd">asIScriptEngine::GCEnumCallback</a></div><div class="ttdeci">virtual void GCEnumCallback(void *reference)=0</div><div class="ttdoc">Used by the garbage collector to enumerate all references held by an object.</div></div>
<div class="ttc" id="aclassas_i_type_info_html"><div class="ttname"><a href="classas_i_type_info.html">asITypeInfo</a></div><div class="ttdoc">The interface for describing types This interface is used to describe the types in the script engine.</div><div class="ttdef"><b>Definition:</b> angelscript.h:3527</div></div>
<div class="ttc" id="aangelscript_8h_html_a7345e6b3afabec24efd0ff77886d49a6"><div class="ttname"><a href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a></div><div class="ttdeci">#define asMETHOD(c, m)</div><div class="ttdoc">Returns an asSFuncPtr representing the class method specified by class and method name.</div><div class="ttdef"><b>Definition:</b> angelscript.h:740</div></div>
<div class="ttc" id="aangelscript_8h_html_a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96"><div class="ttname"><a href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a></div><div class="ttdeci">@ asCALL_THISCALL</div><div class="ttdoc">A thiscall class method.</div><div class="ttdef"><b>Definition:</b> angelscript.h:232</div></div>
<div class="ttc" id="aangelscript_8h_html_a855d86fa9ee15b9f75e553ee376b5c7aacc1d835f9c25043cef86026a4aa6a470"><div class="ttname"><a href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aacc1d835f9c25043cef86026a4aa6a470">asOBJ_GC</a></div><div class="ttdeci">@ asOBJ_GC</div><div class="ttdoc">A garbage collected type. Only valid for reference types.</div><div class="ttdef"><b>Definition:</b> angelscript.h:254</div></div>
<div class="ttc" id="aangelscript_8h_html_a855d86fa9ee15b9f75e553ee376b5c7aa9fc16a8ac0f30f9ff9c6568e0b7be91d"><div class="ttname"><a href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9fc16a8ac0f30f9ff9c6568e0b7be91d">asOBJ_VALUE</a></div><div class="ttdeci">@ asOBJ_VALUE</div><div class="ttdoc">A value type.</div><div class="ttdef"><b>Definition:</b> angelscript.h:252</div></div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5a1dfa5b72ad69a7bf70636d4fcb1b1d84"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a1dfa5b72ad69a7bf70636d4fcb1b1d84">asBEHAVE_ADDREF</a></div><div class="ttdeci">@ asBEHAVE_ADDREF</div><div class="ttdoc">AddRef.</div><div class="ttdef"><b>Definition:</b> angelscript.h:366</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_a52a7644b48cbc771e33db5070814f6df"><div class="ttname"><a href="classas_i_script_engine.html#a52a7644b48cbc771e33db5070814f6df">asIScriptEngine::NotifyGarbageCollectorOfNewObject</a></div><div class="ttdeci">virtual int NotifyGarbageCollectorOfNewObject(void *obj, asITypeInfo *type)=0</div><div class="ttdoc">Notify the garbage collector of a new object that needs to be managed.</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_abe95ce0e45d914fec478fa112a7bb8dd"><div class="ttname"><a href="classas_i_script_engine.html#abe95ce0e45d914fec478fa112a7bb8dd">asIScriptEngine::ForwardGCEnumReferences</a></div><div class="ttdeci">virtual void ForwardGCEnumReferences(void *ref, asITypeInfo *type)=0</div><div class="ttdoc">Used to forward GC callback to held value types that may contain references.</div></div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5abfce2539609e667f15b24bbc8551c7b7"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5abfce2539609e667f15b24bbc8551c7b7">asBEHAVE_GETGCFLAG</a></div><div class="ttdeci">@ asBEHAVE_GETGCFLAG</div><div class="ttdoc">(GC) Get GC flag</div><div class="ttdef"><b>Definition:</b> angelscript.h:383</div></div>
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="footer">Generated on Sat Dec 5 2020 23:20:24 for AngelScript by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.18 </li>
</ul>
</div>
</body>
</html>