Two part question. Making a dynamic array of delegates, and taking in a delegate with unknown parameters as an argument .

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Dec 1 16:11:07 PST 2016


On 12/01/2016 03:51 PM, Payotz wrote:
 > So, to give context, I am trying to make an event manager for a game I'm
 > making.
 > I was writing the "register()" method so I ran into a problem.
 >
 > The register method will take in delegates as an argument, but those
 > delegates have varied arguments themselves, so I can't really put
 > anything there.

What you know is how you will call them. Let's assume just an int argument.

 > I know that it's got something to do with templates so I
 > tried my hand in it and came up with this:
 >
 > void registerEvent(string event_name,T...)(T delegate() dg);

Binding state to callables is pretty easy in D. You don't want to pass 
the arguments to the registration because it wouldn't know what to do 
with those: Store the state for the delegate? Maybe, maybe not.

 > I know there's something missing in the way I did it, so I'll be glad
 > for you folks to tell me what I'm missing.

All you need is your interface to these callbacks.

 > And for the second part of the question, I can't seem to make a Dynamic
 > Array where I could store the delegates taken in the "registerEvent"
 > method. Closest thing I have gotten to is this:
 >
 > private void delegate(T)(T args)[string] event;
 >
 > which resulted in the compiler screaming Error signs at me.
 > So how does one do it?

Here is a start:

import std.stdio;

alias Func = void delegate(int);

Func[string] registry;

void register(string event_name, Func func) {
     registry[event_name] = func;
}

struct S {
     double d;
     string s;

     void foo(int i) {
         writefln("S.foo called with %s; my state: %s", i, this);
     }
}

void bar(int i) {
     writefln("bar called with %s", i);
}

void main() {
     register("trivial", (int a) => writefln("called with %s", a));

     auto s = S(2.5, "hello");
     register("with_struct", &s.foo);

     int j;
     register("using_local_state", (int a) {
             ++j;
             writefln("Incremented local j: %s", j);
         });

     // This won't work as &bar because &bar is not a delegate, but a 
function.
     // Very simple with toDelegate.
     // http://dlang.org/phobos/std_functional.html#toDelegate
     import std.functional: toDelegate;
     register("regular_function", toDelegate(&bar));

     foreach (event_name, func; registry) {
         writefln("--- Calling function registered for %s", event_name);
         func(cast(int)event_name.length);
     }
}

Ali



More information about the Digitalmars-d-learn mailing list