Thread overview
Signals and slots ready for evaluation.
Sep 17, 2004
Bastiaan Veelo
Sep 17, 2004
Sean Kelly
Sep 17, 2004
Bastiaan Veelo
Sep 17, 2004
Bastiaan Veelo
Sep 17, 2004
Sean Kelly
September 17, 2004
As promised back in April, http://www.digitalmars.com/drn-bin/wwwnews?D/28471, I just gave a first shot at implementing a small framework for managed signals and slots in D, and I am looking forward to comments. Have a look at http://svn.dsource.org/svn/projects/dcouple/trunk/managed/doc/index.html and maybe grab the sources at http://dsource.org/projects/dcouple/.

The syntax of signals and especially of slots is slightly more verbose than the equivalent in Qt, but, on the other hand, connecting them actually looks a bit nicer than in Qt. This may not be too bad, as signals and slots are probably connected more often than they are defined.

Check it out :-)

Bastiaan.
September 17, 2004
Bastiaan Veelo wrote:
> As promised back in April, http://www.digitalmars.com/drn-bin/wwwnews?D/28471, I just gave a first shot at implementing a small framework for managed signals and slots in D, and I am looking forward to comments. Have a look at http://svn.dsource.org/svn/projects/dcouple/trunk/managed/doc/index.html and maybe grab the sources at http://dsource.org/projects/dcouple/.

Just a few quick comments (more once I find some time to play with this)... can you use abstract classes instead of interfaces?  Or are both broken for your purposes?  Also, a production implementation may want to take multithreading into consideration (though I couldn't say how without a longer look at the source code).

All in all this seems quite cool though.  I've always used proxy objects for this purpose, and the signal/slot mechanism seems a bit more flexible.


Sean
September 17, 2004
Sean Kelly wrote:
> 
> Just a few quick comments (more once I find some time to play with this)... can you use abstract classes instead of interfaces?  Or are both broken for your purposes?

I have a hard time looking for documentation of the abstract attribute. I guess it helps forcing a user to provide an implementation, i.e, override member functions in SignalSlotManager with an implementation. In that case, I should use it in SignalSlotManager.

What I actually want is multiple inheritance. The managing code can be split into SignalManager and SlotManager for classes that have only signals or only slots. Classes that have both should inherit both. This can only be done with interfaces, AFAIK. An abstract class would require the Manager to be at the top of the inheritance tree, which is a tough requirement to put on users. Using interfaces and mixing in the implementation of managing code makes it possible to equip any existing class with signals and/or slots by deriving from it, plus from one or two interfaces.

So I hope interfaces get fixed soon so I can just use them and toss SignalSlotManager.

I am not sure one would always want the owning class to manage its signals and slots. The most important managing code is in the signals and slots themselves. The only reason why I made it a requirement now is  to allow more RTTI than D currently provides. Currently, that information is only used in the warning message produced by the free connect() function, when it is called with incompatible arguments. An implementation of a Qt Designer equivalent would also need it. And I use it to implement a discard() method for owning classes, that cuts all connections (see the example).

There may be cases where you do not need discarding functionality and are not interested in the benefits of RTTI. Therefore, future versions of dcouple may be split into two levels, with and without managing owners.

>  Also, a production implementation may want to take multithreading into consideration (though I couldn't say how without a longer look at the source code).

Of course, I need to dive into that at some point. It will be my debute with multi-threading. I know that Qt as well has some restrictions on how you can use signals and slots in different threads, but Trolltech claims they can tackle slots that get deleted while a signal is emitting. I have not looked at any of their internal code yet, and they have the benefit of a pre-processor and meta object compiler.

> All in all this seems quite cool though.  I've always used proxy objects for this purpose, and the signal/slot mechanism seems a bit more flexible.

Nice to hear :-) For me it is a fun way to learn D. So far I am enjoying myself, although I have used a fair amount of time struggling with the interfaces bug.


Bastiaan.
September 17, 2004
Bastiaan Veelo wrote:
> Sean Kelly wrote:
> 
>>
>> Just a few quick comments (more once I find some time to play with this)... can you use abstract classes instead of interfaces?  Or are both broken for your purposes?
> 
> 
> I have a hard time looking for documentation of the abstract attribute. I guess it helps forcing a user to provide an implementation, i.e, override member functions in SignalSlotManager with an implementation. In that case, I should use it in SignalSlotManager.

This is now in the repository.

Bastiaan.
September 17, 2004
In article <cieepi$10vt$1@digitaldaemon.com>, Bastiaan Veelo says...
>
>>  Also, a production implementation may
>> want to take multithreading into consideration (though I couldn't say
>> how without a longer look at the source code).
>
>Of course, I need to dive into that at some point. It will be my debute with multi-threading. I know that Qt as well has some restrictions on how you can use signals and slots in different threads, but Trolltech claims they can tackle slots that get deleted while a signal is emitting. I have not looked at any of their internal code yet, and they have the benefit of a pre-processor and meta object compiler.

The most obvious way I can think of would be to use a counter.  Have a signal increment an "in use" counter on entrance and decrement the counter on exit. The slot would first detach the object reference so no more signals could be sent and then wait for the counter to drop to zero before continuing.  You could probably use atomic CAS for everything to avoid the need for synchronization blocks (Ben has CompareAndSwap in his MinTL library).

Sean