Signals and Slots in D

Fredrik Olsson peylow at gmail.com
Fri Sep 29 00:27:35 PDT 2006


Walter Bright skrev:
> Walter Bright wrote:
>> Some of the boilerplate can be eliminated with a mixin.
>  
> class Foo
> {
>     this() { }
> 
>     int value() { return val; }
> 
>     void setValue( int v )
>     {
>       if ( v != val )
>       {
>     val = v;
>     emit(v);
>       }
>     }
> 
>     mixin Signal!(int);    // adds in all the boilerplate to make it work
> 
>   private:
>     int val;
> }
> 

I like what I see. But there is a problem, a signal is hereby identified 
by it's types only. In a real world scenario many signals will have the 
same types. Bith a keyUp and a keyDown signal will probably want to send 
  a key code of the same type.

I see that as a minor problem though, it would work just as the 
target/action mechanism of Cocoa. Where the majority of UI controls have 
a single "signal". In reality a button rarely need more than "onClick", 
a text field "onChange", etc.

But still the exceptional events would need to be handled in some way, I 
would suggest going down the object delegate route just as Cocoa. A 
simple TextField could be:
interface TextFieldDelagate {
   bool shouldChange(TextField, char[]);
   void didChange(TextField);
}

And then the TextField class have a delage getter/setter of this 
interface type. If no delegate is set then the all calls are simply 
ignored, if set then the TextField will call them when appropriate.


For simplicity you do not want more than a single delegate, but if a 
control have say 10 delegate methods in it's delegate interface then you 
would not want to implement dummies for them all.

May I therefor suggest Interfaces with "optional" methods. Something 
like this:
interface TextFieldDelagate {
   optinal bool shouldChange(TextField, char[]);
   optional void didChange(TextField);
}

You would then need the ability to query the availability of an optional 
method. I guess something like this (Somewhere in the TextField class 
using the delegate interface):
void doStuff() {
   if (_delaget && _delegate.implements(void didChange(TextField))) {
     _delegate.didChange(this);
   }
}

I guess unimplemented methods would have NULL pointers in the method 
tables. So this test stage could be ignored for most cases as the 
compiler could simply skip calling the method if it gets a NULL-pointer 
when fetching the function pointer.


// Fredrik Olsson




More information about the Digitalmars-d mailing list