-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Track: Add missing NOTIFY
signals for Q_PROPERTY
declarations
#3924
Conversation
This fixes some clazy-qproperty-without-notify warnings. Every `Q_PROPERTY` should either have a `NOTIFY` signal or be declared as `CONSTANT`. See this for details: - https://github.com/KDE/clazy/blob/master/docs/checks/README-qproperty-without-notify.md - https://doc.qt.io/qt-5.12/properties.html
All those properties might also change when invoking one of the following functions:
We could simply trigger all property changed signals in the first step to ensure consistency, especially for the first 4 methods. |
src/track/track.h
Outdated
Q_PROPERTY(int timesPlayed READ getTimesPlayed NOTIFY timesPlayedChanged) | ||
Q_PROPERTY(QString comment READ getComment WRITE setComment NOTIFY commentChanged) | ||
Q_PROPERTY(double bpm READ getBpm NOTIFY bpmUpdated) | ||
Q_PROPERTY(QString bpmFormatted READ getBpmText STORED false NOTIFY bpmUpdated) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change signal has a different type than the property. Is this intended? I would expect that all change signals emit the actual property type.
This also applies to the key text and formatted duration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The signals without parameters are intended:
A NOTIFY signal is optional. If defined, it should specify one existing signal in that class that is emitted whenever the value of the property changes. NOTIFY signals for MEMBER variables must take zero or one parameter, which must be of the same type as the property.
https://doc.qt.io/qt-5.12/properties.html
The type mismatch is unintended though :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/track/track.cpp
Outdated
@@ -84,6 +84,9 @@ Track::Track( | |||
<< "->" | |||
<< numberOfInstancesBefore + 1; | |||
} | |||
|
|||
connect(this, &Track::titleChanged, this, &Track::infoChanged); | |||
connect(this, &Track::artistChanged, this, &Track::infoChanged); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to call the additional signals explicit.
For less magic to consider in case of future refactoring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want me to add slots that only contain emit infoChanged()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I mean copy emit infoChanged() below emit artistChanged()
Than the call tree has one interruption less when debugging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Than we can consider to get rid of infoChanged() in favor of changed()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the signal signature is incompatible. I added the direct emit statements as you suggested.
Does this really modify any metadata?
This can only change the duration, right? I added some commits, please have a look. |
Ok, exportMetadata() doesn't seem to modify any of those exposed properties. It might only update hidden, internal members. Duration should be the only Q_PROPERTY that is affected by stream info changes. |
Ok, then I think this is ready. |
src/track/track.h
Outdated
Q_PROPERTY(int timesPlayed READ getTimesPlayed NOTIFY timesPlayedChanged) | ||
Q_PROPERTY(QString comment READ getComment WRITE setComment NOTIFY commentChanged) | ||
Q_PROPERTY(double bpm READ getBpm NOTIFY bpmUpdated) | ||
Q_PROPERTY(QString bpmFormatted READ getBpmText STORED false NOTIFY bpmTextChanged) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about consistently adopting the Text
prefix for all formatted (= derived text) properties, i.e. bpmFormatted
-> bpmText
for consistency?
This also applies to key
-> keyText
/ keysUpdated
-> keyTextUpdated
.
Even worse are the naming inconsistencies of the various duration properties. I didn't check how much code would be affected.
Managing all those updates and their dependencies is tedious and error prone.. Unfortunately, I have no idea how to adopt and apply FRP principles in Qt/QML or what idiomatic patterns they propose instead.
src/track/track.h
Outdated
void trackNumberChanged(const QString&); | ||
void trackTotalChanged(const QString&); | ||
void commentChanged(const QString&); | ||
void bpmTextChanged(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do some signals carry the value and others not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, even the docs don't apply a consistent approach:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0 or 1 parameter are allowed, but if the new value is provided as a parameter than it's type must match the type of the property.
In order to keep the number of signals low let's apply the following rationale:
- For native properties without any derived properties provide the new value if possible
- For properties with derived properties use the name of the native property, reuse the signal for all derived properties, and don't provide any value.
By applying this rule we need to revert bpmTextChanged
to bpmChanged
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Track
object with its thread synchronization is a bastard and not really suitable for this purpose. What we actually would need is a distinction between view model and domain model classes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For native properties without any derived properties provide the new value if possible. For properties with derived properties use the name of the native property, reuse the signal for all derived properties, and don't provide any value.
2c30a72
to
640a59d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is a signal missing in:
Track::setType(const QString& sType)
Track::setBitrate(int iBitrate)
Track::setURL(const QString& url)
Track::shiftCuePositionsMillis(double milliseconds)
Track::setRating (int rating)
Track::setBpmLocked(bool bpmLocked)
I am unsure if everything is correct in
Track::updateStreamInfoFromSource()
There is either an emitMetadataChanged() missing, or an redundant markDirtyAndUnlock(&lock); call.
None of those is a Q_PROPERTY. We can add more if we need to, but this is out of scope here.
Good catch, added the missing durationChanged signal. |
@daschuer Ping |
LGTM, thank you. |
This fixes some clazy-qproperty-without-notify warnings. Every
Q_PROPERTY
should either have aNOTIFY
signal or be declared asCONSTANT
.See this for details: