From a26147582ce8cbd6a5206aee4b59de98c9dfe9b6 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Wed, 27 Jul 2022 20:19:44 +0200 Subject: DEFINE_SIMPLE_EVENT: support custom JSON keys --- quotest/quotest.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'quotest') diff --git a/quotest/quotest.cpp b/quotest/quotest.cpp index b6c855bb..3860ae1e 100644 --- a/quotest/quotest.cpp +++ b/quotest/quotest.cpp @@ -524,7 +524,8 @@ bool TestSuite::checkFileSendingOutcome(const TestToken& thisTest, return true; } -DEFINE_SIMPLE_EVENT(CustomEvent, RoomEvent, "quotest.custom", int, testValue) +DEFINE_SIMPLE_EVENT(CustomEvent, RoomEvent, "quotest.custom", int, testValue, + "test_value") TEST_IMPL(sendCustomEvent) { -- cgit v1.2.3 From 80499cc7619bb857c284e6e89db728ccee9c61f6 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Sat, 3 Sep 2022 19:12:42 +0200 Subject: More cleanup --- lib/events/encryptedevent.cpp | 7 ++++--- lib/events/encryptedevent.h | 7 ++++--- lib/events/event.h | 2 +- lib/events/roommessageevent.cpp | 5 ++--- lib/expected.h | 7 ++++--- lib/room.cpp | 16 ++++++++-------- lib/room.h | 7 +++---- quotest/quotest.cpp | 2 +- 8 files changed, 27 insertions(+), 26 deletions(-) (limited to 'quotest') diff --git a/lib/events/encryptedevent.cpp b/lib/events/encryptedevent.cpp index e9b4a585..94b44901 100644 --- a/lib/events/encryptedevent.cpp +++ b/lib/events/encryptedevent.cpp @@ -6,14 +6,15 @@ using namespace Quotient; -EncryptedEvent::EncryptedEvent(const QJsonObject& ciphertext, +EncryptedEvent::EncryptedEvent(const QJsonObject& ciphertexts, const QString& senderKey) : RoomEvent({ { AlgorithmKeyL, OlmV1Curve25519AesSha2AlgoKey }, - { CiphertextKeyL, ciphertext }, + { CiphertextKeyL, ciphertexts }, { SenderKeyKeyL, senderKey } }) {} -EncryptedEvent::EncryptedEvent(QByteArray ciphertext, const QString& senderKey, +EncryptedEvent::EncryptedEvent(const QByteArray& ciphertext, + const QString& senderKey, const QString& deviceId, const QString& sessionId) : RoomEvent({ { AlgorithmKeyL, MegolmV1AesSha2AlgoKey }, diff --git a/lib/events/encryptedevent.h b/lib/events/encryptedevent.h index 22e51cb8..02d4c7aa 100644 --- a/lib/events/encryptedevent.h +++ b/lib/events/encryptedevent.h @@ -32,11 +32,12 @@ public: /* In case with Olm, the encrypted content of the event is * a map from the recipient Curve25519 identity key to ciphertext * information */ - explicit EncryptedEvent(const QJsonObject& ciphertext, + explicit EncryptedEvent(const QJsonObject& ciphertexts, const QString& senderKey); /* In case with Megolm, device_id and session_id are required */ - explicit EncryptedEvent(QByteArray ciphertext, const QString& senderKey, - const QString& deviceId, const QString& sessionId); + explicit EncryptedEvent(const QByteArray& ciphertext, + const QString& senderKey, const QString& deviceId, + const QString& sessionId); explicit EncryptedEvent(const QJsonObject& obj); QString algorithm() const; diff --git a/lib/events/event.h b/lib/events/event.h index 4b715813..ea5a2554 100644 --- a/lib/events/event.h +++ b/lib/events/event.h @@ -269,7 +269,7 @@ public: explicit Event(const QJsonObject& json); Q_DISABLE_COPY(Event) - Event(Event&&) = default; + Event(Event&&) noexcept = default; Event& operator=(Event&&) = delete; virtual ~Event(); diff --git a/lib/events/roommessageevent.cpp b/lib/events/roommessageevent.cpp index db5afaf1..df4840b3 100644 --- a/lib/events/roommessageevent.cpp +++ b/lib/events/roommessageevent.cpp @@ -128,9 +128,8 @@ QJsonObject RoomMessageEvent::assembleContentJson(const QString& plainBody, RoomMessageEvent::RoomMessageEvent(const QString& plainBody, const QString& jsonMsgType, TypedBase* content) - : RoomEvent(RoomEvent::basicJson(TypeId, - assembleContentJson(plainBody, jsonMsgType, - content))) + : RoomEvent( + basicJson(TypeId, assembleContentJson(plainBody, jsonMsgType, content))) , _content(content) {} diff --git a/lib/expected.h b/lib/expected.h index 7b9e7f1d..81e186ea 100644 --- a/lib/expected.h +++ b/lib/expected.h @@ -21,11 +21,12 @@ public: using error_type = E; Expected() = default; - explicit Expected(const Expected&) = default; - explicit Expected(Expected&&) noexcept = default; + Expected(const Expected&) = default; + Expected(Expected&&) noexcept = default; + ~Expected() = default; template > - Expected(X&& x) + QUO_IMPLICIT Expected(X&& x) // NOLINT(google-explicit-constructor) : data(std::forward(x)) {} diff --git a/lib/room.cpp b/lib/room.cpp index f11b03e1..042d38ac 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -26,13 +26,13 @@ #include "csapi/inviting.h" #include "csapi/kicking.h" #include "csapi/leaving.h" +#include "csapi/read_markers.h" #include "csapi/receipts.h" #include "csapi/redaction.h" #include "csapi/room_send.h" #include "csapi/room_state.h" #include "csapi/room_upgrades.h" #include "csapi/rooms.h" -#include "csapi/read_markers.h" #include "csapi/tags.h" #include "events/callanswerevent.h" @@ -44,15 +44,15 @@ #include "events/receiptevent.h" #include "events/redactionevent.h" #include "events/roomavatarevent.h" +#include "events/roomcanonicalaliasevent.h" #include "events/roomcreateevent.h" #include "events/roommemberevent.h" +#include "events/roompowerlevelsevent.h" #include "events/roomtombstoneevent.h" #include "events/simplestateevents.h" #include "events/typingevent.h" -#include "events/roompowerlevelsevent.h" #include "jobs/downloadfilejob.h" #include "jobs/mediathumbnailjob.h" -#include "events/roomcanonicalaliasevent.h" #include #include @@ -1353,7 +1353,7 @@ void Room::setTags(TagsMap newTags, ActionScope applyOn) d->setTags(move(newTags)); connection()->callApi( - localUser()->id(), id(), TagEvent::matrixTypeId(), + localUser()->id(), id(), TagEvent::TypeId, TagEvent(d->tags).contentJson()); if (propagate) { @@ -2635,10 +2635,10 @@ RoomEventPtr makeRedacted(const RoomEvent& target, QStringLiteral("membership") }; // clang-format on - static const std::pair keepContentKeysMap[] { - { RoomMemberEvent::typeId(), { QStringLiteral("membership") } }, - { RoomCreateEvent::typeId(), { QStringLiteral("creator") } }, - { RoomPowerLevelsEvent::typeId(), + static const std::pair keepContentKeysMap[]{ + { RoomMemberEvent::TypeId, { QStringLiteral("membership") } }, + { RoomCreateEvent::TypeId, { QStringLiteral("creator") } }, + { RoomPowerLevelsEvent::TypeId, { QStringLiteral("ban"), QStringLiteral("events"), QStringLiteral("events_default"), QStringLiteral("kick"), QStringLiteral("redact"), QStringLiteral("state_default"), diff --git a/lib/room.h b/lib/room.h index 44504691..b454bfbc 100644 --- a/lib/room.h +++ b/lib/room.h @@ -770,11 +770,10 @@ public: "make sure to check its result for nullptrs")]] // const EvT* getCurrentState(const QString& stateKey = {}) const { - QT_IGNORE_DEPRECATIONS( - const auto* evt = eventCast( - getCurrentState(EvT::matrixTypeId(), stateKey));) + QT_IGNORE_DEPRECATIONS(const auto* evt = eventCast( + getCurrentState(EvT::TypeId, stateKey));) Q_ASSERT(evt); - Q_ASSERT(evt->matrixTypeId() == EvT::matrixTypeId() + Q_ASSERT(evt->matrixType() == EvT::TypeId && evt->stateKey() == stateKey); return evt; } diff --git a/quotest/quotest.cpp b/quotest/quotest.cpp index 3860ae1e..3ac6404a 100644 --- a/quotest/quotest.cpp +++ b/quotest/quotest.cpp @@ -163,7 +163,7 @@ bool TestSuite::validatePendingEvent(const QString& txnId) return it != targetRoom->pendingEvents().end() && it->deliveryStatus() == EventStatus::Submitted && (*it)->transactionId() == txnId && is(**it) - && (*it)->matrixType() == EventT::matrixTypeId(); + && (*it)->matrixType() == EventT::TypeId; } void TestSuite::finishTest(const TestToken& token, bool condition, -- cgit v1.2.3 From bde38f86337d6f49b34b38016ab088d2f48ec371 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Mon, 1 Aug 2022 18:09:47 +0200 Subject: concept EventClass Constrain types to derive from Event (or the chosen class), where applicable. --- lib/connection.cpp | 2 +- lib/connection.h | 2 +- lib/eventitem.h | 4 ++-- lib/events/event.h | 43 ++++++++++++++++++++++++++----------------- quotest/quotest.cpp | 4 ++-- 5 files changed, 32 insertions(+), 23 deletions(-) (limited to 'quotest') diff --git a/lib/connection.cpp b/lib/connection.cpp index a33ace51..d9268028 100644 --- a/lib/connection.cpp +++ b/lib/connection.cpp @@ -188,7 +188,7 @@ public: emit q->accountDataChanged(eventType); } - template + template void packAndSendAccountData(ContentT&& content) { packAndSendAccountData( diff --git a/lib/connection.h b/lib/connection.h index 66ed8b68..5afcfc2f 100644 --- a/lib/connection.h +++ b/lib/connection.h @@ -189,7 +189,7 @@ public: //! of that type. //! \note Direct chats map cannot be retrieved using this method _yet_; //! use directChats() instead. - template + template const EventT* accountData() const { return eventCast(accountData(EventT::TypeId)); diff --git a/lib/eventitem.h b/lib/eventitem.h index 2e55a724..445f8265 100644 --- a/lib/eventitem.h +++ b/lib/eventitem.h @@ -46,7 +46,7 @@ public: const RoomEvent* event() const { return rawPtr(evt); } const RoomEvent* get() const { return event(); } - template + template EventT> const EventT* viewAs() const { return eventCast(evt); @@ -67,7 +67,7 @@ public: std::any& userData() { return data; } protected: - template + template EventT> EventT* getAs() { return eventCast(evt); diff --git a/lib/events/event.h b/lib/events/event.h index 9d7c61a9..d0b63085 100644 --- a/lib/events/event.h +++ b/lib/events/event.h @@ -64,7 +64,11 @@ struct QUOTIENT_API EventTypeRegistry { class Event; -template +// TODO: move over to std::derived_from once it's available everywhere +template +concept EventClass = std::is_base_of_v; + +template bool is(const Event& e); //! \brief The base class for event metatypes @@ -206,13 +210,13 @@ private: //! //! This should not be used to load events from JSON - use loadEvent() for that. //! \sa loadEvent -template +template inline event_ptr_tt makeEvent(ArgTs&&... args) { return std::make_unique(std::forward(args)...); } -template +template constexpr const auto& mostSpecificMetaType() { if constexpr (requires { EventT::MetaType; }) @@ -226,7 +230,7 @@ constexpr const auto& mostSpecificMetaType() //! Use this factory template to detect the type from the JSON object //! contents (the detected event type should derive from the template //! parameter type) and create an event object of that type. -template +template inline event_ptr_tt loadEvent(const QJsonObject& fullJson) { return mostSpecificMetaType().loadFrom( @@ -238,7 +242,7 @@ inline event_ptr_tt loadEvent(const QJsonObject& fullJson) //! Use this template to resolve the C++ type from the Matrix type string in //! \p matrixType and create an event of that type by passing all parameters //! to BaseEventT::basicJson(). -template +template inline event_ptr_tt loadEvent(const QString& matrixType, const auto&... otherBasicJsonParams) { @@ -246,7 +250,7 @@ inline event_ptr_tt loadEvent(const QString& matrixType, EventT::basicJson(matrixType, otherBasicJsonParams...), matrixType); } -template +template struct JsonConverter> : JsonObjectUnpacker> { // No dump() to avoid any ambiguity on whether a given export to JSON uses @@ -295,7 +299,7 @@ public: //! the returned value will be different. QString matrixType() const; - template + template bool is() const { return Quotient::is(*this); @@ -377,7 +381,7 @@ private: }; using EventPtr = event_ptr_tt; -template +template using EventsArray = std::vector>; using Events = EventsArray; @@ -400,8 +404,10 @@ using Events = EventsArray; //! your class will likely be clearer and more concise. //! \sa https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern //! \sa DEFINE_SIMPLE_EVENT -template +template class EventTemplate : public BaseEventT { + // Above: can't constrain EventT to be EventClass because it's incomplete + // by CRTP definition. public: static_assert( !std::is_same_v, @@ -522,7 +528,7 @@ public: // === is<>(), eventCast<>() and switchOnType<>() === -template +template inline bool is(const Event& e) { if constexpr (requires { EventT::MetaType; }) { @@ -544,7 +550,7 @@ inline bool is(const Event& e) //! can be either "dumb" (BaseEventT*) or "smart" (`event_ptr_tt<>`). This //! overload doesn't affect the event ownership - if the original pointer owns //! the event it must outlive the downcast pointer to keep it from dangling. -template +template inline auto eventCast(const BasePtrT& eptr) -> decltype(static_cast(&*eptr)) { @@ -567,7 +573,7 @@ inline auto eventCast(const BasePtrT& eptr) //! after calling this overload; if it is a temporary, this normally //! leads to the event getting deleted along with the end of //! the temporary's lifetime. -template +template inline auto eventCast(event_ptr_tt&& eptr) { return eptr && is>(*eptr) @@ -576,12 +582,15 @@ inline auto eventCast(event_ptr_tt&& eptr) } namespace _impl { - template - concept Invocable_With_Downcast = + template + concept Invocable_With_Downcast = requires + { + requires EventClass; std::is_base_of_v>>; + }; } -template +template inline auto switchOnType(const BaseT& event, TailT&& tail) { if constexpr (std::is_invocable_v) { @@ -596,7 +605,7 @@ inline auto switchOnType(const BaseT& event, TailT&& tail) } } -template +template inline auto switchOnType(const BaseT& event, FnT1&& fn1, FnTs&&... fns) { using event_type1 = fn_arg_t; @@ -605,7 +614,7 @@ inline auto switchOnType(const BaseT& event, FnT1&& fn1, FnTs&&... fns) return switchOnType(event, std::forward(fns)...); } -template +template [[deprecated("The new name for visit() is switchOnType()")]] // inline auto visit(const BaseT& event, FnTs&&... fns) { diff --git a/quotest/quotest.cpp b/quotest/quotest.cpp index 3ac6404a..624888be 100644 --- a/quotest/quotest.cpp +++ b/quotest/quotest.cpp @@ -128,7 +128,7 @@ private: [[nodiscard]] bool checkRedactionOutcome(const QByteArray& thisTest, const QString& evtIdToRedact); - template + template EventT> [[nodiscard]] bool validatePendingEvent(const QString& txnId); [[nodiscard]] bool checkDirectChat() const; void finishTest(const TestToken& token, bool condition, const char* file, @@ -156,7 +156,7 @@ void TestSuite::doTest(const QByteArray& testName) Q_ARG(TestToken, testName)); } -template +template EventT> bool TestSuite::validatePendingEvent(const QString& txnId) { auto it = targetRoom->findPendingEvent(txnId); -- cgit v1.2.3