array of delegates

2016-04-13 Thread Alex via Digitalmars-d-learn

Hi at all!
Having read this:
http://forum.dlang.org/post/mailman.2415.1354291433.5162.digitalmars-d-le...@puremagic.com

still have a problem...
Lets begin with what works:

enum Props{p1, p2}

class AA
{
int[] arr1;
int[] arr2;
this()
{
//arbitrary values...
arr1 = [9, 6, 33, 42, 58];
arr2 = [2, 3, 44, 28, 77];
}

auto Foo(int i, Props p)
{
with(Props)
{
final switch(p)
{
case p1:
{ return arr1[i]; }
break;
case p2:
{ return arr2[i]; }
break;
}
}
}
}

main()
{
int indarr[] = [0, 1, 2, 3, 4];
import std.stdio;
import std.functional;
AA aa = new AA();
int delegate(int, Props) sg;
sg = &aa.Foo;
alias M3 = partial!(sg, 3);
writeln(M3(Props.p1));
writeln(M3(Props.p2));
}

So far, so good. But now the question:
if I try

import std.algorithm;
indarr.map!(a => partial!(sg, a));

I get an error, like Error: partial (Props _param_0) is not 
callable using argument types ().


Do you have a hint, what I'm doing wrong?

For the motivation: In this way I would like to store some 
"links" to data I have without having to define a struct, which 
incorporate the data.
The struct itself is not the problem, but how the data is handled 
is not known by the struct, but only by the class AA, so the 
expressions inside the switch should not (?) lie inside the 
struct.


Re: array of delegates

2016-04-13 Thread David Skluzacek via Digitalmars-d-learn
So, that message is a pretty cryptic, but the problem there is 
that map does its thing at runtime, but partial is a template and 
must be instantiated at compile time.


Instead you can use std.meta.staticMap, by doing something like 
this:




void main()
{
import std.stdio;
import std.functional;
import std.meta;

AA aa = new AA();
int delegate(int, Props) sg;
sg = &aa.Foo;

template partialSG(alias a)
{
alias partialSG = partial!(sg, a);
}

alias indarr = AliasSeq!(0, 1, 2, 3, 4);
alias funs = staticMap!(partialSG, indarr);

foreach (fun; funs)
{
writeln( fun(Props.p1) );
writeln( fun(Props.p2) );
}
}


Re: array of delegates

2016-04-13 Thread Ali Çehreli via Digitalmars-d-learn

On 04/13/2016 04:39 PM, Alex wrote:

> import std.algorithm;
> indarr.map!(a => partial!(sg, a));

I think you want to generate a different delegate for each element where 
the first argument to sg is the value of that element (0, 1, etc.). 
Since the second element of sg is a Props, you then want to call those 
delegates with a Props value (e.g. Props.p1).


The following works:

import std.algorithm;
auto mapped = indarr
  .map!(a => (Props p) => sg(a, p))
  .map!(d => d(Props.p1));

writeln(mapped);

Ali



Re: array of delegates

2016-04-13 Thread Alex via Digitalmars-d-learn

On Thursday, 14 April 2016 at 05:54:38 UTC, David Skluzacek wrote:
So, that message is a pretty cryptic, but the problem there is 
that map does its thing at runtime, but partial is a template 
and must be instantiated at compile time.


Instead you can use std.meta.staticMap, by doing something like 
this:




void main()
{
import std.stdio;
import std.functional;
import std.meta;

AA aa = new AA();
int delegate(int, Props) sg;
sg = &aa.Foo;

template partialSG(alias a)
{
alias partialSG = partial!(sg, a);
}

alias indarr = AliasSeq!(0, 1, 2, 3, 4);
alias funs = staticMap!(partialSG, indarr);

foreach (fun; funs)
{
writeln( fun(Props.p1) );
writeln( fun(Props.p2) );
}
}


Ah, ok... so, it was my mistake due to runtime <-> compile time 
templates. Thanks.


But, this would help, only if I know the total amount of my 
elements at compile time. Say, the length of the indarr would be 
known.
What if I don't have this information? In reality, this 
information is already known for the constructors of my classes. 
But it seems very strange to me, to let the user recompile the 
program each time with some compiler flag in order to deliver 
this parameter a step prior to this.


Re: array of delegates

2016-04-13 Thread Alex via Digitalmars-d-learn

On Thursday, 14 April 2016 at 06:27:29 UTC, Ali Çehreli wrote:

On 04/13/2016 04:39 PM, Alex wrote:

> import std.algorithm;
> indarr.map!(a => partial!(sg, a));

I think you want to generate a different delegate for each 
element where the first argument to sg is the value of that 
element (0, 1, etc.). Since the second element of sg is a 
Props, you then want to call those delegates with a Props value 
(e.g. Props.p1).


The following works:

import std.algorithm;
auto mapped = indarr
  .map!(a => (Props p) => sg(a, p))
  .map!(d => d(Props.p1));

writeln(mapped);

Ali


Yes exactly!
The idea is to save
auto mapped = indarr.map!(a => (Props p) => sg(a, p));
for later use and use it then
by mapped[someIndex](Props.p1) or mapped[someIndex](Props.p2) 
when needed.

Thank you very much! :)



problem with array of delegates!

2011-06-19 Thread Lloyd Dupont

the following code seem problematic to compile...


import std.algorithm;
private alias void delegate(int, int) SlotDelegate;

class A
{
   void DIT(int a, int b)
   {
   }
}

