From 22ac47b275c2bcad5b5ff3c0cc3e10f3caaeb65b Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Thu, 30 Dec 2021 15:46:11 +0100 Subject: 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. --- lib/events/event.h | 14 +++++++++----- 1 file 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 -inline event_type_t typeId() +constexpr event_type_t typeId() { return std::decay_t::TypeId; } @@ -147,8 +147,12 @@ public: template const auto& addMethod() { + const auto m = &makeIfMatches; + 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); + return methods.emplace_back(m); } auto loadEvent(const QJsonObject& json, const QString& matrixType) @@ -268,9 +272,9 @@ using Events = EventsArray; // 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(); \ +#define REGISTER_EVENT_TYPE(Type_) \ + [[maybe_unused]] inline const auto& factoryMethodFor##Type_ = \ + Type_::factory.addMethod(); \ // End of macro // === is<>(), eventCast<>() and switchOnType<>() === -- cgit v1.2.3