CsSignal can only connect to references?!

Discuss anything related to product development
Post Reply
bankai
Posts: 6
Joined: Sun Jun 26 2022 2:44 pm

CsSignal can only connect to references?!

Post by bankai »

I am converting some code to CsSignal,which seems rather straightforward: derive classes from CsSignal::SignalBase and CsSignal::SignalSlot, replace existing connections (which already use &Class::member pointers) with connect(). Of course we use pointers, but CsSignal does not support them, only references??

This is the old code:

Code: Select all

channel->LogEvent.connect (this, &Export::channelEvent);
I expect that code to convert to:

Code: Select all

connect (channel, &Channel::LogEvent, this, &Export::channelEvent);
But this fails with the following compiler message (Visual Studio 2022):

Code: Select all

C2338: static_assert failed: 'connect():  Signal was not a child class of Sender'
C2338: static_assert failed: 'connect():  Slot was not a child class of Receiver'
C2530: 'item': references must be initialized
C3531: 'item': a symbol whose type contains 'auto' must have an initializer
C2143: syntax error: missing ';' before ':'
C3536: 'senderListHandle': cannot be used before it is initialized
C2100: illegal indirection
C2143: syntax error: missing ';' before ')'
The only way to get it compiled is by dereferencing the pointers:

Code: Select all

connect (*channel, &Channel::LogEvent, *this, &Export::channelEvent);
I looked at the code in cs_signal.h and there does not seem to be any code that connects pointers of objects, only references. Why? 99.99% of our code deals with pointers. Sure I can add the '*' but that just looks, for lack of a better word, ugly. For the sender object I might concur, but '*this'? [1]

Before I continue with the conversion I would like know a bit more about the reasoning behind this design.


[1] I know *this will work,I just have never been forced to use it this way.
barbara
Posts: 446
Joined: Sat Apr 04 2015 2:32 am
Contact:

Re: CsSignal can only connect to references?!

Post by barbara »

I am converting some code to CsSignal
What are you converting from? Using the CsSignal library is definitely an option however we are curious if it would make more sense for you to use the CsCore library in CopperSpice.
I looked at the code in cs_signal.h and there does not seem to be any code that connects pointers of objects, only references
There are design considerations you must consider when writing a library. Some of these may not be obvious at first glance. There are slight differences in the API for CsSignal versus CopperSpice.

For example, in CS you can call disconnect() and pass a nullptr for the Receiver. This has the effect of disconnecting every Slot for the given Signal. With connect() the first four parameter are required to be valid and none of these pointers can be null. This requires a runtime verification.

For a lower level library like CsSignal it is not appropriate to weigh down the code with runtime checks. In order prevent the first and third parameters from accidentally being a nullptr, the API design requires these to be objects.

Barbara
bankai
Posts: 6
Joined: Sun Jun 26 2022 2:44 pm

Re: CsSignal can only connect to references?!

Post by bankai »

barbara wrote: Wed Dec 07 2022 5:38 pm What are you converting from? Using the CsSignal library is definitely an option however we are curious if it would make more sense for you to use the CsCore library in CopperSpice.
Sigslot by Sarah Thompson; one of the reasons to switch to CsSignal is the ability to deliver signals to other threads. Regarding CsCore, for now we only really want the signalling; the rest of code uses a lot of the C++ std:: library and some other 3rd party libraries.
barbara wrote: Wed Dec 07 2022 5:38 pm There are design considerations you must consider when writing a library. Some of these may not be obvious at first glance. There are slight differences in the API for CsSignal versus CopperSpice.

For example, in CS you can call disconnect() and pass a nullptr for the Receiver. This has the effect of disconnecting every Slot for the given Signal. With connect() the first four parameter are required to be valid and none of these pointers can be null. This requires a runtime verification.

For a lower level library like CsSignal it is not appropriate to weigh down the code with runtime checks. In order prevent the first and third parameters from accidentally being a nullptr, the API design requires these to be objects.

Barbara
That is a valid point, but is it really that much of an overhead? It's not like I am going to connect and disconnect millions of times per second. In the end, inside CsSignal the object references are converted back to pointers (at least for the receiver), so I find the limitation to use references a bit artificial. What the behaviour for a nullpointer should be is then open for debate; personally I would just return and do nothing in CsSignal.
Post Reply