Skip to content
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

Expose enums to the Qt meta-object system #207

Merged
merged 1 commit into from
Sep 19, 2020
Merged

Conversation

jpnurmi
Copy link
Contributor

@jpnurmi jpnurmi commented Sep 5, 2020

This allows e.g. conversions between enum values and key names:

QMetaEnum metaEnum = QMetaEnum::fromType<QMQTT::ClientError>();
qDebug() << metaEnum.keyToValue("SocketTimeoutError"); // "6"

Furthermore, this lets QDebug print out descriptive names instead of
plain int values:

qDebug() << QMQTT::STATE_CONNECTING; // "1" vs. "QMQTT::STATE_CONNECTING"

NOTE: Q_NAMESPACE & Q_ENUM_NS were introduced in Qt 5.8.

@jpnurmi
Copy link
Contributor Author

jpnurmi commented Sep 5, 2020

Is the dependency on Qt 5.8+ acceptable?

@@ -52,6 +52,7 @@ QT_FORWARD_DECLARE_CLASS(QSslError)
#endif // QT_NO_SSL

namespace QMQTT {
Q_MQTT_EXPORT Q_NAMESPACE
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since Qt 5.14, there's also Q_NAMESPACE_EXPORT().

@mwallnoefer
Copy link
Collaborator

mwallnoefer commented Sep 6, 2020

Is the dependency on Qt 5.8+ acceptable?

Yes, good point. I think that currently we achieve compatibility back to Qt 5.5-5.6. Qt 5.7 for instance is the default version shipped with Ubuntu 16.04 LTS (and derivatives) which is still not end-of-life. On the other hand I guess that it shouldn't be that hard to introduce some no-op fill macros for Q_NAMESPACE and Q_ENUM_NS at the beginning of qmqtt_client.h.

What does @ejvr think?

@ejvr
Copy link
Contributor

ejvr commented Sep 8, 2020 via email

This allows e.g. conversions between enum values and key names:

    QMetaEnum metaEnum = QMetaEnum::fromType<QMQTT::ClientError>();
    qDebug() << metaEnum.keyToValue("SocketTimeoutError"); // "6"

Furthermore, this lets QDebug print out descriptive names instead of
plain int values:

    qDebug() << QMQTT::STATE_CONNECTING; // "1" vs. "QMQTT::STATE_CONNECTING"

NOTE: Q_NAMESPACE & Q_ENUM_NS were introduced in Qt 5.8,
      and Q_NAMESPACE_EXPORT() was introduced in Qt 5.14.
@jpnurmi
Copy link
Contributor Author

jpnurmi commented Sep 19, 2020

Qt 5.6:

qDebug() << QT_VERSION_STR << QMQTT::STATE_CONNECTING; // no Q_ENUM_NS so can't use QMetaEnum::fromType() either
// "5.6.2 1"

Qt 5.9:

qDebug() << QT_VERSION_STR << QMQTT::STATE_CONNECTING << QMetaEnum::fromType<QMQTT::ClientError>().keyToValue("SocketTimeoutError");
// "5.9.9 QMQTT::ConnectionState(STATE_CONNECTING) 6"

Qt 5.12:

qDebug() << QT_VERSION_STR << QMQTT::STATE_CONNECTING << QMetaEnum::fromType<QMQTT::ClientError>().keyToValue("SocketTimeoutError");
// "5.12.8 QMQTT::STATE_CONNECTING 6"

Qt 5.14:

qDebug() << QT_VERSION_STR << QMQTT::STATE_CONNECTING << QMetaEnum::fromType<QMQTT::ClientError>().keyToValue("SocketTimeoutError");
// "5.14.2 QMQTT::STATE_CONNECTING 6"

@jpnurmi
Copy link
Contributor Author

jpnurmi commented Sep 19, 2020

I wanted to do:

#ifndef Q_NAMESPACE_EXPORT
#ifdef Q_NAMESPACE
#define Q_NAMESPACE_EXPORT(x) x Q_NAMESPACE
#else
#define Q_NAMESPACE_EXPORT(x)
#endif // Q_NAMESPACE
#endif // Q_NAMESPACE_EXPORT

namespace QMQTT {
Q_NAMESPACE_EXPORT(Q_MQTT_EXPORT)
// ...
}

because then you could simply just throw out the Q_NAMESPACE_EXPORT macro definition whenever you're ready to depend on Qt 5.14+ in the future, but unfortunately, moc was not happy with this approach:

qmqtt_client.h:66: Error: Namespace declaration lacks Q_NAMESPACE macro.

@ejvr
Copy link
Contributor

ejvr commented Sep 19, 2020

I guess this is a bit tricky, because qmake probably scans for the Q_NAMESPACE macro itself when parsing the header file. It does not call the preprocessor, so when compiler with older QT versions, moc.exe does not see Q_NAMESPACE.

Anyway, I like the current patch. Assuming it compiles with older version of QT, I'm in favour of accepting it.

EDIT: the patch compiles with QT 5.11.3, 5.15.1 and 5.7.1.

@mwallnoefer mwallnoefer merged commit 1fc3e1c into emqx:master Sep 19, 2020
@jpnurmi jpnurmi deleted the enums branch September 19, 2020 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants