I am creating the AI engine for a JS game, and it's made of Finite State Machines. I am loading the number of states and their variable values from the XML. I also want to load the behaviour, and since I don't have the time to create a scripting language, I thought it would be a good idea to 'insert' JS code on external files (inside XML nodes), and execute it on demand.
Something like that
<evilguy1> <behaviour> this.x++; </behaviour> <behaviour> this.y++; </behaviour> </evilguy1>
To something like that:
function behaviour_1(){ this.x++; } function behaviour_2(){ this.y++; }
My question is, now that I have the code loaded, how can I execute it? I would like to create a function with an unique name for each code 'node', and then call them from the game logic, but I don't know if this is possible (Since you can load more JS code from the HTML, you should also be able to do it from the JS code, no?). If not, is there any similar solution? Thanks in advance!
(PS:The less external-library-dependent, the better)
Edit 1:
Ok, so now I know how to create functions to contain the code
window[classname] = function() { ... };
The dynamic nature of JavaScript means that a function is able to not only call itself, but define itself, and even redefine itself. This is done by assigning an anonymous function to a variable that has the same name as the function.
The syntax for creating a function: let func = new Function ([arg1, arg2, ... argN], functionBody); The function is created with the arguments arg1...
Dynamic function is a way of dynamically invoking a function call. The compiler will have limited knowledge of what you are up to so you will get run time errors if you don't use correct inputs and outputs. One example that runs different functions depending on user input: DEFINE VARIABLE iFunc AS INTEGER NO-UNDO.
Function() constructor. The Function() constructor creates a new Function object. Calling the constructor directly can create functions dynamically, but suffers from security and similar (but far less significant) performance issues as eval() .
Well, you could use Function
constructor, like in this example:
var f = new Function('name', 'return alert("hello, " + name + "!");'); f('erick');
This way you're defining a new function with arguments and body and assigning it to a variable f. You could use a hashset and store many functions:
var fs = []; fs['f1'] = new Function('name', 'return alert("hello, " + name + "!");'); fs['f1']('erick');
Loading xml depends if it is running on browser or server.
To extend Ericks answer about the Function constructor.
The Function constructor creates an anonymous function, which on runtime error would print out anonymous for each function (created using Function) in the call stack. Which could make debugging harder.
By using a utility function you can dynamically name your created functions and bypass that dilemma. This example also merges all the bodies of each function inside the functions array into one before returning everything as one named function.
const _createFn = function(name, functions, strict=false) { var cr = `\n`, a = [ 'return function ' + name + '(p) {' ]; for(var i=0, j=functions.length; i<j; i++) { var str = functions[i].toString(); var s = str.indexOf(cr) + 1; a.push(str.substr(s, str.lastIndexOf(cr) - s)); } if(strict == true) { a.splice(1, 0, '\"use strict\";' + cr) } return new Function(a.join(cr) + cr + '}')(); }
A heads up about the Function constructor:
A function defined by a function expression inherits the current scope. That is, the function forms a closure. On the other hand, a function defined by a Function constructor does not inherit any scope other than the global scope (which all functions inherit).
source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Differences
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With