- Home /
Can References to Functions Be Stored in an Array?
Let me begin by explaining what I am doing. I am developing a Need based AI system. Basically, the agent polls surrounding objects and determines which will provide the best reward in terms of the agent's current needs. In order to get the reward as advertised, the agent will need to perform certain actions that are dictated by the advertising object. So, for example, to get a +10 reward towards hunger, the agent would have to do certain actions that are determine by the advertising object. When the agent selects an advertising object, that object pushes the actions the agent needs to do onto the agent's action queue.
Now to my question. I need to somehow create the action queue for the agent such that reward objects can push their actions onto it. My first thought was to define the actions and their logic somewhere on the reward object as functions, and then, somehow, pass a reference to the functions to the agent to be stored on the action queue. Is this possible? Can a create an array on the agent that can store references to functions on another object? As I believe it has some relevance, I am currently attempting this using JS, but am not opposed to C# if it is easier to implement.
Or, perhaps, there is a better way of doing all of this?
If it helps, this is the article I am using as a starting point for this system: http://robert.zubek.net/publications/Needs-based-AI-draft.pdf
Answer by Eric5h5 · Jan 26, 2012 at 10:48 PM
It's easy enough if all the functions have the same parameter types (in the case of this example, no parameters):
function Start () {
var functionList = new List.<function()>();
functionList.Add(Foo);
functionList.Add(Bar);
for (var i = 0; i < functionList.Count; i++) {
functionList[i]();
}
}
function Foo () {
Debug.Log ("foo");
}
function Bar () {
Debug.Log ("bar");
}
Do you say "if they have the same parameter types" because List will only store objects of the same type? If that is the case, then, could I use Array ins$$anonymous$$d, since it doesn't care about the type, and use it to store any set of functions, even with differing parameter types?
There's no reason to use Array, but you can use a List of Object (which would mostly amount to the same thing, except faster), though you'd have to cast to the correct type when accessing each element, so I don't know how useful that would be in practice:
function Start () {
var functionList = new List.<Object>();
functionList.Add(Foo);
functionList.Add(Bar);
(functionList[0] as function())();
(functionList[1] as function(int))(123);
}
function Foo () {
Debug.Log ("foo");
}
function Bar (x : int) {
Debug.Log ("bar " + x);
}
Ok. I'm trying this system a little differently, and I am having issues with syntax. How can I, if possible, declare a variable of type function(Type)? Or better yet, how can I translate the aspect of what you have given me into an argument I can pass to another function?
What I am trying to do now is have an object that, when it needs something done, it will send a request for service via a task manager. Think of the task manager as a bulletin board of sorts. When an object needs something done, it posts a task request to the task manager. The task request would identify the script on whichever object is requesting service and which function in that script should be called by whichever agent is going to fulfill the request.
What I have got so far is some object with a function, CallRepair(), and a function Repair(Agent). Repair(Agent) will be the code that assumes control of the agent that is passed to it until the repair is complete. CallRepair() will call Task$$anonymous$$anager.PostTask(this,Repair). I need a way to define Task$$anonymous$$anager.PostTask() such that it knows to expect a script of any type and a as parameters so that it can store those as a Task object in a list. A Task object is basically a struct that has variables for the script and the function to call in that script.
Answer by Maker16 · Jun 12, 2012 at 02:02 AM
Nevermind. I sorted it out(basically, I overlooked the obvious and assumed it would be more complex):
function PostTask(func : function(Agent):int)