PageRenderTime 36ms CodeModel.GetById 16ms app.highlight 11ms RepoModel.GetById 2ms app.codeStats 1ms

/xbmc/visualizations/Vortex/angelscript/docs/manual/doc_gc_object.html

http://github.com/xbmc/xbmc
HTML | 100 lines | 92 code | 7 blank | 1 comment | 0 complexity | e42e3b26287bc2ec0ab8da54337a99d9 MD5 | raw file
  1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  2<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
  3<title>AngelScript: Garbage collected objects</title>
  4<link href="tabs.css" rel="stylesheet" type="text/css">
  5<link href="doxygen.css" rel="stylesheet" type="text/css">
  6</head><body>
  7<!-- Generated by Doxygen 1.5.9 -->
  8<div class="contents">
  9<h1><a class="anchor" name="doc_gc_object">Garbage collected objects </a></h1>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>
 10<div class="fragment"><pre class="fragment"><span class="comment">// Registering the garbage collected reference type</span>
 11r = engine-&gt;<a class="code" href="classas_i_script_engine.html#29c6c087c8c5b5cdb6271cfd161cc5a6" title="Registers a new object type.">RegisterObjectType</a>(<span class="stringliteral">"ref"</span>, 0, <a class="code" href="angelscript_8h.html#855d86fa9ee15b9f75e553ee376b5c7a9450e038342b36c745858d2e5ae4b861" title="A reference type.">asOBJ_REF</a> | <a class="code" href="angelscript_8h.html#855d86fa9ee15b9f75e553ee376b5c7acc1d835f9c25043cef86026a4aa6a470" title="A garbage collected type. Only valid for reference types.">asOBJ_GC</a>); assert( r &gt;= 0 );
 12</pre></div><p>
 13The 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>
 14<dl class="see" compact><dt><b>See also:</b></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>
 15<h2><a class="anchor" name="doc_reg_gcref_1">
 16GC support behaviours</a></h2>
 17The 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>
 18The process of determining the dead objects uses the first for of the behaviours below, while the destruction of the objects is done by forcing the release of the object's references.<p>
 19<div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> CGCRef::SetGCFlag()
 20{
 21    <span class="comment">// Set the gc flag as the high bit in the reference counter</span>
 22    refCount |= 0x80000000;
 23}
 24
 25<span class="keywordtype">bool</span> CGCRef::GetGCFlag()
 26{
 27    <span class="comment">// Return the gc flag</span>
 28    <span class="keywordflow">return</span> (refCount &amp; 0x80000000) ? <span class="keyword">true</span> : <span class="keyword">false</span>;
 29}
 30
 31<span class="keywordtype">int</span> CGCRef::GetRefCount()
 32{
 33    <span class="comment">// Return the reference count, without the gc flag</span>
 34    <span class="keywordflow">return</span> (refCount &amp; 0x7FFFFFFF);
 35}
 36
 37<span class="keywordtype">void</span> CGCRef::EnumReferences()
 38{
 39    <span class="comment">// Call the engine::GCEnumCallback for all references to other objects held</span>
 40    engine-&gt;<a class="code" href="classas_i_script_engine.html#58ceeafd780dea3543e0ede4106199fd" title="Used by the garbage collector to enumerate all references held by an object.">GCEnumCallback</a>(myref);
 41}
 42
 43<span class="keywordtype">void</span> CGCRef::ReleaseAllReferences()
 44{
 45    <span class="comment">// When we receive this call, we are as good as dead, but</span>
 46    <span class="comment">// the garbage collector will still hold a references to us, so we</span>
 47    <span class="comment">// cannot just delete ourself yet. Just free all references to other</span>
 48    <span class="comment">// objects that we hold</span>
 49    <span class="keywordflow">if</span>( myref )
 50    {
 51        myref-&gt;Release();
 52        myref = 0;
 53    }
 54}
 55
 56<span class="comment">// Register the GC support behaviours</span>
 57r = engine-&gt;<a class="code" href="classas_i_script_engine.html#7ea3c93dea338b0287027de0e4895dcb" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">"gc"</span>, <a class="code" href="angelscript_8h.html#7e38df5b10ec8cbf2a688f1d114097c5adbad474a338c3a0fe6e90df679bb2e6" title="(GC) Set GC flag">asBEHAVE_SETGCFLAG</a>, <span class="stringliteral">"void f()"</span>, <a class="code" href="angelscript_8h.html#7345e6b3afabec24efd0ff77886d49a6" title="Returns an asSFuncPtr representing the class method specified by class and method...">asMETHOD</a>(CGCRef,SetGCFlag), <a class="code" href="angelscript_8h.html#3ec92ea3c4762e44c2df788ceccdd1e4ea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );
 58r = engine-&gt;<a class="code" href="classas_i_script_engine.html#7ea3c93dea338b0287027de0e4895dcb" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">"gc"</span>, <a class="code" href="angelscript_8h.html#7e38df5b10ec8cbf2a688f1d114097c5bfce2539609e667f15b24bbc8551c7b7" title="(GC) Get GC flag">asBEHAVE_GETGCFLAG</a>, <span class="stringliteral">"bool f()"</span>, <a class="code" href="angelscript_8h.html#7345e6b3afabec24efd0ff77886d49a6" title="Returns an asSFuncPtr representing the class method specified by class and method...">asMETHOD</a>(CGCRef,GetGCFlag), <a class="code" href="angelscript_8h.html#3ec92ea3c4762e44c2df788ceccdd1e4ea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );
 59r = engine-&gt;<a class="code" href="classas_i_script_engine.html#7ea3c93dea338b0287027de0e4895dcb" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">"gc"</span>, <a class="code" href="angelscript_8h.html#7e38df5b10ec8cbf2a688f1d114097c5f998529f8ea1e54567997b8fb2867640" title="(GC) Get reference count">asBEHAVE_GETREFCOUNT</a>, <span class="stringliteral">"int f()"</span>, <a class="code" href="angelscript_8h.html#7345e6b3afabec24efd0ff77886d49a6" title="Returns an asSFuncPtr representing the class method specified by class and method...">asMETHOD</a>(CGCRef,GetRefCount), <a class="code" href="angelscript_8h.html#3ec92ea3c4762e44c2df788ceccdd1e4ea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );
 60r = engine-&gt;<a class="code" href="classas_i_script_engine.html#7ea3c93dea338b0287027de0e4895dcb" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">"gc"</span>, <a class="code" href="angelscript_8h.html#7e38df5b10ec8cbf2a688f1d114097c508ccf78a37567b5dd192ff5d95c6667b" title="(GC) Enumerate held references">asBEHAVE_ENUMREFS</a>, <span class="stringliteral">"void f(int&amp;in)"</span>, <a class="code" href="angelscript_8h.html#7345e6b3afabec24efd0ff77886d49a6" title="Returns an asSFuncPtr representing the class method specified by class and method...">asMETHOD</a>(CGCRef,EnumReferences), <a class="code" href="angelscript_8h.html#3ec92ea3c4762e44c2df788ceccdd1e4ea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );
 61r = engine-&gt;<a class="code" href="classas_i_script_engine.html#7ea3c93dea338b0287027de0e4895dcb" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">"gc"</span>, <a class="code" href="angelscript_8h.html#7e38df5b10ec8cbf2a688f1d114097c54275ebe0b4852f2d4a10d4d9db333fe9" title="(GC) Release all references">asBEHAVE_RELEASEREFS</a>, <span class="stringliteral">"void f(int&amp;in)"</span>, <a class="code" href="angelscript_8h.html#7345e6b3afabec24efd0ff77886d49a6" title="Returns an asSFuncPtr representing the class method specified by class and method...">asMETHOD</a>(CGCRef,ReleaseAllReferences), <a class="code" href="angelscript_8h.html#3ec92ea3c4762e44c2df788ceccdd1e4ea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );
 62</pre></div><h2><a class="anchor" name="doc_reg_gcref_2">
 63Factory for garbage collection</a></h2>
 64Whenever 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>
 65<div class="fragment"><pre class="fragment">CGCRef *GCRef_Factory()
 66{
 67    <span class="comment">// Create the object and then notify the GC of its existence</span>
 68    CGCRef *obj = <span class="keyword">new</span> CGCRef();
 69    <span class="keywordtype">int</span> typeId = engine-&gt;<a class="code" href="classas_i_script_engine.html#1e8dde38773b0e0d96811f1316964cb0" title="Returns a type id by declaration.">GetTypeIdByDecl</a>(<span class="stringliteral">"gc"</span>);
 70    engine-&gt;<a class="code" href="classas_i_script_engine.html#8ea9a6f3ed9f69a5c4e07c87281117c0" title="Notify the garbage collector of a new object that needs to be managed.">NotifyGarbageCollectorOfNewObject</a>(obj, typeId);
 71    <span class="keywordflow">return</span> obj;
 72}
 73</pre></div><p>
 74You 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>
 75Note, 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.<h2><a class="anchor" name="doc_reg_gcref_3">
 76Addref and release for garbage collection</a></h2>
 77For 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>
 78<div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> CGCRef::AddRef()
 79{
 80    <span class="comment">// Clear the gc flag and increase the reference counter</span>
 81    refCount = (refCount&amp;0x7FFFFFFF) + 1;
 82}
 83
 84<span class="keywordtype">void</span> CGCRef::Release()
 85{
 86    <span class="comment">// Clear the gc flag, decrease ref count and delete if it reaches 0</span>
 87    refCount &amp;= 0x7FFFFFFF;
 88    <span class="keywordflow">if</span>( --refCount == 0 )
 89        <span class="keyword">delete</span> <span class="keyword">this</span>;
 90}
 91
 92<span class="comment">// Registering the addref/release behaviours</span>
 93r = engine-&gt;<a class="code" href="classas_i_script_engine.html#7ea3c93dea338b0287027de0e4895dcb" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">"gc"</span>, <a class="code" href="angelscript_8h.html#7e38df5b10ec8cbf2a688f1d114097c51dfa5b72ad69a7bf70636d4fcb1b1d84" title="AddRef.">asBEHAVE_ADDREF</a>, <span class="stringliteral">"void f()"</span>, <a class="code" href="angelscript_8h.html#7345e6b3afabec24efd0ff77886d49a6" title="Returns an asSFuncPtr representing the class method specified by class and method...">asMETHOD</a>(CGCRef,AddRef), <a class="code" href="angelscript_8h.html#3ec92ea3c4762e44c2df788ceccdd1e4ea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );
 94r = engine-&gt;<a class="code" href="classas_i_script_engine.html#7ea3c93dea338b0287027de0e4895dcb" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">"gc"</span>, <a class="code" href="angelscript_8h.html#7e38df5b10ec8cbf2a688f1d114097c57134ce13c81967191af401a1e5170a0c" title="Release.">asBEHAVE_RELEASE</a>, <span class="stringliteral">"void f()"</span>, <a class="code" href="angelscript_8h.html#7345e6b3afabec24efd0ff77886d49a6" title="Returns an asSFuncPtr representing the class method specified by class and method...">asMETHOD</a>(CGCRef,Release), <a class="code" href="angelscript_8h.html#3ec92ea3c4762e44c2df788ceccdd1e4ea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );
 95</pre></div> </div>
 96<hr size="1"><address style="text-align: right;"><small>Generated on Wed Dec 16 19:34:50 2009 for AngelScript by&nbsp;
 97<a href="http://www.doxygen.org/index.html">
 98<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.9 </small></address>
 99</body>
100</html>