April 25, 2004
Colin JN Breame wrote:

>Seconded - this is exactly how it should work.  Any idea how we can get Walter
>to take a look at this proposal?
>  
>

Put something up on http://www.prowiki.org/wiki4d/wiki.cgi?FeatureRequestList.

-- 
-Anderson: http://badmama.com.au/~anderson/
April 25, 2004
> >
> I think signals and slots could be implemented neatly in a library if some language support was provided for removing delegates that reference objects that no-longer exist.
>

There is also the problem of names: it is ugly to have signal0, signal1, signal2 etc.



April 25, 2004
Achilleas Margaritis wrote:

>> >
>> I think signals and slots could be implemented neatly in a library if some language support was provided for removing delegates that reference objects that no-longer exist.
>>
> 
> There is also the problem of names: it is ugly to have signal0, signal1, signal2 etc.

That's not a problem in D: you can have templates with different number of parameters but the same name, and even templates with zero arguments. (A non-templated class would clash with the name of a template, but a zero-parameter class can have the same name as a one-parameter class)
April 25, 2004
> That's not a problem in D: you can have templates with different number of parameters but the same name, and even templates with zero arguments. (A non-templated class would clash with the name of a template, but a zero-parameter class can have the same name as a one-parameter class)

D is even cooler than I thought. :-)

Anyway, a signals and slots mechanism not supported by the language also has other problems:

1) one has to cater for the different number of parameters. Libsig++ has 20 template signals, all doing the same thing.

2) objects should inherit from a specific class that knows about how to get rid of slots when deleted. If they don't inherit from the class, they can't be connected to slots.

3) specifically for garbage collected languages, object pointers in slots must not be garbage collected; otherwise, the GC will never delete the objects, unless the slots are explicitely removed from their signals, which is not desired.



April 25, 2004
Achilleas Margaritis wrote:

>> That's not a problem in D: you can have templates with different number of parameters but the same name, and even templates with zero arguments. (A non-templated class would clash with the name of a template, but a zero-parameter class can have the same name as a one-parameter class)
> 
> D is even cooler than I thought. :-)
> 
> Anyway, a signals and slots mechanism not supported by the language also has other problems:
> 
> 1) one has to cater for the different number of parameters. Libsig++ has 20 template signals, all doing the same thing.

Yes, true, we need to copy/paste for every number of arguments. I doubt, 20 would be necessary, though...

> 2) objects should inherit from a specific class that knows about how to get rid of slots when deleted. If they don't inherit from the class, they can't be connected to slots.

True, lacking multiple inheritance, you have to put that code right into the base of any class hierarchy you build. Alternatively, you can use an interface that slot-aware objects have to implement to get auto-disconnection. Not too much of a problem: you would put that code way up in the hierarchy of any library anyway.

> 3) specifically for garbage collected languages, object pointers in slots must not be garbage collected; otherwise, the GC will never delete the objects, unless the slots are explicitely removed from their signals, which is not desired.

True, from the GC point of view, signal-slot-connections should be handled as one-way pointers, even if the implementation needs pointers in both directions to enable auto-disconnection. Maybe there should be a way to specify pointers that should not be traversed, when the garbage collector marks life objects?
October 20, 2005
Well this thread is kind of old, but I'm somewhat interested in this signal/slot, event/delegate thing and I happened to find this article on C# events (which are delegates with a few special constranints/feautures): http://blog.monstuff.com/archives/000040.html

And here is a simple use of events for non-gui use (a metranome): http://www.codeproject.com/csharp/SimplestEventExample.asp

I've read that this kind of thing can be done in D, so what would be a simple way to do this in D (I'm still kind of new to D)?

Thanks,
Lucas


