Jump to page: 1 2
Thread overview
Suggestion: signal/slot mechanism
Sep 02, 2006
Kristian
Sep 02, 2006
Lutger
Sep 02, 2006
Kristian
Sep 02, 2006
Brad Anderson
Sep 03, 2006
Kristian
Sep 03, 2006
Bruno Medeiros
Sep 03, 2006
Juan Jose Comellas
Sep 03, 2006
Kristian
Sep 03, 2006
Lutger
Sep 04, 2006
Bruno Medeiros
Sep 04, 2006
Kristian
Sep 06, 2006
Lutger
Sep 07, 2006
Kristian
Sep 07, 2006
Lutger
Sep 07, 2006
Serg Kovrov
Sep 04, 2006
Agent Orange
September 02, 2006
It would be nice if D had a signal/slot mechanism similiar to Qt:
http://doc.trolltech.com/4.1/signalsandslots.html

It's an elegant way to handle messages sent between objects. It beats event table declarations used by other GUI libraries IMHO.

It would make D a lot more appealing language to write GUI applications. Think of wxWidgets written in D... ;)


I think it would be quite simple to build a S/S support for a compiler (at first glance, at least). For example:

The 'Object' class has a pointer to S/S data (it's null if the object don't currently use signals/slots). S/S data holds a slot list for each signal. It also holds a list of objects that have slot(s) connected to this object's signal(s). This list is used to disconnect necessary slots at a destruction of the object.

When the compiler reads a 'emit X' statement, it will do two things. First, it generates an id for the signal which is used to retrieve a correct slot list.

Second, the compiler puts the signal's parameters to the stack as it would call a corresponding function. Instead, the 'Object._emit_signal(id)' function (or something) is called, where 'id' is the generated id. (Note that there are no function bodies for signals.) '_emit_signal()' retrieves the correct slot list, and calls all the slots (delegates) in it. Finally the parameters are removed from the stack.

Of course, slots should not modify their parameters so that all the slots will receive the same parameter values. Hence slots should not use the 'out type'. There is a market for a 'const type' here... *wink*


Maybe there should be no slot keyword at all as there is in Qt. You don't need to declare a function to be a slot; all the (virtual) functions can be used with signals.

Because the return values of all the signals are void, the void typeword could be removed from signal declarations.

signal clicked();

signals:
clicked();
clicked(int button);


BTW, Qt generates ids for signals as follows:

signals:
void clicked(int button, bool isMoved);
-> the id is a string "clicked(int,bool)"
September 02, 2006
Kristian wrote:
> It would be nice if D had a signal/slot mechanism similiar to Qt:
> http://doc.trolltech.com/4.1/signalsandslots.html
> 
> It's an elegant way to handle messages sent between objects. It beats event table declarations used by other GUI libraries IMHO.
> 
> It would make D a lot more appealing language to write GUI applications. Think of wxWidgets written in D... ;)
> 
> 
> I think it would be quite simple to build a S/S support for a compiler (at first glance, at least). For example:
> 
> The 'Object' class has a pointer to S/S data (it's null if the object don't currently use signals/slots). S/S data holds a slot list for each signal. It also holds a list of objects that have slot(s) connected to this object's signal(s). This list is used to disconnect necessary slots at a destruction of the object.
> 
> When the compiler reads a 'emit X' statement, it will do two things. First, it generates an id for the signal which is used to retrieve a correct slot list.
> 
> Second, the compiler puts the signal's parameters to the stack as it would call a corresponding function. Instead, the 'Object._emit_signal(id)' function (or something) is called, where 'id' is the generated id. (Note that there are no function bodies for signals.) '_emit_signal()' retrieves the correct slot list, and calls all the slots (delegates) in it. Finally the parameters are removed from the stack.
> 
> Of course, slots should not modify their parameters so that all the slots will receive the same parameter values. Hence slots should not use the 'out type'. There is a market for a 'const type' here... *wink*
> 
> 
> Maybe there should be no slot keyword at all as there is in Qt. You don't need to declare a function to be a slot; all the (virtual) functions can be used with signals.
> 
> Because the return values of all the signals are void, the void typeword could be removed from signal declarations.
> 
> signal clicked();
> 
> signals:
> clicked();
> clicked(int button);
> 
> 
> BTW, Qt generates ids for signals as follows:
> 
> signals:
> void clicked(int button, bool isMoved);
> -> the id is a string "clicked(int,bool)"