int main(string[] argv)
{
   A a;
   SlotDelegate x= &a.DIT;

   SlotDelegate[] _slotDg;
   _slotDg.remove(x);

   return 0;
}

I have some strange error:
Error: incompatible types for ((pos) < (from)): 'uint' and 'void 
delegate(int, int)' 
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d5609



I try a method like that as well (but similar problem! :( )

void removeAt(T)(ref T[] array, int index)
{
   if(index < 0 || index >= array.length)
   return;
   const T[] empty = null;
   array.replaceInPlace(index, index + 1, empty);
}
 



Re: problem with array of delegates!

2011-06-19 Thread Andrej Mitrovic
Remove takes an offset, not a value as far as I know.

If you need fast lookup and removal you could use hashes instead:

int main(string[] argv)
{
auto a = new A;
SlotDelegate x = &a.DIT;

bool[SlotDelegate] _slotDg;
_slotDg.remove(x);

return 0;
}


Re: problem with array of delegates!

2011-06-19 Thread Andrej Mitrovic
Seems like gmail likes to cut my code. If that didn't paste well here:
http://codepad.org/cyEDHSGc


Re: problem with array of delegates!

2011-06-19 Thread Lloyd Dupont
There is a remove() method in std.algorithm!I even got asked why I was 
reimplementing it!

(well, because I didn't know it existed hey!)

works fine with, say, int...

but not with delegate!

associative array will solve the problem indeed.. (I hope) but they use way 
more memory!

it would be nice to have remove working() :)


Further, as you can see in my post, even my (reasonable) implementation of 
removeAt() fail! :(

(but, again, it works for int!)




"Andrej Mitrovic"  wrote in message 
news:mailman.1010.1308495216.14074.digitalmars-d-le...@puremagic.com...


Remove takes an offset, not a value as far as I know.

If you need fast lookup and removal you could use hashes instead:

int main(string[] argv)
{
   auto a = new A;
   SlotDelegate x = &a.DIT;

   bool[SlotDelegate] _slotDg;
   _slotDg.remove(x);

   return 0;
} 



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

2016-12-01 Thread Payotz via Digitalmars-d-learn
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. 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);

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.


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?


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

2016-12-01 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Dec 01, 2016 at 11:51:19PM +, Payotz via Digitalmars-d-learn 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. 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);
> 
> 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.
> 
> 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?

This requires heavy trickery, because what you're essentially doing is
taking a compile-time construct (type-safe variadic functions) and
applying it at runtime (array elements don't know how many arguments
they will have until actually initialized at runtime). The solution is
non-obvious, but, thankfully, *possible*, 'cos D is just *that* awesome.
;-)

An example of how to do this can be found in Adam Ruppe's eventloop.d
module, available here:

https://github.com/adamdruppe/arsd/blob/master/eventloop.d

In particular, look at the `typehash` template, the addListener() and
send() functions, and the WrappedListener interface (along with the
wrap() function). That should give you the basic idea of what's
involved. Past that, there are also some dirty implementation details
you have to work with such as getPtrPair() that performs some
compiler-dependent type-casting black magic just to tie things together.

(Alternatively, you could just use eventloop.d in your game and save
yourself the trouble of reinventing it yourself. ;-)  It has a pretty
nice API that I've used in my own projects quite successfuly.)


T

-- 
Shin: (n.) A device for finding furniture in the dark.


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

2016-12-01 Thread Ali Çehreli via Digitalmars-d-learn

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



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

2016-12-01 Thread crimaniak via Digitalmars-d-learn

On Thursday, 1 December 2016 at 23:51:19 UTC, 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. 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);


May be std.variant will help you. 
https://dlang.org/phobos/std_variant.html
You can bring the delegates to a common interface, hiding the 
differences in std.variant


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

2016-12-01 Thread Nicholas Wilson via Digitalmars-d-learn

On Thursday, 1 December 2016 at 23:51:19 UTC, 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. 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);



You could do what pthread does in C to achieve similar goals.

void delegate(void*); // or int delegate(void*) if you want 
to return an error code

and then store the void pointer along with the delegate
and then cast the void* to the correct type (a struct of 
arguments or similar) and call it later. not very safe but there 
are ways to make it nicer.


However if the set of types of events is closed you can use

ailas event = Algebraic!(ev1,ev2,ev3...);

where ev1 and so on are structs that hold parameters of the event.
and have

void delegate(event);

This is effectively how SDL does events.

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.


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?


You get an error here because you are trying to have an 
associative array of templates. if they were all void 
delegate(int)'s that would work. You can't use an uninstantiated 
template as a type.




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

2016-12-01 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 1 December 2016 at 23:51:19 UTC, Payotz wrote:

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. 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);


Off the top of my head, you should be able to do something like 
this:


void registerEvent(string event_name, T, Args...)(T 
delegate(Args) dg) {}





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.


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?


This isn't going to work because you can't have an array of mixed 
types. Something like `KyeEvent delegate() dg` and `MouseEvent 
delegate() dg` are distinct types, so they can't be stored in the 
same array.


Since you say the delegates have different parameters, the only 
option I'm aware of to store them is to use either the Variant or 
Algebraic type in std.variant. If only the return type differed, 
there would be other options. And I don't know what you're doing 
with that event_name template parameter. But anyway, checkout 
std.variant.


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

2016-12-01 Thread Payotz via Digitalmars-d-learn
Thank you all for the replies. I'm extremely grateful. I'll look 
into each and every answer.