Angelscript/docs/manual/doc_adv_weakref.html

194 lines
18 KiB
HTML

<!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: Weak references</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_adv_weakref.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">Weak references </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>Even though AngelScript uses a <a class="el" href="doc_gc.html">garbage collector</a> to resolve cyclic references weak references may still come in handy. Weak references are especifically useful in scenarios were an object wants to be able to access other objects, but do not want to kept them alive longer than necessary.</p>
<p>AngelScript supports weak references with the use of shared booleans. The code that wants to keep a weak reference to an object should obtain the weakref flag from that object, which is a shared boolean, and before using the pointer to the object it should check if this flag has been set to indicate that the object is no longer alive.</p>
<p>Script classes automatically supports weak references without the script writing having to do anything. Application registered types on the other hand must register the behaviour <a class="el" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a7a5e435e88a5fc1dcdee13fce091b081">asBEHAVE_GET_WEAKREF_FLAG</a> and implement the logic to set the flag upon destroying the object.</p>
<p>The following code shows how to do a thread safe implementation:</p>
<div class="fragment"><div class="line"><span class="keyword">class </span>MyClass</div>
<div class="line">{</div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line"> MyClass() { refCount = 1; weakRefFlag = 0; }</div>
<div class="line"> <span class="keywordtype">void</span> AddRef() { <a class="code" href="group__api__multithread__functions.html#gaf0074d581ac2edd06e63e56e4be52c8e">asAtomicInc</a>(refCount); }</div>
<div class="line"> <span class="keywordtype">void</span> Release() </div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// If the weak ref flag exists it is because someone held a weak ref</span></div>
<div class="line"> <span class="comment">// and that someone may add a reference to the object at any time. It</span></div>
<div class="line"> <span class="comment">// is ok to check the existance of the weakRefFlag without locking here</span></div>
<div class="line"> <span class="comment">// because if the refCount is 1 then no other thread is currently </span></div>
<div class="line"> <span class="comment">// creating the weakRefFlag.</span></div>
<div class="line"> <span class="keywordflow">if</span>( refCount == 1 &amp;&amp; weakRefFlag )</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// Set the flag to tell others that the object is no longer alive</span></div>
<div class="line"> <span class="comment">// We must do this before decreasing the refCount to 0 so we don&#39;t</span></div>
<div class="line"> <span class="comment">// end up with a race condition between this thread attempting to </span></div>
<div class="line"> <span class="comment">// destroy the object and the other that temporary added a strong</span></div>
<div class="line"> <span class="comment">// ref from the weak ref.</span></div>
<div class="line"> weakRefFlag-&gt;Set(<span class="keyword">true</span>);</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">if</span>( <a class="code" href="group__api__multithread__functions.html#ga0565bcb53be170dd85ae27a5b6f2b828">asAtomicDec</a>(refCount) == 0 ) </div>
<div class="line"> <span class="keyword">delete</span> <span class="keyword">this</span>; </div>
<div class="line"> }</div>
<div class="line"> <a class="code" href="classas_i_lockable_shared_bool.html">asILockableSharedBool</a> *GetWeakRefFlag()</div>
<div class="line"> {</div>
<div class="line"> <span class="keywordflow">if</span>( !weakRefFlag )</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// Lock globally so no other thread can attempt</span></div>
<div class="line"> <span class="comment">// to create a shared bool at the same time</span></div>
<div class="line"> <a class="code" href="group__api__multithread__functions.html#ga016dbf716a1c761b3f903b92eb8bb580">asAcquireExclusiveLock</a>();</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Make sure another thread didn&#39;t create the </span></div>
<div class="line"> <span class="comment">// flag while we waited for the lock</span></div>
<div class="line"> <span class="keywordflow">if</span>( !weakRefFlag )</div>
<div class="line"> weakRefFlag = <a class="code" href="group__api__multithread__functions.html#gaa0ffb789dab56b5617e2f961f9c79fdb">asCreateLockableSharedBool</a>();</div>
<div class="line"> </div>
<div class="line"> <a class="code" href="group__api__multithread__functions.html#ga8a0617637eea3d76e33a52758b2cd49f">asReleaseExclusiveLock</a>();</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">return</span> weakRefFlag;</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keyword">static</span> MyClass *Factory() { <span class="keywordflow">return</span> <span class="keyword">new</span> MyClass(); }</div>
<div class="line"> </div>
<div class="line"><span class="keyword">protected</span>:</div>
<div class="line"> ~MyClass()</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// Release the weak reference flag that may still</span></div>
<div class="line"> <span class="comment">// be accessed by the code that holds a weak reference</span></div>
<div class="line"> <span class="keywordflow">if</span>( weakRefFlag )</div>
<div class="line"> weakRefFlag-&gt;Release();</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="keywordtype">int</span> refCount;</div>
<div class="line"> <a class="code" href="classas_i_lockable_shared_bool.html">asILockableSharedBool</a> *weakRefFlag;</div>
<div class="line">};</div>
</div><!-- fragment --><p>The <a class="el" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a7a5e435e88a5fc1dcdee13fce091b081">asBEHAVE_GET_WEAKREF_FLAG</a> behaviour for this class is registered like this:</p>
<div class="fragment"><div class="line">engine-&gt;<a class="code" href="classas_i_script_engine.html#a29c6c087c8c5b5cdb6271cfd161cc5a6">RegisterObjectType</a>(<span class="stringliteral">&quot;MyClass&quot;</span>, 0, <a class="code" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861">asOBJ_REF</a>);</div>
<div class="line">engine-&gt;<a class="code" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;MyClass&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>(MyClass, AddRef), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>);</div>
<div class="line">engine-&gt;<a class="code" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;MyClass&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>(MyClass, Release), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>);</div>
<div class="line">engine-&gt;<a class="code" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;MyClass&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a7a5e435e88a5fc1dcdee13fce091b081">asBEHAVE_GET_WEAKREF_FLAG</a>, <span class="stringliteral">&quot;int &amp;f()&quot;</span>, <a class="code" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>(MyClass, GetWeakRefFlag), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>);</div>
</div><!-- fragment --><p>The script language doesn't have a built-in syntax for weak references. Instead a standard <a class="el" href="doc_addon_weakref.html">weakref add-on</a> has been implemented to provide this for the applications that wants to provide this support in the scripts. </p>
</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="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_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="agroup__api__multithread__functions_html_gaf0074d581ac2edd06e63e56e4be52c8e"><div class="ttname"><a href="group__api__multithread__functions.html#gaf0074d581ac2edd06e63e56e4be52c8e">asAtomicInc</a></div><div class="ttdeci">AS_API int asAtomicInc(int &amp;value)</div><div class="ttdoc">Increments the value by one and returns the result as a single atomic instruction.</div></div>
<div class="ttc" id="agroup__api__multithread__functions_html_ga016dbf716a1c761b3f903b92eb8bb580"><div class="ttname"><a href="group__api__multithread__functions.html#ga016dbf716a1c761b3f903b92eb8bb580">asAcquireExclusiveLock</a></div><div class="ttdeci">AS_API void asAcquireExclusiveLock()</div><div class="ttdoc">Acquire an exclusive lock.</div></div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5a7a5e435e88a5fc1dcdee13fce091b081"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a7a5e435e88a5fc1dcdee13fce091b081">asBEHAVE_GET_WEAKREF_FLAG</a></div><div class="ttdeci">@ asBEHAVE_GET_WEAKREF_FLAG</div><div class="ttdoc">Obtain weak ref flag.</div><div class="ttdef"><b>Definition:</b> angelscript.h:370</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="agroup__api__multithread__functions_html_ga8a0617637eea3d76e33a52758b2cd49f"><div class="ttname"><a href="group__api__multithread__functions.html#ga8a0617637eea3d76e33a52758b2cd49f">asReleaseExclusiveLock</a></div><div class="ttdeci">AS_API void asReleaseExclusiveLock()</div><div class="ttdoc">Release an exclusive lock.</div></div>
<div class="ttc" id="agroup__api__multithread__functions_html_ga0565bcb53be170dd85ae27a5b6f2b828"><div class="ttname"><a href="group__api__multithread__functions.html#ga0565bcb53be170dd85ae27a5b6f2b828">asAtomicDec</a></div><div class="ttdeci">AS_API int asAtomicDec(int &amp;value)</div><div class="ttdoc">Decrements the value by one and returns the result as a single atomic instruction.</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="aclassas_i_lockable_shared_bool_html"><div class="ttname"><a href="classas_i_lockable_shared_bool.html">asILockableSharedBool</a></div><div class="ttdoc">A lockable shared boolean.</div><div class="ttdef"><b>Definition:</b> angelscript.h:4077</div></div>
<div class="ttc" id="agroup__api__multithread__functions_html_gaa0ffb789dab56b5617e2f961f9c79fdb"><div class="ttname"><a href="group__api__multithread__functions.html#gaa0ffb789dab56b5617e2f961f9c79fdb">asCreateLockableSharedBool</a></div><div class="ttdeci">AS_API asILockableSharedBool * asCreateLockableSharedBool()</div><div class="ttdoc">Create a lockable shared boolean.</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>
<!-- 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>