November 08, 2013
Is it reasonable to introduce new identifier _sig for each signal sig?
You could just make emit private static function,that takes signal by the first argument instead.
November 08, 2013
>
> I was referring to the issue of string mixin vs mixin template.

My bad ;-) My first implementation was using just a template mixin, but I hit a few bugs (At least 2, one should be fixed already the other one I can't remember, but had something to do with derived classes), so I tried the string mixin approach and I have to admit, that I like it more now, regardless of template mixin bugs. The added flexibility of choosing the protection is a big win as it is not that unlikely that someone wants for example derived classes being able to emit the signal.

Another minor drawback of the template mixin, is that I have to wrap all struct members into mixin functions*) and the actual struct would need to be renamed into something less straight forward too.

Best regards,
Robert

*) Without wrapping, using the signal would be more ugly, something like:

class Test {
 mixin Signal!int a;
 mixin(signal!int("b"));
 void doSomething() {
     // something
     a.signal.emit(4);
     // vs
     b.emit(4);
 }
}
November 08, 2013
On Friday, 8 November 2013 at 16:13:04 UTC, Anonimous wrote:
> Is it reasonable to introduce new identifier _sig for each signal sig?

I think so, yes. It is more or less the code one would write by hand if there were no mixin.

> You could just make emit private static function,that takes signal by the first argument instead.

I don't understand that. :-(

November 08, 2013
On 2013-11-08 11:22, Robert wrote:

> I agree that template mixin syntax is a bit nicer, but I ran into a few
> issues with them. In the end I settled with the string mixin, because it
> avoids those issues and also was more powerful (User can now choose the
> protection). How would your template mixin wrapper look like?

Just take the same arguments as the "signal" function, something like:

template signal (string name, string protection, Args...)
{
    mixin(signalImpl!(Args)(name, protection));
}

> Oh, quite the other way round, the public in the assert list is quite
> unnecessary. If you want to go public/export just use "none" as
> protection and set it yourself, like:
> public {
>       mixin(signal!(string, int)("valueChanged", "none"));
> }

If that works, why do you have the option to specify the protection at all?

BWT, shouldn't that assert be static?

-- 
/Jacob Carlborg
November 09, 2013
> Just take the same arguments as the "signal" function, something like:
>
> template signal (string name, string protection, Args...)
> {
>     mixin(signalImpl!(Args)(name, protection));
> }

Nice. But you trade it for protection having a default value, making the syntax more verbose in the general case.

>
> If that works, why do you have the option to specify the protection at all?

So you can have a different protection for the full signal implementation and for the restricted part.

>
> BWT, shouldn't that assert be static?

Well the function is executed at compile time, but protection is still a "runtime" argument (so to speak) so I guess the answer is no.

Best regards,

Robert

November 10, 2013
On 2013-11-09 23:50, Robert wrote:
1
> Nice. But you trade it for protection having a default value, making the
> syntax more verbose in the general case.

You can overload it:

template signal (string name, Args...)

> So you can have a different protection for the full signal
> implementation and for the restricted part.

Ok, I see.

> Well the function is executed at compile time, but protection is still a
> "runtime" argument (so to speak) so I guess the answer is no.

Right.

-- 
/Jacob Carlborg
November 10, 2013
On Sunday, 10 November 2013 at 10:37:41 UTC, Jacob Carlborg wrote:
> On 2013-11-09 23:50, Robert wrote:
> 1
>> Nice. But you trade it for protection having a default value, making the
>> syntax more verbose in the general case.
>
> You can overload it:
>
> template signal (string name, Args...)
>

Smartass! ;-) Of course this would work, not bad! I am not sure whether this additional wrapper it is worth its salt, but it is definitely a nice alternative. I will absolutely think about it. Thanks!
November 10, 2013
On Sunday, 10 November 2013 at 11:32:45 UTC, Robert wrote:
> On Sunday, 10 November 2013 at 10:37:41 UTC, Jacob Carlborg wrote:
>> On 2013-11-09 23:50, Robert wrote:
>> 1
>>> Nice. But you trade it for protection having a default value, making the
>>> syntax more verbose in the general case.
>>
>> You can overload it:
>>
>> template signal (string name, Args...)
>>
>
> Smartass! ;-) Of course this would work, not bad! I am not sure whether this additional wrapper it is worth its salt, but it is definitely a nice alternative. I will absolutely think about it. Thanks!

You can use this syntax:

template signal (ProtectionType protection = ProtectionType.private_, string name, Args...)
{
    mixin(signalImpl!(Args)(name, protection));
}

enum ProtectionType
{
    none,
    private_,
    //...
}

It combines both Jacob's suggestions.

Also, it looks like that you don't need `string mixin` at all. You can use `static if`.
November 12, 2013
Upping the thread as it did not receive much review attention is is slowly getting fading away.

Robert, for someone who has only vague knowledge of signal stuff (me), can you explain why exactly this design was necessary? (mixing in global variable and wrapper function which returns its restricted version) Is the desire to separate protection attributes the only motivation or there are some other concerns?
November 12, 2013
> Robert, for someone who has only vague knowledge of signal stuff (me), can you explain why exactly this design was necessary? (mixing in global variable and wrapper function which returns its restricted version) Is the desire to separate protection attributes the only motivation or there are some other concerns?

No this is the only reason. Usually it is the common case that you only want the "owner" of the signal to emit it. Without the mixin, this would require the following boilerplate for every single signal:

    ref RestrictedSignal!(SomeTemplate!int) mysig() { return _mysig;}
    private Signal!(SomeTemplate!int) _mysig;

which is a bit tedious.

I am currently considering the suggestions of Jacob Carlborg:
 - using an enum for the protections
 - provide an additional template mixin wrapper for another minor reduction of boilerplate.

Signal slot frameworks in C++ usually either only allow the owner to emit the signal (Qt) or you are required to write some wrapper functions for restrictions on the public API (e.g. boost signal).

Best regards,

Robert