diff options
author | Alexey Rusakov <Kitsune-Ral@users.sf.net> | 2021-12-30 15:46:11 +0100 |
---|---|---|
committer | Alexey Rusakov <Kitsune-Ral@users.sf.net> | 2022-01-01 20:46:53 +0100 |
commit | 22ac47b275c2bcad5b5ff3c0cc3e10f3caaeb65b (patch) | |
tree | 83d43e30b5becac541514dc26809046e9f22fd06 | |
parent | 8f03628ee0e4d1d1cb4e2f237e8fa695bc2cde42 (diff) | |
download | libquotient-22ac47b275c2bcad5b5ff3c0cc3e10f3caaeb65b.tar.gz libquotient-22ac47b275c2bcad5b5ff3c0cc3e10f3caaeb65b.zip |
Don't use QUOTIENT_API inside REGISTER_EVENT_TYPE
On Windows QUOTIENT_API expands to different things depending on whether
the library is built or used. This results in confusing statements (and
MSVC erroring out on them, in some cases - see below - quite
legitimately) not only when the application includes Quotient headers
but also when the application defines custom events and uses
REGISTER_EVENT_TYPE to make them creatable from /sync responses.
To avoid repeated registration when dynamic linking is involved,
EventFactory<>::addMethod() now bluntly looks up the method for this
type in the vector of already registered methods. It would surely be
quicker to use a static variable instead; but since the refreshed API
for addMethod returns a reference to the factory method it's necessary
to do this lookup anyway. Once the primary goal of this branch is
achieved across platforms I might experiment with lighter ways to
register factory methods; for now here's a minimal change to make
the code build on Windows.
-rw-r--r-- | lib/events/event.h | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/lib/events/event.h b/lib/events/event.h index 692e88e7..4024c6f8 100644 --- a/lib/events/event.h +++ b/lib/events/event.h @@ -73,7 +73,7 @@ private: }; template <typename EventT> -inline event_type_t typeId() +constexpr event_type_t typeId() { return std::decay_t<EventT>::TypeId; } @@ -147,8 +147,12 @@ public: template <class EventT> const auto& addMethod() { + const auto m = &makeIfMatches<EventT>; + const auto it = std::find(methods.cbegin(), methods.cend(), m); + if (it != methods.cend()) + return *it; logAddingMethod(EventT::TypeId, methods.size() + 1); - return methods.emplace_back(&makeIfMatches<EventT>); + return methods.emplace_back(m); } auto loadEvent(const QJsonObject& json, const QString& matrixType) @@ -268,9 +272,9 @@ using Events = EventsArray<Event>; // This macro should be put after an event class definition (in .h or .cpp) // to enable its deserialisation from a /sync and other // polymorphic event arrays -#define REGISTER_EVENT_TYPE(Type_) \ - [[maybe_unused]] QUOTIENT_API inline const auto& factoryMethodFor##Type_ = \ - Type_::factory.addMethod<Type_>(); \ +#define REGISTER_EVENT_TYPE(Type_) \ + [[maybe_unused]] inline const auto& factoryMethodFor##Type_ = \ + Type_::factory.addMethod<Type_>(); \ // End of macro // === is<>(), eventCast<>() and switchOnType<>() === |