Sorry, slight typo in my original email. Creating an observer would be done 
like this:

addObserver(sender, SomeSignalEvent::eventID(), receiver, 
&ReceivingClass::handleSomeSignalEvent);

Also, the SomeSignalEvent class should have had an accessor function to allow 
the receiver to get the someString_ value. I'm sure you'd all figured that out 
on your own though. ;)


On 22/09/2011, at 9:48 AM, <craig.sc...@csiro.au> <craig.sc...@csiro.au> wrote:

> 
> On 22/09/2011, at 3:20 AM, Thiago Macieira wrote:
> 
>> On Wednesday, 21 de September de 2011 18:49:04 Stephen Kelly wrote:
>>>>> Another solution (also by way of adding an indirection) is to add a
>>>>> function that emits, which is protected.
>>>>> 
>>>>> template <typename Klass, typename... Args>
>>>>> void QObject::emitSignal(void (Klass:: *signal)(Args...), Args... args);
>>>>> 
>>>>> Then you'd write:
>>>>> emitSignal(&Me::textChanged, newText);
>>>>> instead of:
>>>>> emit textChanged(newText);
>>>>> 
>>>>> The template magic to make that happen is already present.
>>>>> 
>>>>> However, it would be completely source-incompatible with the existing
>>>>> code, which is a big no-no. It would require making the signal functions
>>>>> themselves not do anything -- only serve as identifiers.
>>>> 
>>>> For source compatibility they could be implemented by moc to work as
>>>> currently, no?
>>> 
>>> Oh, they need to keep the current implementation so that SIGNAL and SLOT
>>> based connections still work. Never mind me.
>> 
>> The old connection mechanism is almost guaranteed to work.
>> 
>> The problem is to update "emit" lines, which are calls to functions that 
>> cause 
>> the signal to be emitted.
>> 
>> Also note that the solution above doesn't fix the following case:
>> 
>>      otherObject->emitSignal(&Them::textChanged, newText);
>> 
>> Just as it doesn't protect today:
>>      emit otherObject->textChanged(newText);
>> 
>> The big difference is that "emitSignal" would be protected in QObject, so 
>> any 
>> class deriving from QObject would have access to it.
>> 
>> We've been looking at this for a year. If anyone has more interesting ideas, 
>> they are more than welcome. But please try to write the proof of concept 
>> first.
>> 
>> Our conclusion is that if you want compile-time checking of the arguments, 
>> you 
>> need to give up the protectedness of the emission.
> 
> I'll mention one approach not because I think it is the right one to use 
> here, but rather just to potentially fuel further discussion. For reasons I 
> won't go into, we have our own observer-based code which has similarities to 
> what Qt's signal-slot mechanism offers. Instead of relying on string-based 
> signatures, it uses addresses of instances of a specific event class, which 
> we call EventID. We also have an event base class which we call 
> ObservableEvent. Our equivalent of defining a signal is to define a subclass 
> of ObservableEvent. We provide the EventID singleton that corresponds to an 
> ObservableEvent subclass using a static function. A short code extract to 
> give you an idea of how this works would be:
> 
> class SomeSignalEvent : public ObservableEvent
> {
>    QString  someString_;
> public:
>    SomeSignalEvent(const QString& s) : someString_(s) {}
> 
>    static const EventID&  eventID()   { ... }    // Implementation hidden to 
> keep it simple
> };
> 
> class SendingClass : public CanNotifyEvents    // I won't explain this, but 
> it's similar to inheriting from QObject
> {
>    // ...
> };
> 
> class ReceivingClass
> {
> public:
>    void  handleSomeSignalEvent(const SomeSignalEvent& e);
> };
> 
> In our code, you would create an observer for an event on a specific object 
> something like this:
> 
> addObserver(sender, SomeSignalEvent::eventID(), receiver & 
> ReceivingClass::handleSomeSignalEvent);
> 
> 
> Now, let's say that, as per this discussion thread, you wanted to limit who 
> can emit/raise the SomeSignalEvent. Specifically, let's say you only wanted 
> SendingClass to be able to do that. In that case, you could make the 
> constructor for SomeSignalEvent private and add SendingClass as a friend. You 
> leave the eventID() static function public. This means only SendingClass can 
> create/emit the event, but anyone can connect to / listen for that 
> signal/event.
> 
> Now, it may look like more work and yes, there are some things that the above 
> approach makes a bit harder than the current signal-slot mechanism, but it 
> does allow you to have full compile time checking and it does allow you to 
> have non-public emit access while still allowing public connect/listen 
> access. I've simplified things a bit in the examples above. In our code, we 
> have macros and templates handle all the gory details and it is actually very 
> simple to use. We've also very much appreciated that receivers don't have to 
> derive from a common base class, so it's easy to add connections where we 
> want the receiver to be a private class defined within a .cpp file, for 
> instance.
> 
> I reiterate that I'm not advocating this as a replacement for the current 
> signal-slot mechanism. It isn't source compatible with it, obviously, and it 
> is a bit different in how the receiver is defined. I mention it only as an 
> example of something that does meet the requirements of being able to control 
> who can emit/raise a signal while still allowing anyone to connect to it, all 
> with compile-time checking.
> 
> --
> Dr Craig Scott
> Computational Software Engineering Team Leader, CSIRO (CMIS)
> Melbourne, Australia
> 
> 
> 
> _______________________________________________
> Qt5-feedback mailing list
> Qt5-feedback@qt.nokia.com
> http://lists.qt.nokia.com/mailman/listinfo/qt5-feedback

--
Dr Craig Scott
Computational Software Engineering Team Leader, CSIRO (CMIS)
Melbourne, Australia



_______________________________________________
Qt5-feedback mailing list
Qt5-feedback@qt.nokia.com
http://lists.qt.nokia.com/mailman/listinfo/qt5-feedback

Reply via email to