PageRenderTime 21ms CodeModel.GetById 13ms app.highlight 4ms RepoModel.GetById 2ms app.codeStats 0ms

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

http://github.com/xbmc/xbmc
HTML | 102 lines | 86 code | 15 blank | 1 comment | 0 complexity | bb428231106db82cc50076621a59d08f 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: Class hierarchies</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_adv_class_hierarchy">Class hierarchies </a></h1>AngelScript cannot automatically determine relationships between registered classes, so in order to establish the hierarchies for use within the script language it is necessary to do a bit more registration beyond the normal <a class="el" href="doc_register_type.html">object registration</a>.<p>
 10Hierarchies can currently only be registered for <a class="el" href="doc_reg_basicref.html">reference types</a>, not for <a class="el" href="doc_register_val_type.html">value types</a>.<h2><a class="anchor" name="doc_adv_class_hierarchy_1">
 11Establishing the relationship</a></h2>
 12In order to let AngelScript know that two types are related you need to register the reference cast behaviours <a class="el" href="angelscript_8h.html#7e38df5b10ec8cbf2a688f1d114097c520746394824509f369f860ea1e96d1f6">asBEHAVE_REF_CAST</a> and <a class="el" href="angelscript_8h.html#7e38df5b10ec8cbf2a688f1d114097c59b23cc523e8aa4984e5e56e54b95dee4">asBEHAVE_IMPLICIT_REF_CAST</a>. The asBEHAVE_REF_CAST should be used if you only want to allow the cast through an explicit call with the <code><a class="el" href="doc_expressions.html#conversion">cast&lt;class&gt;</a></code> operator. asBEHAVE_IMPLICIT_REF_CAST should be used when you want to allow the compiler to implicitly perform the cast as necessary.<p>
 13Usually you'll want to use asBEHAVE_IMPLICIT_REF_CAST for casts from a derived type to the base type, and asBEHAVE_REF_CAST for casts from a base type to a derived type.<p>
 14<div class="fragment"><pre class="fragment"><span class="comment">// Example REF_CAST behaviour</span>
 15<span class="keyword">template</span>&lt;<span class="keyword">class</span> A, B&gt;
 16B* refCast(A* a)
 17{
 18    <span class="comment">// If the handle already is a null handle, then just return the null handle</span>
 19    <span class="keywordflow">if</span>( !a ) <span class="keywordflow">return</span> 0;
 20
 21    <span class="comment">// Now try to dynamically cast the pointer to the wanted type</span>
 22    B* b = <span class="keyword">dynamic_cast&lt;</span>B*<span class="keyword">&gt;</span>(a);
 23    <span class="keywordflow">if</span>( b != 0 )
 24    {
 25        <span class="comment">// Since the cast was made, we need to increase the ref counter for the returned handle</span>
 26        b-&gt;addref();
 27    }
 28    <span class="keywordflow">return</span> b;
 29}
 30
 31<span class="comment">// Example registration of the behaviour</span>
 32r = 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">"base"</span>, <a class="code" href="angelscript_8h.html#7e38df5b10ec8cbf2a688f1d114097c520746394824509f369f860ea1e96d1f6" title="Explicit reference cast operator.">asBEHAVE_REF_CAST</a>, <span class="stringliteral">"derived@ f()"</span>, <a class="code" href="angelscript_8h.html#78f8f2c7f1c88b12e74a5ac47b4184ae" title="Returns an asSFuncPtr representing the function specified by the name.">asFUNCTION</a>((refCast&lt;base,derived&gt;)), <a class="code" href="angelscript_8h.html#3ec92ea3c4762e44c2df788ceccdd1e4c08652c72f1cc0dc81c37812fab0e253" title="A cdecl function that takes the object pointer as the last parameter.">asCALL_CDECL_OBJLAST</a>); assert( r &gt;= 0 );
 33r = 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">"derived"</span>, <a class="code" href="angelscript_8h.html#7e38df5b10ec8cbf2a688f1d114097c59b23cc523e8aa4984e5e56e54b95dee4" title="Implicit reference cast operator.">asBEHAVE_IMPLICIT_REF_CAST</a>, <span class="stringliteral">"base@ f()"</span>, <a class="code" href="angelscript_8h.html#78f8f2c7f1c88b12e74a5ac47b4184ae" title="Returns an asSFuncPtr representing the function specified by the name.">asFUNCTION</a>((refCast&lt;derived,base&gt;)), <a class="code" href="angelscript_8h.html#3ec92ea3c4762e44c2df788ceccdd1e4c08652c72f1cc0dc81c37812fab0e253" title="A cdecl function that takes the object pointer as the last parameter.">asCALL_CDECL_OBJLAST</a>); assert( r &gt;= 0 );
 34</pre></div><p>
 35Note that it may be necessary to add extra parenthesis to the <code>asFUNCTION</code> macro so that the preprocessor doesn't interpret the <code>,</code> in the template declaration as the argument separator in the macro.<p>
 36Remember that it is legal for the script to attempt a cast on a null pointer, in which case the result is also a null pointer. This means that the reference cast behaviour must not be implemented as a virtual class method, because then the call will crash if the object pointer is null.<h2><a class="anchor" name="doc_adv_class_hierarchy_2">
 37Inherited methods and properties</a></h2>
 38Just as relationships cannot be determined, there is also no way to automatically let AngelScript add inherited methods and properties to derived types. The reason for this is that method pointers and property offsets may differ between the base class and derived class, especially when multiple inheritance is used, and there is no way to automatically determine exactly what the difference is.<p>
 39For this reason the application needs to register all the inherited methods and properties for the derived classes, which may lead to a bit of duplicate code. However, you may be able to avoid the duplication through a bit of clever thinking. Here is an example of registering the methods and properties for a base class and the derived class (registration of behaviours has been omitted for briefness):<p>
 40<div class="fragment"><pre class="fragment"><span class="comment">// The base class</span>
 41<span class="keyword">class </span>base
 42{
 43<span class="keyword">public</span>:
 44  <span class="keyword">virtual</span> <span class="keywordtype">void</span> aMethod();
 45  
 46  <span class="keywordtype">int</span> aProperty;
 47};
 48
 49<span class="comment">// The derived class</span>
 50<span class="keyword">class </span>derived : <span class="keyword">public</span> base
 51{
 52<span class="keyword">public</span>:
 53  <span class="keyword">virtual</span> <span class="keywordtype">void</span> aNewMethod();
 54  
 55  <span class="keywordtype">int</span> aNewProperty;
 56};
 57
 58<span class="comment">// The code to register the classes</span>
 59<span class="comment">// This is implemented as a template function, to support multiple inheritance</span>
 60<span class="keyword">template</span> &lt;<span class="keyword">class</span> T&gt;
 61<span class="keywordtype">void</span> RegisterBaseMembers(<a class="code" href="classas_i_script_engine.html" title="The engine interface.">asIScriptEngine</a> *engine, <span class="keyword">const</span> <span class="keywordtype">char</span> *type)
 62{
 63  <span class="keywordtype">int</span> r;
 64
 65  r = engine-&gt;<a class="code" href="classas_i_script_engine.html#6686c12ef37f4a4b1f9e90997b4756d0" title="Registers a method for the object type.">RegisterObjectMethod</a>(type, <span class="stringliteral">"void aMethod()"</span>, <a class="code" href="angelscript_8h.html#7345e6b3afabec24efd0ff77886d49a6" title="Returns an asSFuncPtr representing the class method specified by class and method...">asMETHOD</a>(T, aMethod), <a class="code" href="angelscript_8h.html#3ec92ea3c4762e44c2df788ceccdd1e4ea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );
 66  
 67  r = engine-&gt;<a class="code" href="classas_i_script_engine.html#33f3cd249307f5f11120a395579410f6" title="Registers a property for the object type.">RegisterObjectProperty</a>(type, <span class="stringliteral">"int aProperty"</span>, offsetof(T, aProperty)); assert( r &gt;= 0 );
 68}
 69
 70<span class="keyword">template</span> &lt;<span class="keyword">class</span> T&gt;
 71<span class="keywordtype">void</span> RegisterDerivedMembers(<a class="code" href="classas_i_script_engine.html" title="The engine interface.">asIScriptEngine</a> *engine, <span class="keyword">const</span> <span class="keywordtype">char</span> *type)
 72{
 73  <span class="keywordtype">int</span> r;
 74
 75  <span class="comment">// Register the inherited members by calling </span>
 76  <span class="comment">// the registration of the base members</span>
 77  RegisterBaseMembers&lt;T&gt;(engine, type);
 78
 79  <span class="comment">// Now register the new members</span>
 80  r = engine-&gt;RegisterObjectMethod(type, <span class="stringliteral">"void aNewMethod()"</span>, <a class="code" href="angelscript_8h.html#7345e6b3afabec24efd0ff77886d49a6" title="Returns an asSFuncPtr representing the class method specified by class and method...">asMETHOD</a>(T, aNewMethod), <a class="code" href="angelscript_8h.html#3ec92ea3c4762e44c2df788ceccdd1e4ea516c8742acc1edff6a43dc1bb09e96" title="A thiscall class method.">asCALL_THISCALL</a>); assert( r &gt;= 0 );
 81
 82  r = engine-&gt;RegisterObjectProperty(type, <span class="stringliteral">"int aProperty"</span>, offsetof(T, aProperty)); assert( r &gt;= 0 );
 83}
 84
 85<span class="keywordtype">void</span> RegisterTypes(<a class="code" href="classas_i_script_engine.html" title="The engine interface.">asIScriptEngine</a> *engine)
 86{
 87  <span class="keywordtype">int</span> r;
 88
 89  <span class="comment">// Register the base type</span>
 90  r = engine-&gt;<a class="code" href="classas_i_script_engine.html#29c6c087c8c5b5cdb6271cfd161cc5a6" title="Registers a new object type.">RegisterObjectType</a>(<span class="stringliteral">"base"</span>, 0, <a class="code" href="angelscript_8h.html#855d86fa9ee15b9f75e553ee376b5c7a9450e038342b36c745858d2e5ae4b861" title="A reference type.">asOBJ_REF</a>); assert( r &gt;= 0 );
 91  RegisterBaseMembers&lt;base&gt;(engine, <span class="stringliteral">"base"</span>);
 92
 93  <span class="comment">// Register the derived type</span>
 94  r = engine-&gt;RegisterObjectType(<span class="stringliteral">"derived"</span>, 0, <a class="code" href="angelscript_8h.html#855d86fa9ee15b9f75e553ee376b5c7a9450e038342b36c745858d2e5ae4b861" title="A reference type.">asOBJ_REF</a>); assert( r &gt;= 0 );
 95  RegisterDerivedMembers&lt;derived&gt;(engine, <span class="stringliteral">"derived"</span>);
 96}
 97</pre></div> </div>
 98<hr size="1"><address style="text-align: right;"><small>Generated on Wed Dec 16 19:34:50 2009 for AngelScript by&nbsp;
 99<a href="http://www.doxygen.org/index.html">
100<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.9 </small></address>
101</body>
102</html>