skip to content
Frictional Game Wiki
User Tools
Register
Log In
Site Tools
Search
Tools
Show page
Old revisions
Backlinks
Recent Changes
Media Manager
Sitemap
Log In
Register
>
Recent Changes
Media Manager
Sitemap
Trace:
hpl2:tutorials:script:funcdef
<h1>Funcdef & Function Pointers</h1> <div class="level1"> <p> This tutorial explains how to set up and use funcdefs & function pointers in level scripts. The first two parts of this tutorial cover some very basic examples on use, with the last mixing arrays and function pointers to allow both calling sequences and a function at random. </p> </div> <h3>Introduction to the "funcdef" statement</h3> <div class="level3"> <p> The <a href="http://www.angelcode.com/angelscript/sdk/docs/manual/doc_datatypes_funcptr.html" class="urlextern" title="http://www.angelcode.com/angelscript/sdk/docs/manual/doc_datatypes_funcptr.html" rel="nofollow">Angelscript documentation</a> states that <em>"A function pointer 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." </em> In other words, you're making a <b>type</b> - something like <em>int </em> or <em>string </em> - but instead of this type's variables containing <em>text</em> or <em>numbers</em>, it contains functions - or more specifically, pointers to functions . <br/> To understand better what a function pointer is: Consider a box, and this box contains a note telling you to look in another box somewhere else - this is your function pointer, it just contains information on where to look. The other box, the one <em>referenced, </em> contains the actual functional information. We can use these "extra boxes" to create variables that can be called just like functions. </p> <p> The first stage in the process, is to make the type which will used to create variables later. This type is dependant on what the signature of your function is (that is, what arguments are taken in by the function, and what is returned by the function) - Below are some example funcdef statements: </p> <pre class="code cpp">funcdef <span class="kw4">void</span> fdSimpleFunction<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Used for pointers to functions which take no arguments and return no vales </span> funcdef <span class="kw4">int</span> fdReturningFunction<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Used for pointers to functions which return an int and take no arguments.</span> funcdef <span class="kw4">int</span> fdComplexFunction<span class="br0">(</span><span class="kw4">int</span>, <span class="kw4">int</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Used for pointers to functions which of return type int and take two ints as arguments</span> </pre><p> </p> <p> Taking the top statement, here is a sample function which could later be pointed to: </p> <pre class="code cpp"><span class="kw4">void</span> sfHelloWorld<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> AddDebugMessage<span class="br0">(</span>"Hello World<span class="sy3">!</span>", <span class="kw2">false</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Outputs: Hello World!</span> <span class="br0">}</span> </pre><p> </p> <p> With a function pointer type defined, and a function to point to - the next step is to make the function pointer: </p> <pre class="code cpp">fdSimpleFunction@ functionVar<span class="sy4">;</span> </pre><p> </p> <p> This is similar to just normal variable creation, except the "@" sign - The "@" symbol in angelscript literally means "Handle of" / "Address of", and is just stating that our variable is a pointer. However it currently point anywhere - it literally <em>"is null"</em>. To make it point to a function, we use an assignment statement just like a normal variable, except the "@" symbol appears again: </p> <pre class="code cpp"><span class="co1">// We know this line declares our functionVar</span> fdSimpleFunction@ functionVar<span class="sy4">;</span> <span class="co1">// We now will make this point to sfHelloWorld()!</span> @functionVar <span class="sy1">=</span> @sfHelloWorld<span class="sy4">;</span> </pre><p> </p> <p> This new line is making <em>functionVar </em> point to the address of <em>sfHelloWorld</em> (in other words, we just put a note in our box saying look into the specific other box for <em>sfHelloWorld</em>). You are actually saying <b>"set the handle of function var to the handle of sfHelloWorld"</b> - this is why <em>functionVar </em> can be called just like the function, even though it is actually a variable: </p> <pre class="code cpp"><span class="co1">// If all has gone well:</span> functionVar<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Does exactly the same as:</span> sfHelloWorld<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> </pre><p> </p> <p> Below is a sample map script file using the code covered in this section, make sure to be in developer mode to see the output. </p> <pre class="code cpp"><span class="co1">// Make the type "fdSimpleFunction"</span> funcdef <span class="kw4">void</span> fdSimpleFunction<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Output hello world</span> <span class="kw4">void</span> sfHelloWorld<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> AddDebugMessage<span class="br0">(</span>"Hello World<span class="sy3">!</span>", <span class="kw2">false</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> <span class="kw4">void</span> OnStart<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="co1">// Call the function normally!</span> AddDebugMessage<span class="br0">(</span>"Calling the function normally<span class="sy3">!</span>", <span class="kw2">false</span><span class="br0">)</span><span class="sy4">;</span> sfHelloWorld<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Call the function using our variable!</span> AddDebugMessage<span class="br0">(</span>"Calling the function <span class="kw2">using</span> the pointer<span class="sy3">!</span>", <span class="kw2">false</span><span class="br0">)</span><span class="sy4">;</span> fdSimpleFunction@ functionVar<span class="sy4">;</span> @functionVar <span class="sy1">=</span> @sfHelloWorld<span class="sy4">;</span> functionVar<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> </pre><p> </p> <p> So far, all we have managed to achieve is something we could have done already! Why go through all this hassle, to just call a function we could have called anyway? The next section shows how the variable aspect of the function can be exploited to solve a basic problem. </p> </div> <h3>Solving a basic problem with function pointers</h3> <div class="level3"> <p> This following example can easily be solved without function pointers - however it compactly demonstrates that function pointers can point to any function with a matching signature, and gives a glimpse of what can be achieved using this. If a function pointer can change where it points to - we can effectively make one function call actually call different things to suit what we want. Take for example, the following two functions: </p> <pre class="code cpp"><span class="kw4">void</span> bigFunction<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> subFunction<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> <span class="kw4">void</span> subFunction<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="co1">//Implementing later...</span> <span class="br0">}</span> </pre><p> </p> <p> The specification is as follows: At the end of <em>bigFunction</em> we want to call a function called <em>output1</em>. However, <em>subFunction</em> should have a random (1/4) chance of making <em>bigFunction</em> call <em>output2</em> instead. Both the output functions are defined below: </p> <pre class="code cpp"><span class="kw4">void</span> output1<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> AddDebugMessage<span class="br0">(</span>"Yo<span class="sy3">!</span>", <span class="kw2">false</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> <span class="kw4">void</span> output2<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> AddDebugMessage<span class="br0">(</span>"Dawg<span class="sy3">!</span>", <span class="kw2">false</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> </pre><p> </p> <p> This problem can be solved using a function pointer. First again, the type which matches are output functions is defined: </p> <pre class="code cpp"><span class="co1">// Create a function definition (which is actually the same as fdSimpleFunction)</span> <span class="co1">// Which will matches the signature of both our output functions</span> funcdef <span class="kw4">void</span> fdOutput<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> </pre><p> </p> <p> With the second step creating the variable which shall initially point to <em>output1 </em> at the start of <em>bigFunction. </em> Next we call <em>subFunction </em> as before, which will change the function pointer. Finally, we will call the function pointed to by the pointer: </p> <pre class="code cpp">fdOutput @outputChoice<span class="sy4">;</span> <span class="kw4">void</span> bigFunction<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> @outputChoice <span class="sy1">=</span> @output1<span class="sy4">;</span> subFunction<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> outputChoice<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> </pre><p> </p> <p> The <em>subFunction</em> implementation is as follows: </p> <pre class="code cpp"><span class="kw4">void</span> subFunction<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">if</span><span class="br0">(</span>RandInt<span class="br0">(</span><span class="nu0">0</span>, <span class="nu0">3</span><span class="br0">)</span> <span class="sy1">==</span> <span class="nu0">1</span><span class="br0">)</span> <span class="br0">{</span> @outputChoice <span class="sy1">=</span> @output2<span class="sy4">;</span> <span class="co1">// A 1 in 4 chance of this code being reached</span> <span class="br0">}</span> <span class="br0">}</span> </pre><p> </p> <p> Problem solved. You can test out the full code as with the previous section below: </p> <pre class="code cpp"><span class="co1">// Create a function definition (which is actually the same as fdSimpleFunction)</span> <span class="co1">// Which will matches the signature of both our output functions</span> funcdef <span class="kw4">void</span> fdOutput<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Our output functions </span> <span class="kw4">void</span> output1<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> AddDebugMessage<span class="br0">(</span>"Yo<span class="sy3">!</span>", <span class="kw2">false</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> <span class="kw4">void</span> output2<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> AddDebugMessage<span class="br0">(</span>"Dawg<span class="sy3">!</span>", <span class="kw2">false</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> <span class="co1">// The actual stuff that does the descision making</span> fdOutput @outputChoice<span class="sy4">;</span> <span class="kw4">void</span> bigFunction<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> @outputChoice <span class="sy1">=</span> @output1<span class="sy4">;</span> <span class="co1">// Initially point to output 1</span> subFunction<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Call with 1/4 chance of changing outputChoice </span> outputChoice<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Call whichever output has been chosen</span> <span class="br0">}</span> <span class="kw4">void</span> subFunction<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">if</span><span class="br0">(</span>RandInt<span class="br0">(</span><span class="nu0">0</span>, <span class="nu0">3</span><span class="br0">)</span> <span class="sy1">==</span> <span class="nu0">1</span><span class="br0">)</span> <span class="br0">{</span> @outputChoice <span class="sy1">=</span> @output2<span class="sy4">;</span> <span class="co1">// A 1 in 4 chance of changing the function pointer</span> <span class="br0">}</span> <span class="br0">}</span> <span class="kw4">void</span> OnStart<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="co1">// Call bigFunction 20 times - notice roughly a 1/4 chance of output2?</span> <span class="kw1">for</span><span class="br0">(</span><span class="kw4">int</span> i<span class="sy1">=</span><span class="nu0">0</span><span class="sy4">;</span> i< 20<span class="sy4">;</span> i<span class="sy2">++</span><span class="br0">)</span> bigFunction<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> </pre><p> </p> <p> It's time to move onto solving a much bigger problem: Calling a random function. </p> </div> <h3>Arrays, function pointers, and you</h3> <div class="level3"> <p> We shall extend the above problem to have an arbitrary number of functions, and still manage calling one at random. To make things easier though, we will have each function called with an equal probablility. Obviously we could do a massive set of ifs, or a huge switch-case block (what if there are 100 choices? who would want to write that out that switch-case?). We shall re-use most of the code from the first section to get started, however, this time there are two new signature matching functions, giving us the following script file so far: </p> <pre class="code cpp"><span class="co1">// This creates a signature called "SimpleFunction"</span> <span class="co1">// Which matches functions which take no arguments, and return nothing...</span> funcdef <span class="kw4">void</span> fdSimpleFunction<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// ...such as the following sample functions:</span> <span class="co1">// This function will output "hello world"</span> <span class="kw4">void</span> sfHelloWorld<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> AddDebugMessage<span class="br0">(</span>"Hello World<span class="sy3">!</span>", <span class="kw2">false</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> <span class="co1">// This function will output how many times it has been called </span> <span class="kw4">void</span> sfDisplayTimesCalled<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> AddLocalVarInt<span class="br0">(</span>"DTC_TimesCalled", <span class="nu0">1</span><span class="br0">)</span><span class="sy4">;</span> AddDebugMessage<span class="br0">(</span>"DisplayTimesCalled, called<span class="sy4">:</span> " <span class="sy2">+</span> GetLocalVarInt<span class="br0">(</span>"DTC_TimesCalled"<span class="br0">)</span> <span class="sy2">+</span> " times", <span class="kw2">false</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> <span class="co1">//This function will play the sound of an angry brute! </span> <span class="kw4">void</span> sfPlayScarySound<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> PlayGuiSound<span class="br0">(</span>"enemy\\brute\\notice.<span class="me1">snt"</span>, <span class="nu17">1.0f</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> </pre><p> </p> <p> The problem of calling one of the functions at random is going to be solved by making an array. Each index is going to contain one of the above functions, we just then pick a random index, and call the function at that index. This solution scales really nicely when there is are a good number of functions to call. </p> <p> An array of function pointers is declared in the following code segment - note that the {} part is not required, but merely used for the sake of compact-ness, all this section does is initialise the array with some values in it already. If you are not familiar with arrays, take a scan through the <a href="http://www.angelcode.com/angelscript/sdk/docs/manual/doc_script.html" class="urlextern" title="http://www.angelcode.com/angelscript/sdk/docs/manual/doc_script.html" rel="nofollow">Angelscript documentation</a>. </p> <pre class="code cpp">fdSimpleFunction@<span class="br0">[</span><span class="br0">]</span> simpleFunctions <span class="sy1">=</span> <span class="br0">{</span> @sfHelloWorld, @sfDisplayTimesCalled, @sfPlayScarySound <span class="br0">}</span><span class="sy4">;</span> </pre><p> </p> <p> Now all is left to do is create a function that picks an index at random, and calls the function at that index: </p> <pre class="code cpp"><span class="kw4">void</span> callRandomSimpleFunction<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> uint index <span class="sy1">=</span> RandInt<span class="br0">(</span><span class="nu0">0</span>, simpleFunctions.<span class="me1">length</span><span class="br0">(</span><span class="br0">)</span><span class="sy2">-</span><span class="nu0">1</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Pick a random index from the array</span> fdSimpleFunction @functionToCall <span class="sy1">=</span> simpleFunctions<span class="br0">[</span>index<span class="br0">]</span><span class="sy4">;</span> <span class="co1">// Select that function</span> functionToCall<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Call that function</span> <span class="co1">// Note this can be simplified down to one line:</span> <span class="co1">// simpleFunctions[RandInt(0, simpleFunctions.length()-1)]();</span> <span class="br0">}</span> </pre><p> </p> <p> We are also in a prime position to solve the problem of sequences here too, the following code will call each function in order in the array: </p> <pre class="code cpp"><span class="kw4">void</span> callEachFunction<span class="br0">(</span>string <span class="sy3">&</span>in asTimerName<span class="br0">)</span> <span class="br0">{</span> uint index <span class="sy1">=</span> GetLocalVarInt<span class="br0">(</span>"simpleFunctionIndex"<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Get the index</span> <span class="kw1">if</span><span class="br0">(</span>index<span class="sy1">>=</span> simpleFunctions.<span class="me1">length</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="kw1">return</span><span class="sy4">;</span> <span class="co1">// Don't go any further if we have called all the functions</span> <span class="co1">// Access, and call like before:</span> fdSimpleFunction @functionToCall <span class="sy1">=</span> simpleFunctions<span class="br0">[</span>index<span class="br0">]</span><span class="sy4">;</span> functionToCall<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> AddLocalVarInt<span class="br0">(</span>"simpleFunctionIndex", <span class="nu0">1</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Increment the index, so the next function is called shortly...</span> AddTimer<span class="br0">(</span>asTimerName, <span class="nu17">1.0f</span>, "callEachFunction"<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Call this function again in 1 second, so the next function is called</span> <span class="br0">}</span> </pre><p> </p> <p> One potential extension for use with sequences is making each function return a float, which can then be used as the delay time before calling the next function. The sample script file for this section is below, don't forget to visit the OnStart routine and uncomment one of the two lines - or you won't see anything, and additional function is added to loop the <em>callRandomSimpleFunction</em> with a timer so it's effects can be seen easier: </p> <pre class="code cpp"><span class="co1">// This creates a signature called "SimpleFunction"</span> <span class="co1">// Which matches functions which take no arguments, and return nothing.</span> funcdef <span class="kw4">void</span> fdSimpleFunction<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Such as these sample functions:</span> <span class="kw4">void</span> sfHelloWorld<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> AddDebugMessage<span class="br0">(</span>"Hello World<span class="sy3">!</span>", <span class="kw2">false</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Output hello world</span> <span class="br0">}</span> <span class="kw4">void</span> sfDisplayTimesCalled<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> AddLocalVarInt<span class="br0">(</span>"DTC_TimesCalled", <span class="nu0">1</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">//Display how many times function was called:</span> AddDebugMessage<span class="br0">(</span>"DisplayTimesCalled, called<span class="sy4">:</span> " <span class="sy2">+</span> GetLocalVarInt<span class="br0">(</span>"DTC_TimesCalled"<span class="br0">)</span> <span class="sy2">+</span> " times", <span class="kw2">false</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> <span class="kw4">void</span> sfPlayScarySound<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> PlayGuiSound<span class="br0">(</span>"enemy\\brute\\notice.<span class="me1">snt"</span>, <span class="nu17">1.0f</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Play the sound of an angry brute!</span> <span class="br0">}</span> <span class="co1">// We now can create an array of these simple functions for further use.</span> fdSimpleFunction@<span class="br0">[</span><span class="br0">]</span> simpleFunctions <span class="sy1">=</span> <span class="br0">{</span> @sfHelloWorld, @sfDisplayTimesCalled, @sfPlayScarySound <span class="br0">}</span><span class="sy4">;</span> <span class="co1">// Some example uses of this: </span> <span class="co1">// Calling a random function</span> <span class="kw4">void</span> callRandomSimpleFunction<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> uint index <span class="sy1">=</span> RandInt<span class="br0">(</span><span class="nu0">0</span>, simpleFunctions.<span class="me1">length</span><span class="br0">(</span><span class="br0">)</span><span class="sy2">-</span><span class="nu0">1</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Pick a random index from the array</span> fdSimpleFunction @functionToCall <span class="sy1">=</span> simpleFunctions<span class="br0">[</span>index<span class="br0">]</span><span class="sy4">;</span> <span class="co1">// Select that function</span> functionToCall<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Call that function</span> <span class="co1">// Note this can be simplified down to one line:</span> <span class="co1">// simpleFunctions[RandInt(0, simpleFunctions.length()-1)]();</span> <span class="br0">}</span> <span class="co1">// Using a timer to call one function per second in sequence.</span> <span class="kw4">void</span> callEachFunction<span class="br0">(</span>string <span class="sy3">&</span>in asTimerName<span class="br0">)</span> <span class="br0">{</span> uint index <span class="sy1">=</span> GetLocalVarInt<span class="br0">(</span>"simpleFunctionIndex"<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Get the index</span> <span class="kw1">if</span><span class="br0">(</span>index<span class="sy1">>=</span> simpleFunctions.<span class="me1">length</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="kw1">return</span><span class="sy4">;</span> <span class="co1">// Don't go any further if we have called all the functions</span> <span class="co1">// Access, and call like before:</span> fdSimpleFunction @functionToCall <span class="sy1">=</span> simpleFunctions<span class="br0">[</span>index<span class="br0">]</span><span class="sy4">;</span> functionToCall<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> AddLocalVarInt<span class="br0">(</span>"simpleFunctionIndex", <span class="nu0">1</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Increment the index</span> AddTimer<span class="br0">(</span>asTimerName, <span class="nu17">1.0f</span>, "callEachFunction"<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// Call this function again in 1 second</span> <span class="br0">}</span> <span class="co1">// Using a timer to repeatedly call a random function</span> <span class="kw4">void</span> callRandTimer<span class="br0">(</span>string <span class="sy3">&</span>in asTimerName<span class="br0">)</span> <span class="br0">{</span> callRandomSimpleFunction<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> AddTimer<span class="br0">(</span>asTimerName, <span class="nu17">1.0f</span>, "callRandTimer"<span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> <span class="kw4">void</span> OnStart<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="co1">// Uncomment one of the following to test it out!</span> <span class="co1">//callEachFunction("testTimer1");</span> <span class="co1">//callRandTimer("testTimer2");</span> <span class="br0">}</span> </pre><p> </p> </div> <h3>Closing comments</h3> <div class="level3"> <p> A quick note on an earlier point - when the function pointer is defined initially, it points nowhere (as it does if an assignment fails due to mismatching signatures). This can be tested for with the following code: </p> <pre class="code cpp"><span class="kw1">if</span><span class="br0">(</span> functionPointer is null <span class="br0">)</span> </pre><p> </p> <p> Finally, that state of a function pointer <b>is not saved when the map is - </b> there is no way to save the state of a function pointer - so keep them the same (which is fine in the case of an array - like the last example), or assume they haven't changed within the <b>scope</b> of the first function (E.g. the second example). </p> <p> <b>You should now understand a little about funcdefs. Have a play around, you can use this to make sequences, callbacks, and all sorts of fun stuff. </b> </p> <p> <a href="http://www.angelcode.com/angelscript/sdk/docs/manual/doc_script.html" class="urlextern" title="http://www.angelcode.com/angelscript/sdk/docs/manual/doc_script.html" rel="nofollow">Check out the documentation at: www.angelcode.com/angelscript/sdk/docs/manual/doc_script.html</a> </p> </div>
hpl2/tutorials/script/funcdef.txt
· Last modified: 2011/08/15 01:09 by
apjjm
Page Tools
Show page
Old revisions
Backlinks
Export to PDF
Back to top