|
|
Elvis Dowson wrote on Friday, October 24, 2008 10:50 AM:
> Hi Andre,
> When you design a component, it should have
> no knowledge of the other components that use a particular signal.
That is very true. Especially since in theory you should not rely on such
"implementation details" - they might change, as André from Trolltech/Nokia
pointed out (in practice though they probably won't).
But even if the implementation - the order of execution of the slots - won't
change, it still leaves a bad feeling. It is bad design to rely on this
behaviour.
> Similarly, when you consume an event/signal, the component should
> have no knowledge of who else is consuming the event/signal. So, in
> the spirit of true object orientation, one should not write
> components with an implicit knowledge of the execution order of other
> dependent components when using slots and signals.
As you - the designer - already know the dependency of your components, but the
components themselves mustn't know about each other, maybe you could get away
with the following approach:
Instead of connecting each component to the sender object, implement one
"manager" object with one single connection to the sender.
In this "manager" object you would then call the components in the order in
which you would also prioritise the signals. You could also make this dynamic
by setting the priority in this manager object (per component to be called).
So you would take the responsibility of the signal priorisation from the sender
object and move it "upwards" into your (somewhat artificial, I agree) "manager".
The downside of this approach would be to loose the flexibility of dynamically
de-/connecting the individual components. But thinking about this you could
probably also provide an API in the "manager object" to enable/disable the call
to the components.
And if you want to make it even more dynamically, you could even define a
"component interface", derive your components from that and in your "manager"
you would provide a means to dynamically "install" the components (so the
"manager" wouldn't even know the components themselves).
Something like this:
class Component {
public:
virtual void update() = 0;
};
/**
* Receives the signal from the "sender" and calls update() on the
* Components, in order of their Priority
*/
class MyManager : QObject {
Q_OBJECT
public:
...
/**
* Calls the update() method of the component in the order defined
* by 'priority' upon reception of the signal 'modified'.
*
* Components with the /same/ priority are called in arbitrary order!
* (alternative: increment the existing order(s) by one or something)
*/
void addComponent(const Component *component, Priority priority);
/**
* Removes the 'component' so it is not notified anymore.
*/
void removeComponent(const Component *component);
void changePriority(const Component *component, Priority newPriority);
...
private slots:
// calls the update() method on the components, according to their
// priority - connected to the "sender object"
void handleModified();
private:
// some clever data structure (a Map?), sorted according to Priority
PriorityQueue<const Component *, Priority> m_priorityQueue;
};
I agree, a bit of an overkill, but it would work...
>
> Rather, from with Qt Designer, when you connect signals to slow, the
> design environment should detect that there are multiple slots
> connected to a particular signal,
As André mentioned the signal/slot mechanism should be with as little overhead
(compared to normal method calls) as possible. But maybe an extension like:
connectPriority(sender, signal, receiver, slot, priority);
would be possible, that is another way of connecting signal/slots, so the
existing signal/slot implementation would not be touched. I only thought about
this for 30 secs, so it might not be possible after all, or not that easily...
Cheers, Oliver
--
To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
"unsubscribe" in the subject or the body.
List archive and information: http://lists.trolltech.com/qt-interest/
|
|