I agree the signal-slot mechanism is nice, but why must it be supported by a compiler? There a lots of good libraries in C++ for this, such as sigslots, libsigc++ and boost::signals. It is not necessary to have extra preprocessor or language support.

It should be possible to do this in a D library. There already is dcouple at dsource, but it is inactive. I have been working on a signal-slot module myself, the only thing missing now is automatic disconnections of which I am not sure how and if to proceed.
September 02, 2006
On Sat, 02 Sep 2006 14:20:22 +0300, Lutger <lutger.blijdestijn@gmail.com> wrote:
> Kristian wrote:
>> It would be nice if D had a signal/slot mechanism similiar to Qt:
>> http://doc.trolltech.com/4.1/signalsandslots.html
>>  It's an elegant way to handle messages sent between objects. It beats event table declarations used by other GUI libraries IMHO.
>>  It would make D a lot more appealing language to write GUI applications. Think of wxWidgets written in D... ;)
[snip]
>
> I agree the signal-slot mechanism is nice, but why must it be supported by a compiler? There a lots of good libraries in C++ for this, such as sigslots, libsigc++ and boost::signals. It is not necessary to have extra preprocessor or language support.
>
> It should be possible to do this in a D library. There already is dcouple at dsource, but it is inactive. I have been working on a signal-slot module myself, the only thing missing now is automatic disconnections of which I am not sure how and if to proceed.


Well, one could ask if it's possible to implement a signal/slot mechanism by using a library (or by doing it by yourself), then why none of the GUI libraries I'm familiar with do not use it? (Qt uses preprocessor.)


There are several general reasons for a feature being directly supported:

- If a feature is supported by a language, programmers will use it a lot more often. Actually it almost certainly guarantees that a feature will be used.

- Syntax sugar. Being the part of a language, the syntax is consistent with the rest of the statements. This makes the feature (usually) simplier and easier to use. At least overall readability is better.

- Compile time errors could be more informative.

- If there is a compiler for a operating system, then the feature is automatically supported in that system, of course.

- You can rely on the feature being bug free. (You can make that assumption.)


And of course, the S/S mechanism wouldn't look bad at the feature list of D. ;)
September 02, 2006
Kristian wrote:
> It would be nice if D had a signal/slot mechanism similiar to Qt: http://doc.trolltech.com/4.1/signalsandslots.html
> 
> It's an elegant way to handle messages sent between objects. It beats event table declarations used by other GUI libraries IMHO.
> 
> It would make D a lot more appealing language to write GUI applications. Think of wxWidgets written in D... ;)
> 
> 
> I think it would be quite simple to build a S/S support for a compiler (at first glance, at least). For example:
> 
> The 'Object' class has a pointer to S/S data (it's null if the object don't currently use signals/slots). S/S data holds a slot list for each signal. It also holds a list of objects that have slot(s) connected to this object's signal(s). This list is used to disconnect necessary slots at a destruction of the object.
> 
> When the compiler reads a 'emit X' statement, it will do two things. First, it generates an id for the signal which is used to retrieve a correct slot list.
> 
> Second, the compiler puts the signal's parameters to the stack as it
> would call a corresponding function. Instead, the
> 'Object._emit_signal(id)' function (or something) is called, where 'id'
> is the generated id. (Note that there are no function bodies for
> signals.) '_emit_signal()' retrieves the correct slot list, and calls
> all the slots (delegates) in it. Finally the parameters are removed from
> the stack.
> 
> Of course, slots should not modify their parameters so that all the slots will receive the same parameter values. Hence slots should not use the 'out type'. There is a market for a 'const type' here... *wink*
> 
> 
> Maybe there should be no slot keyword at all as there is in Qt. You don't need to declare a function to be a slot; all the (virtual) functions can be used with signals.
> 
> Because the return values of all the signals are void, the void typeword could be removed from signal declarations.
> 
> signal clicked();
> 
> signals:
> clicked();
> clicked(int button);
> 
> 
> BTW, Qt generates ids for signals as follows:
> 
> signals:
> void clicked(int button, bool isMoved);
> -> the id is a string "clicked(int,bool)"

Not terribly active recently, but the SVN repos here may have some stuff for you.

http://svn.dsource.org/projects/dcouple/