February 09, 2006
lgoss007@yahoo.com wrote:
> Well this thread is kind of old, but I'm somewhat interested in this
> signal/slot, event/delegate thing and I happened to find this article on C#
> events (which are delegates with a few special constranints/feautures):
> http://blog.monstuff.com/archives/000040.html
> 
> And here is a simple use of events for non-gui use (a metranome):
> http://www.codeproject.com/csharp/SimplestEventExample.asp
> 
> I've read that this kind of thing can be done in D, so what would be a simple
> way to do this in D (I'm still kind of new to D)?
> 
> Thanks,
> Lucas
> 
> 

Start here:

http://www.digitalmars.com/d/type.html#delegates

search for the word delegate in this page for some examples:
http://www.digitalmars.com/d/expression.html

also on this page:
http://www.digitalmars.com/d/statement.html

and just try it things with DMD until it works.
Goodluck
July 17, 2006
Like this

Module ss.d

typedef void delegate(...)  SIGNAL;
typedef void delegate(...)  SLOT;

struct SIGNAL_SLOT
{
SIGNAL _in;
SLOT _out;
}

struct SIGNAL_SIGNAL
{
SIGNAL _in;
SIGNAL _out;
}

extern (D) SIGNAL_SLOT[int] signal_slot;
extern (D) SIGNAL_SIGNAL[int] signal_signal;


static class SS
{
//**************************************************************************
static void connect(SIGNAL _in, SLOT _out)
{
int index = -1;
int keys[] = signal_slot.keys;

foreach (int key; keys)
{
if (signal_slot[key]._in==_in && signal_slot[key]._out==_out )
{
index = key;
break;
}
}

if (index==-1)
{
SIGNAL_SLOT tmp;
tmp._in = _in;
tmp._out = _out;
signal_slot[signal_slot.length+1] = tmp;
}

}


//**************************************************************************
static void connect2(SIGNAL _in, SIGNAL _out)
{
if (_in==_out){return;}

int index = -1;
int keys[] = signal_signal.keys;

foreach (int key; keys)
{
if (signal_signal[key]._in==_in && signal_signal[key]._out==_out )
{
index = key;
break;
}
}

if (index==-1)
{
SIGNAL_SIGNAL tmp;
tmp._in = _in;
tmp._out = _out;
signal_signal[signal_signal.length+1] = tmp;
}
}


//**************************************************************************
static void disconnect(SIGNAL _in, SLOT _out)
{
int keys[] = signal_slot.keys;

foreach (int key; keys)
{
if (signal_slot[key]._in==_in && signal_slot[key]._out==_out )
{
signal_slot.remove(key);
break;
}
}
}

//**************************************************************************
static void disconnect2(SIGNAL _in, SIGNAL _out)
{
int keys[] = signal_signal.keys;

foreach (int key; keys)
{
if (signal_signal[key]._in==_in && signal_signal[key]._out==_out )
{
signal_signal.remove(key);
break;
}
}
}


//**************************************************************************
static void signal(SIGNAL _in, void *_argptr, TypeInfo[] _arguments)
{
int keys[] = signal_slot.keys;
foreach (int key; keys)
{
if (signal_slot[key]._in==_in )
{
signal_slot[key]._out(_argptr,_arguments);
}
}

int keys2[] = signal_signal.keys;
foreach (int key; keys2)
{
if (signal_signal[key]._in==_in )
{
//signal_signal[key]._out(_argptr,_arguments);
}
}
}


}



How use

import ss;


class test
{
this(){}
~this(){}


void signal(...)
{
printf("signal\n");
SS.signal(&this.signal,_argptr,_arguments);

}

void signal2(...)
{
printf("signal2\n");
SS.signal(&this.signal2,_argptr,_arguments);
}



void slot(...)
{
printf("slot\n");
}

void slot2(...)
{
printf("slot2\n");
}
}


void f(int f)
{
test t = new test();

SS.connect(&t.signal, &t.slot);
SS.connect(&t.signal2, &t.slot2);
SS.connect(&t.signal, &t.signal2);
t.signal();

delete t;
}




1 2 3 4
Next ›   Last »