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