BA
September 03, 2006
Kristian wrote:
> It would be nice if D had a signal/slot mechanism similiar to Qt:
> http://doc.trolltech.com/4.1/signalsandslots.html
> 
> It's an elegant way to handle messages sent between objects. It beats event table declarations used by other GUI libraries IMHO.
> 
> It would make D a lot more appealing language to write GUI applications. Think of wxWidgets written in D... ;)
> 
> 
> I think it would be quite simple to build a S/S support for a compiler (at first glance, at least). For example:
> 
> The 'Object' class has a pointer to S/S data (it's null if the object don't currently use signals/slots). S/S data holds a slot list for each signal. It also holds a list of objects that have slot(s) connected to this object's signal(s). This list is used to disconnect necessary slots at a destruction of the object.
> 
> When the compiler reads a 'emit X' statement, it will do two things. First, it generates an id for the signal which is used to retrieve a correct slot list.
> 
> Second, the compiler puts the signal's parameters to the stack as it would call a corresponding function. Instead, the 'Object._emit_signal(id)' function (or something) is called, where 'id' is the generated id. (Note that there are no function bodies for signals.) '_emit_signal()' retrieves the correct slot list, and calls all the slots (delegates) in it. Finally the parameters are removed from the stack.
> 
> Of course, slots should not modify their parameters so that all the slots will receive the same parameter values. Hence slots should not use the 'out type'. There is a market for a 'const type' here... *wink*
> 
> 
> Maybe there should be no slot keyword at all as there is in Qt. You don't need to declare a function to be a slot; all the (virtual) functions can be used with signals.
> 
> Because the return values of all the signals are void, the void typeword could be removed from signal declarations.
> 
> signal clicked();
> 
> signals:
> clicked();
> clicked(int button);
> 
> 
> BTW, Qt generates ids for signals as follows:
> 
> signals:
> void clicked(int button, bool isMoved);
> -> the id is a string "clicked(int,bool)"

The Signal and slots pattern is little more than an abstraction for languages that do not support delegates (and dynamic arrays). Which is not the case for D:

  // Declare a signal:
  void delegate(Button, int)[] someSignal;

  // Connect a slot to a signal:
  someSignal ~= foo.someSlot;

  // emit the signal
  foreach(dg; someSignal)
    dg(myButton, myInt);

The only limitation I see with D so far, is on the emit part. You can't create an emit function that works like this:
  emit(someSignal, myButton, myInt);
and that would do the same as that foreach. Because you cannot do "parameterized"(whether compile time or runtime) function calls.

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
September 03, 2006
Bruno Medeiros wrote:
> The Signal and slots pattern is little more than an abstraction for languages that do not support delegates (and dynamic arrays). Which is not the case for D:
> 
>    // Declare a signal:
>    void delegate(Button, int)[] someSignal;
> 
>    // Connect a slot to a signal:
>    someSignal ~= foo.someSlot;
> 
>    // emit the signal
>    foreach(dg; someSignal)
>      dg(myButton, myInt);
> 
> The only limitation I see with D so far, is on the emit part. You can't
> create an emit function that works like this:
>    emit(someSignal, myButton, myInt);
> and that would do the same as that foreach. Because you cannot do
> "parameterized"(whether compile time or runtime) function calls.
> 

This problem is usually solved by creating a template signal class per number of parameters that it can allow (i.e. the arity of the signal). You'd have something like:

template Signal0() { ... }
template Signal1(T1) { ... }
template Signal2(T1, T2) { ... }
template Signal3(T1, T2, T3) { ... }
...

This is the solution used by libsigc++, boost, Qt Jambi, etc.


