In short, you only have one signal and let the receivers decide if it concern them or not?
Yes. The receivers decide based on the hints flags.
{
Q_OBJECT;
public:
using Hint = enum size_t
{
eHintNothingChanged = 0,
eHintThisChanged = 1 << 0,
eHintThatChanged = 1 << 1,
eHintSomethingElseChanged = 1 << 2,
eHintThisChangedToo = 1 << 3,
};
signals:
void notifyChange( Document * doc, size_t hints );
// ...
};
// Document.cpp
void Document::notifyAboutThisAndThat()
{
size_t hints = eHintThisChanged | eHintThatChanged;
emit notifyChange( this, hints );
}
class Document : public QObject
{
Q_OBJECT;
public:
using Hint = enum size_t
{
eHintNothingChanged = 0,
eHintThisChanged = 1 << 0,
eHintThatChanged = 1 << 1,
eHintSomethingElseChanged = 1 << 2,
eHintThisChangedToo = 1 << 3,
};
signals:
void notifyChange( Document * doc, size_t hints );
// ...
};
// Document.cpp
void Document::notifyAboutThisAndThat()
{
size_t hints = eHintThisChanged | eHintThatChanged;
emit notifyChange( this, hints );
}
To copy to clipboard, switch view to plain text mode
// SomeOtherClass.h
public slots:
void onDocumentChanged( Document * doc, size_t hints )
{
if ( hints & Document::eHintSomethingElseChanged )
{
// It's for me!
}
else
{
// Too bad, not my day
}
}
// SomeOtherClass.h
public slots:
void onDocumentChanged( Document * doc, size_t hints )
{
if ( hints & Document::eHintSomethingElseChanged )
{
// It's for me!
}
else
{
// Too bad, not my day
}
}
To copy to clipboard, switch view to plain text mode
"manager" that manage inputs and contains other methods, specific variables and a pointer to the document class.
My MainWindow class usually has this role. The Document class is usually not connected directly to anything in the UI. The MainWindow holds the pointer to the Document instance and the MainWindow connects to all of the other UI elements and their signals. So for example, if there is a menu item to edit some parameters, the MainWindow retrieves the parameter instance from the document, and sends it to the UI component that edits it. When that component signals that it is done, the MainWindow retrieves the parameters and stores them back in the document. At that point the document sends its signal with the hint "eHintTheParametersChanged".
I suppose I could use a separate Manager class, but it seems like the Manager class would have to know all about the UI in order to listen for signals, but maybe not. If the MainWindow just creates the UI and then connects the UI signals to slots in the Manager, then the Manager doesn't actually have to know that it was a combo box that sent the signal. I'll have to think about that.
It may be a better idea to separate them into multiple specific serializer as you did though...
I think it is easier from a enhancement and maintenance point of view. There is pretty much a 1-1 mapping between a data structure and its serializer. If you change the data structure, you change its serializer at the same time and nothing else is affected. If you add or remove a data structure, then you need to change the serializer code in the "parent" serializer to match the contents of the "parent" data structure. And you bump up the version numbers for whatever serializers are affected by the change so they can change their behavior based on the version number they are reading or writing.
Bookmarks