aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Rusakov <Kitsune-Ral@users.sf.net>2021-12-30 15:46:11 +0100
committerAlexey Rusakov <Kitsune-Ral@users.sf.net>2022-01-01 20:46:53 +0100
commit22ac47b275c2bcad5b5ff3c0cc3e10f3caaeb65b (patch)
tree83d43e30b5becac541514dc26809046e9f22fd06
parent8f03628ee0e4d1d1cb4e2f237e8fa695bc2cde42 (diff)
downloadlibquotient-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.h14
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<>() ===