From 843f7a0ac2619a2f2863d457cdeaa03707255793 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Wed, 4 May 2022 21:12:29 +0200 Subject: basic*EventJson() -> *Event::basicJson() This makes it easier and more intuitive to build a minimal JSON payload for a given event type. A common basicJson() call point is also convenient in template contexts (see next commits). --- lib/events/event.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/events/event.h') diff --git a/lib/events/event.h b/lib/events/event.h index 113fa3fa..5be2b41b 100644 --- a/lib/events/event.h +++ b/lib/events/event.h @@ -48,13 +48,6 @@ const QString RoomIdKey { RoomIdKeyL }; const QString UnsignedKey { UnsignedKeyL }; const QString StateKeyKey { StateKeyKeyL }; -/// Make a minimal correct Matrix event JSON -inline QJsonObject basicEventJson(const QString& matrixType, - const QJsonObject& content) -{ - return { { TypeKey, matrixType }, { ContentKey, content } }; -} - // === Event types === using event_type_t = QLatin1String; @@ -193,6 +186,13 @@ public: Event& operator=(Event&&) = delete; virtual ~Event(); + /// Make a minimal correct Matrix event JSON + static QJsonObject basicJson(const QString& matrixType, + const QJsonObject& content) + { + return { { TypeKey, matrixType }, { ContentKey, content } }; + } + Type type() const { return _type; } QString matrixType() const; [[deprecated("Use fullJson() and stringify it with QJsonDocument::toJson() " -- cgit v1.2.3 From e7a4b5a545b0f59b95ca8097009dbf6eea534db1 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Fri, 6 May 2022 22:17:55 +0200 Subject: Generalise DEFINE_SIMPLE_EVENT This macro was defined in accountdataevents.h but adding one more parameter (base class) makes it applicable to pretty much any event with the content that has one key-value pair (though state events already have a non-macro solution in the form of `StateEvent`). Now CustomEvent definition in quotest.cpp can be replaced with a single line. --- lib/events/accountdataevents.h | 31 +++++++++---------------------- lib/events/event.h | 26 ++++++++++++++++++++++++++ quotest/quotest.cpp | 18 +----------------- 3 files changed, 36 insertions(+), 39 deletions(-) (limited to 'lib/events/event.h') diff --git a/lib/events/accountdataevents.h b/lib/events/accountdataevents.h index 12f1f00b..ec2f64e3 100644 --- a/lib/events/accountdataevents.h +++ b/lib/events/accountdataevents.h @@ -46,27 +46,14 @@ struct JsonObjectConverter { using TagsMap = QHash; -#define DEFINE_SIMPLE_EVENT(_Name, _TypeId, _ContentType, _ContentKey) \ - class QUOTIENT_API _Name : public Event { \ - public: \ - using content_type = _ContentType; \ - DEFINE_EVENT_TYPEID(_TypeId, _Name) \ - explicit _Name(const QJsonObject& obj) : Event(typeId(), obj) {} \ - explicit _Name(const content_type& content) \ - : Event(typeId(), matrixTypeId(), \ - QJsonObject { \ - { QStringLiteral(#_ContentKey), toJson(content) } }) \ - {} \ - auto _ContentKey() const \ - { \ - return contentPart(#_ContentKey##_ls); \ - } \ - }; \ - REGISTER_EVENT_TYPE(_Name) \ - // End of macro - -DEFINE_SIMPLE_EVENT(TagEvent, "m.tag", TagsMap, tags) -DEFINE_SIMPLE_EVENT(ReadMarkerEvent, "m.fully_read", QString, event_id) -DEFINE_SIMPLE_EVENT(IgnoredUsersEvent, "m.ignored_user_list", QSet, +DEFINE_SIMPLE_EVENT(TagEvent, Event, "m.tag", TagsMap, tags) +DEFINE_SIMPLE_EVENT(ReadMarkerEventImpl, Event, "m.fully_read", QString, eventId) +class ReadMarkerEvent : public ReadMarkerEventImpl { +public: + using ReadMarkerEventImpl::ReadMarkerEventImpl; + [[deprecated("Use ReadMarkerEvent::eventId() instead")]] + QString event_id() const { return eventId(); } +}; +DEFINE_SIMPLE_EVENT(IgnoredUsersEvent, Event, "m.ignored_user_list", QSet, ignored_users) } // namespace Quotient diff --git a/lib/events/event.h b/lib/events/event.h index 5be2b41b..a27c0b96 100644 --- a/lib/events/event.h +++ b/lib/events/event.h @@ -278,6 +278,32 @@ using Events = EventsArray; Type_::factory.addMethod(); \ // End of macro +/// \brief Define a new event class with a single key-value pair in the content +/// +/// This macro defines a new event class \p Name_ derived from \p Base_, +/// with Matrix event type \p TypeId_, providing a getter named \p GetterName_ +/// for a single value of type \p ValueType_ inside the event content. +/// To retrieve the value the getter uses a JSON key name that corresponds to +/// its own (getter's) name but written in snake_case. \p GetterName_ must be +/// in camelCase, no quotes (an identifier, not a literal). +#define DEFINE_SIMPLE_EVENT(Name_, Base_, TypeId_, ValueType_, GetterName_) \ + class QUOTIENT_API Name_ : public Base_ { \ + public: \ + using content_type = ValueType_; \ + DEFINE_EVENT_TYPEID(TypeId_, Name_) \ + explicit Name_(const QJsonObject& obj) : Base_(TypeId, obj) {} \ + explicit Name_(const content_type& content) \ + : Name_(Base_::basicJson(TypeId, { { JsonKey, toJson(content) } })) \ + {} \ + auto GetterName_() const \ + { \ + return contentPart(JsonKey); \ + } \ + static inline const auto JsonKey = toSnakeCase(#GetterName_##_ls); \ + }; \ + REGISTER_EVENT_TYPE(Name_) \ + // End of macro + // === is<>(), eventCast<>() and switchOnType<>() === template diff --git a/quotest/quotest.cpp b/quotest/quotest.cpp index 861cfba0..b14442b9 100644 --- a/quotest/quotest.cpp +++ b/quotest/quotest.cpp @@ -523,23 +523,7 @@ bool TestSuite::checkFileSendingOutcome(const TestToken& thisTest, return true; } -class CustomEvent : public RoomEvent { -public: - DEFINE_EVENT_TYPEID("quotest.custom", CustomEvent) - - CustomEvent(const QJsonObject& jo) - : RoomEvent(typeId(), jo) - {} - CustomEvent(int testValue) - : RoomEvent(TypeId, - Event::basicJson(TypeId, - QJsonObject { { "testValue"_ls, - toJson(testValue) } })) - {} - - auto testValue() const { return contentPart("testValue"_ls); } -}; -REGISTER_EVENT_TYPE(CustomEvent) +DEFINE_SIMPLE_EVENT(CustomEvent, RoomEvent, "quotest.custom", int, testValue) TEST_IMPL(sendCustomEvent) { -- cgit v1.2.3 From c42d268db0b40cdba06381fc64a6966a72c90709 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Fri, 11 Feb 2022 22:21:25 +0100 Subject: QUO_CONTENT_GETTER To streamline adding of simple getters of content parts. --- lib/events/callanswerevent.h | 6 ++---- lib/events/callcandidatesevent.h | 17 +++-------------- lib/events/callinviteevent.h | 5 +---- lib/events/event.h | 15 +++++++++++++++ lib/events/redactionevent.h | 2 +- lib/events/roomevent.h | 4 ++-- 6 files changed, 24 insertions(+), 25 deletions(-) (limited to 'lib/events/event.h') diff --git a/lib/events/callanswerevent.h b/lib/events/callanswerevent.h index 8ffe60f2..70292a7a 100644 --- a/lib/events/callanswerevent.h +++ b/lib/events/callanswerevent.h @@ -17,10 +17,8 @@ public: const QString& sdp); explicit CallAnswerEvent(const QString& callId, const QString& sdp); - int lifetime() const - { - return contentPart("lifetime"_ls); - } // FIXME: Omittable<>? + QUO_CONTENT_GETTER(int, lifetime) // FIXME: Omittable<>? + QString sdp() const { return contentPart("answer"_ls).value("sdp"_ls).toString(); diff --git a/lib/events/callcandidatesevent.h b/lib/events/callcandidatesevent.h index 74c38f2c..e949f722 100644 --- a/lib/events/callcandidatesevent.h +++ b/lib/events/callcandidatesevent.h @@ -23,20 +23,9 @@ public: { { QStringLiteral("candidates"), candidates } }) {} - QJsonArray candidates() const - { - return contentPart("candidates"_ls); - } - - QString callId() const - { - return contentPart("call_id"); - } - - int version() const - { - return contentPart("version"); - } + QUO_CONTENT_GETTER(QJsonArray, candidates) + QUO_CONTENT_GETTER(QString, callId) + QUO_CONTENT_GETTER(int, version) }; REGISTER_EVENT_TYPE(CallCandidatesEvent) diff --git a/lib/events/callinviteevent.h b/lib/events/callinviteevent.h index 47362b5c..1b1f4f0f 100644 --- a/lib/events/callinviteevent.h +++ b/lib/events/callinviteevent.h @@ -16,10 +16,7 @@ public: explicit CallInviteEvent(const QString& callId, const int lifetime, const QString& sdp); - int lifetime() const - { - return contentPart("lifetime"_ls); - } // FIXME: Omittable<>? + QUO_CONTENT_GETTER(int, lifetime) // FIXME: Omittable<>? QString sdp() const { return contentPart("offer"_ls).value("sdp"_ls).toString(); diff --git a/lib/events/event.h b/lib/events/event.h index a27c0b96..ec21c6aa 100644 --- a/lib/events/event.h +++ b/lib/events/event.h @@ -258,6 +258,21 @@ template using EventsArray = std::vector>; using Events = EventsArray; +//! \brief Define an inline method obtaining a content part +//! +//! This macro adds a const method that extracts a JSON value at the key +//! toSnakeCase(PartName_) (sic) and converts it to the type +//! \p PartType_. Effectively, the generated method is an equivalent of +//! \code +//! contentPart(Quotient::toSnakeCase(#PartName_##_ls)); +//! \endcode +#define QUO_CONTENT_GETTER(PartType_, PartName_) \ + PartType_ PartName_() const \ + { \ + static const auto JsonKey = toSnakeCase(#PartName_##_ls); \ + return contentPart(JsonKey); \ + } + // === Facilities for event class definitions === // This macro should be used in a public section of an event class to diff --git a/lib/events/redactionevent.h b/lib/events/redactionevent.h index be20bf52..1c486a44 100644 --- a/lib/events/redactionevent.h +++ b/lib/events/redactionevent.h @@ -17,7 +17,7 @@ public: { return fullJson()["redacts"_ls].toString(); } - QString reason() const { return contentPart("reason"_ls); } + QUO_CONTENT_GETTER(QString, reason) }; REGISTER_EVENT_TYPE(RedactionEvent) } // namespace Quotient diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 0692ad8a..7f724689 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -96,8 +96,8 @@ public: ~CallEventBase() override = default; bool isCallEvent() const override { return true; } - QString callId() const { return contentPart("call_id"_ls); } - int version() const { return contentPart("version"_ls); } + QUO_CONTENT_GETTER(QString, callId) + QUO_CONTENT_GETTER(int, version) protected: static QJsonObject basicJson(const QString& matrixType, -- cgit v1.2.3