September 03, 2006
On Sun, 03 Sep 2006 01:41:55 +0300, Brad Anderson <brad@dsource.org> wrote:
> Kristian wrote:
>> It would be nice if D had a signal/slot mechanism similiar to Qt:
>> http://doc.trolltech.com/4.1/signalsandslots.html
>>
>> It's an elegant way to handle messages sent between objects. It beats
>> event table declarations used by other GUI libraries IMHO.
>>
>> It would make D a lot more appealing language to write GUI applications.
>> Think of wxWidgets written in D... ;)
>>
>>
>> I think it would be quite simple to build a S/S support for a compiler
>> (at first glance, at least). For example:
>>
>> The 'Object' class has a pointer to S/S data (it's null if the object
>> don't currently use signals/slots). S/S data holds a slot list for each
>> signal. It also holds a list of objects that have slot(s) connected to
>> this object's signal(s). This list is used to disconnect necessary slots
>> at a destruction of the object.
>>
>> When the compiler reads a 'emit X' statement, it will do two things.
>> First, it generates an id for the signal which is used to retrieve a
>> correct slot list.
>>
>> Second, the compiler puts the signal's parameters to the stack as it
>> would call a corresponding function. Instead, the
>> 'Object._emit_signal(id)' function (or something) is called, where 'id'
>> is the generated id. (Note that there are no function bodies for
>> signals.) '_emit_signal()' retrieves the correct slot list, and calls
>> all the slots (delegates) in it. Finally the parameters are removed from
>> the stack.
>>
>> Of course, slots should not modify their parameters so that all the
>> slots will receive the same parameter values. Hence slots should not use
>> the 'out type'. There is a market for a 'const type' here... *wink*
>>
>>
>> Maybe there should be no slot keyword at all as there is in Qt. You
>> don't need to declare a function to be a slot; all the (virtual)
>> functions can be used with signals.
>>
>> Because the return values of all the signals are void, the void typeword
>> could be removed from signal declarations.
>>
>> signal clicked();
>>
>> signals:
>> clicked();
>> clicked(int button);
>>
>>
>> BTW, Qt generates ids for signals as follows:
>>
>> signals:
>> void clicked(int button, bool isMoved);
>> -> the id is a string "clicked(int,bool)"
>
> Not terribly active recently, but the SVN repos here may have some stuff for you.
>
> http://svn.dsource.org/projects/dcouple/
>
> BA


Thanks. I like dcouple's syntax. (There seem to be some problems with GC and object deletion currently though.) Being a library, you have to create signal and slot objects in constructors, which is a downside (when compared against S/S mechanism build into D).
September 03, 2006
On Sun, 03 Sep 2006 13:01:28 +0300, Bruno Medeiros <brunodomedeiros+spam@com.gmail> wrote:
> Kristian wrote:
>> It would be nice if D had a signal/slot mechanism similiar to Qt:
>> http://doc.trolltech.com/4.1/signalsandslots.html
>>  It's an elegant way to handle messages sent between objects. It beats event table declarations used by other GUI libraries IMHO.
>>  It would make D a lot more appealing language to write GUI applications. Think of wxWidgets written in D... ;)
>>   I think it would be quite simple to build a S/S support for a compiler (at first glance, at least). For example:
>>  The 'Object' class has a pointer to S/S data (it's null if the object don't currently use signals/slots). S/S data holds a slot list for each signal. It also holds a list of objects that have slot(s) connected to this object's signal(s). This list is used to disconnect necessary slots at a destruction of the object.
>>  When the compiler reads a 'emit X' statement, it will do two things. First, it generates an id for the signal which is used to retrieve a correct slot list.
>>  Second, the compiler puts the signal's parameters to the stack as it would call a corresponding function. Instead, the 'Object._emit_signal(id)' function (or something) is called, where 'id' is the generated id. (Note that there are no function bodies for signals.) '_emit_signal()' retrieves the correct slot list, and calls all the slots (delegates) in it. Finally the parameters are removed from the stack.
>>  Of course, slots should not modify their parameters so that all the slots will receive the same parameter values. Hence slots should not use the 'out type'. There is a market for a 'const type' here... *wink*
>>   Maybe there should be no slot keyword at all as there is in Qt. You don't need to declare a function to be a slot; all the (virtual) functions can be used with signals.
>>  Because the return values of all the signals are void, the void typeword could be removed from signal declarations.
>>  signal clicked();
>>  signals:
>> clicked();
>> clicked(int button);
>>   BTW, Qt generates ids for signals as follows:
>>  signals:
>> void clicked(int button, bool isMoved);
>> -> the id is a string "clicked(int,bool)"
>
> The Signal and slots pattern is little more than an abstraction for languages that do not support delegates (and dynamic arrays). Which is not the case for D:
>
>    // Declare a signal:
>    void delegate(Button, int)[] someSignal;
>
>    // Connect a slot to a signal:
>    someSignal ~= foo.someSlot;
>
>    // emit the signal
>    foreach(dg; someSignal)
>      dg(myButton, myInt);
>
> The only limitation I see with D so far, is on the emit part. You can't create an emit function that works like this:
>    emit(someSignal, myButton, myInt);
> and that would do the same as that foreach. Because you cannot do "parameterized"(whether compile time or runtime) function calls.
>

Automatic S/S disconnection at object destructions should also be implemented, usually, which requires the use of a base class.

I think everybody will agree if I say that the optimal solution would be D supporting S/S mechanism directly.

