Subject: Re: [boost] Interest in non-intrusive signal/slot lib?
From: Edward Diener (eldiener_at_[hidden])
Date: 2015-05-18 17:36:40


On 5/18/2015 1:39 PM, Emil Dotchevski wrote:
> On Mon, May 18, 2015 at 8:42 AM, Edward Diener <eldiener_at_[hidden]>
> wrote:
>
>> On 5/18/2015 12:35 AM, Emil Dotchevski wrote:
>>
>>> On Sun, May 17, 2015 at 7:40 PM, Gavin Lambert <gavinl_at_[hidden]>
>>> wrote:
>>>
>>>> On 17/05/2015 09:35, Edward Diener wrote:
>>>>
>>>>> typedef void (*button_down)(int x, int y);
>>>>> typedef void (*button_up)(int x, int y);
>>>>>
>>>>> void handle_button_down( int x, int y );
>>>>> void handle_button_up( int x, int y );
>>>>>
>>>>> auto c1=connect<button_down>(e,&handle_button_down);
>>>>> auto c2=connect<button_up>(e,&handle_button_up);
>>>>>
>>>>> Is there some reason why the above would not work ? The fact that
>>>>> button_down and button_up are the same types above but different types
>>>>> the way synapse is currently designed seems irrelevant. I am enquiring
>>>>> whether there is an internal reason for that.
>>>>>
>>>>
>>>> I had the same confusion at first. The issue is that there is no "signal
>>>> container" instance within the emitter itself, which is how you'd
>>>> normally
>>>> distinguish between signals with the same signature.
>>>>
>>>> This library stores all signals centrally in the management object,
>>>> indexed by type, rather than having members of the emitter object (that's
>>>> the "non-intrusive" part). As a result the types need to be unique as
>>>> they're the only differentiating feature.
>>>>
>>>
>>> I now understand where the confusion comes from, too. In Boost Signals 2,
>>> a
>>> signal (emitter) is an actual object, and it is the address of that object
>>> that identifies different signals independently from their signature.
>>> Indeed, in Synapse signals are *not* objects, they're types.
>>>
>>
>> That's not where the confusion existed for me. Gavin Lambert explained why
>> each signal must be a different type. I realized that a signal is a type,
>> but not why the same signal could not be used for more than one event (
>> button down, button up etc. ).
>>
>
> The signal *is* the event though. So I guess I still don't understand. If
> you have two events, "button up" and "button down", then you need two
> Synapse signals or else you wouldn't be able to tell them apart.

Your synapse code evidently needs to tell them apart but from the
end-user's perspective it isn't necessary, since the only thing he cares
about is the parameter types being specified. If he has a signal of:

typedef void (*button_signal)(int,int) ;

why wouldn't he use it for both a button_up and a button_down event,
since it has the correct number and type of parameters for both ?

I don't mind your specifying that the above must be something like:

typedef button_up_ (*button_up)(int,int) ;
typedef button_down_ (*button_down)(int,int) ;

so that the types are distinct. But from the end-user's point of view
having each signal be a distinct type seems irrelevant.

I am not questioning your internal need for each signal to be a distinct
type, only pointing out that it isn't needed AFIACS from the end-user's
point of view.

>
> BTW you could provide a fairly simple variadic macro for creating signals
>> which might be a little easier on the end-user:
>>
>> #define SYNAPSE_SIGNAL(name,...) typedef struct name ## _
>> (*name)(__VA_ARGS__);
>>
>
> Maybe I'll add something like this, since I've had a couple of instances
> where through copy&paste I ended up with:
>
> typedef struct foo_(*foo)();
> typedef struct foo_(*bar)();

If your signal can take no parameters then the macro I proposed has to
get more clever. If that is the case I will let you work it out.

>
> BTW I don't think I'd need vaargs even.

Really ? Well if you don't want to use a variadic macro, or any macro at
all, that is up to you.

>
>
>> In your documentation I think you should explain that when you emit a
>> signal you pass a pointer to the object doing the emitting. Also when you
>> connect you are passing a shared_ptr ( or weak_ptr ) to the object doing
>> the emitting. I think I have this correct.
>>
>
> You mean more than I have already in
> http://www.revergestudios.com/boost-synapse/connect.html and
> http://www.revergestudios.com/boost-synapse/emit.html?

In the 'coonect' doc there is nothing which specifies from where
'weak_ptr<emitter const>' is supposed to come.

In the 'emit' doc there is nothing which specifies what 'signal_emitter"
is supposed to be.

There is a value to making things clear on the conceptual level rather
than relying on the details you specify elsewhere to be interpreted
correctly.