It would make using of signals/slots as easy as calling of functions, for instance. But if Walter (and D community) thinks that the S/S mechanism is not important enough to be added to D specs (ever), then Phobos should have a S/S library (in the future). It would make implementation of classes having signals/slots more tedious though. Fortunately using of such classes would be as easy (I looked at some examples of dcouple).
September 03, 2006
Kristian wrote:
<snip>
> 
> Automatic S/S disconnection at object destructions should also be implemented, usually, which requires the use of a base class.
> 
> I think everybody will agree if I say that the optimal solution would be D supporting S/S mechanism directly.
> 
> It would make using of signals/slots as easy as calling of functions, for instance. But if Walter (and D community) thinks that the S/S mechanism is not important enough to be added to D specs (ever), then Phobos should have a S/S library (in the future). It would make implementation of classes having signals/slots more tedious though. Fortunately using of such classes would be as easy (I looked at some examples of dcouple).

I think there are benefits / downsides to both options of language and library implementation. Personally I favor a library option, and if it would be included in some (de facto or official) standard library that would be good indeed.

In C++ the existing library solutions are very nice and prove that a preprocessor like QT uses is not needed at all. I think it can be done in D even better, because of delegate support and template features.

The benefit of a library solution is less language bloat, more flexible   and possible competition. Some libraries also perhaps don't want to use the signal-slot mechanism, like harmonia which prefers to use sinking-bubbling.

It's not that it's not important enough, it's more that it fits better in a library for a language like D imho.
September 04, 2006

Kristian wrote:
> It would be nice if D had a signal/slot mechanism similiar to Qt:
> http://doc.trolltech.com/4.1/signalsandslots.html
> 
> It's an elegant way to handle messages sent between objects. It beats  event table declarations used by other GUI libraries IMHO.
> 
> It would make D a lot more appealing language to write GUI applications.  Think of wxWidgets written in D... ;)
> 
> 
> I think it would be quite simple to build a S/S support for a compiler (at  first glance, at least). For example:
> 
> The 'Object' class has a pointer to S/S data (it's null if the object  don't currently use signals/slots). S/S data holds a slot list for each  signal. It also holds a list of objects that have slot(s) connected to  this object's signal(s). This list is used to disconnect necessary slots  at a destruction of the object.
> 
> When the compiler reads a 'emit X' statement, it will do two things.  First, it generates an id for the signal which is used to retrieve a  correct slot list.
> 
> Second, the compiler puts the signal's parameters to the stack as it would  call a corresponding function. Instead, the 'Object._emit_signal(id)'  function (or something) is called, where 'id' is the generated id. (Note  that there are no function bodies for signals.) '_emit_signal()' retrieves  the correct slot list, and calls all the slots (delegates) in it. Finally  the parameters are removed from the stack.
> 
> Of course, slots should not modify their parameters so that all the slots  will receive the same parameter values. Hence slots should not use the  'out type'. There is a market for a 'const type' here... *wink*
> 
> 
> Maybe there should be no slot keyword at all as there is in Qt. You don't  need to declare a function to be a slot; all the (virtual) functions can  be used with signals.
> 
> Because the return values of all the signals are void, the void typeword  could be removed from signal declarations.
> 
> signal clicked();
> 
> signals:
> clicked();
> clicked(int button);
> 
> 
> BTW, Qt generates ids for signals as follows:
> 
> signals:
> void clicked(int button, bool isMoved);
> -> the id is a string "clicked(int,bool)"


This is a great idea. Trolltech really has created a new style of event based programming. Its especially useful for IU systems. The signal slot pattern is a generalized observer pattern with late binding. The signals are fired at potential observers and resolved via string identifier at runtime; this allows a great deal of tool-code integration. signal slot libraries tend to be a hastle because the observers have to disconnect from their signals on destruction - you cant fire a signal at a dead object, but Qts moc makes takes care of all of that incredibly well. in qt signals and slots are like first class language constructs, and it becomes less of a hastle and more of an amazingly usefull tool. D would be just absolutely incredible if it supported signals and slots, or even just the observer pattern - perhaps something in phobos that hooks into object destruction.... another option is to create a tool such as trolltechs moc but even then you would have to require users to link a library or something; or would be nice to see this attached to something like ares. signals and slots give you anonymous typesafe callbacks that allow a whole new level of object oriented abstraction that most people unfortunately cant fully understand until they use them. walter has said before he doesnt quite know what signals and slots are. I recently used Qt on a project and I immediately fell in love with them similarly to the way I fell for D. A mariage of the two could possibly create an incredible new style of programming.
« First   ‹ Prev
1 2