From 08e19449ad4e33b9ec3eb66c56501f1c4a977350 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 2 Aug 2020 19:31:22 +0200 Subject: Event::dumpTo: make protected, and RoomEvent override The override adds the event's origin timestamp --- lib/events/roomevent.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 621652cb..084cb524 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -87,6 +87,9 @@ public: */ void addId(const QString& newId); +protected: + void dumpTo(QDebug dbg) const override; + private: event_ptr_tt _redactedBecause; }; -- cgit v1.2.3 From cd9c9296bb1ac7af7ebbbf66931e731dbf581bc8 Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Sat, 26 Dec 2020 14:54:31 +0100 Subject: Port existing copyright statement to reuse using licensedigger --- lib/events/roomevent.h | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 084cb524..3fafecfd 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -1,19 +1,7 @@ /****************************************************************************** - * Copyright (C) 2018 Kitsune Ral + * SPDX-FileCopyrightText: 2018 Kitsune Ral * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -- cgit v1.2.3 From 0a775d9b3209be15dea8b8915fc0a1c8e0046ba6 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 16 Jan 2021 18:19:45 +0100 Subject: Updated copyright statements upon Git audit After going through all the files and the history of commits on them it was clear that some copyright statements are obsolete (the code has been overwritten since) and some are missing. This commit tries best to remedy that, along with adding SPDX tags where they were still not used. Also, a minimal SPDX convention is documented for further contributions. Closes #426. --- lib/events/roomevent.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 3fafecfd..fea509c0 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -1,8 +1,5 @@ -/****************************************************************************** - * SPDX-FileCopyrightText: 2018 Kitsune Ral - * - * SPDX-License-Identifier: LGPL-2.1-or-later - */ +// SPDX-FileCopyrightText: 2018 Kitsune Ral +// SPDX-License-Identifier: LGPL-2.1-or-later #pragma once -- cgit v1.2.3 From ea1e849f617f62b3d209b2019e0daa3c6bed50f0 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Mon, 2 Aug 2021 09:02:31 +0200 Subject: More doc-comments --- lib/events/roomevent.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index fea509c0..3abd56c0 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -37,6 +37,10 @@ public: } QString roomId() const; QString senderId() const; + //! \brief Determine whether the event has been replaced + //! + //! \return true if this event has been overridden by another event + //! with `"rel_type": "m.replace"`; false otherwise bool isReplaced() const; QString replacedBy() const; bool isRedacted() const { return bool(_redactedBecause); } -- cgit v1.2.3 From fd42d1dbd29800ef53ab9997c948f39a92aa8bff Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Sun, 22 Aug 2021 20:23:42 +0200 Subject: RoomEvent: drop timestamp() Use originTimestamp(); the corresponding Q_PROPERTY was not renamed (in error) so it is now. --- lib/events/roomevent.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 3abd56c0..3174764f 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -14,7 +14,9 @@ class RedactionEvent; class RoomEvent : public Event { Q_GADGET Q_PROPERTY(QString id READ id) - Q_PROPERTY(QDateTime timestamp READ timestamp CONSTANT) + //! \deprecated Use originTimestamp instead + Q_PROPERTY(QDateTime timestamp READ originTimestamp CONSTANT) + Q_PROPERTY(QDateTime originTimestamp READ originTimestamp CONSTANT) Q_PROPERTY(QString roomId READ roomId CONSTANT) Q_PROPERTY(QString senderId READ senderId CONSTANT) Q_PROPERTY(QString redactionReason READ redactionReason) @@ -32,9 +34,6 @@ public: QString id() const; QDateTime originTimestamp() const; - [[deprecated("Use originTimestamp()")]] QDateTime timestamp() const { - return originTimestamp(); - } QString roomId() const; QString senderId() const; //! \brief Determine whether the event has been replaced -- cgit v1.2.3 From f6155d62740a88b020273ba623c816f7b9805772 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Fri, 26 Nov 2021 13:44:39 +0100 Subject: Drop Q_GADGET from most uncopyable classes; other minor cleanup Q_GADGET is generally used to enable two things outside of QObject: Q_PROPERTY/Q_INVOKABLE and Q_ENUM/Q_FLAG. While the latter can be used in its own right in QML, the former requires Q_GADGET instances to be passed to QML by value, which is not really possible with uncopyable/unassignable classes. Bottom line is that Q_PROPERTY in anything derived from Quotient::Event is not viable, making Q_GADGET macro useless unless there's a Q_ENUM/Q_FLAG (as is the case with RoomMessageEvent, e.g.). --- lib/events/roomevent.h | 41 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 3174764f..a6cd84ca 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -12,16 +12,6 @@ class RedactionEvent; /** This class corresponds to m.room.* events */ class RoomEvent : public Event { - Q_GADGET - Q_PROPERTY(QString id READ id) - //! \deprecated Use originTimestamp instead - Q_PROPERTY(QDateTime timestamp READ originTimestamp CONSTANT) - Q_PROPERTY(QDateTime originTimestamp READ originTimestamp CONSTANT) - Q_PROPERTY(QString roomId READ roomId CONSTANT) - Q_PROPERTY(QString senderId READ senderId CONSTANT) - Q_PROPERTY(QString redactionReason READ redactionReason) - Q_PROPERTY(bool isRedacted READ isRedacted) - Q_PROPERTY(QString transactionId READ transactionId WRITE setTransactionId) public: using factory_t = EventFactory; @@ -51,28 +41,23 @@ public: QString transactionId() const; QString stateKey() const; + //! \brief Fill the pending event object with the room id void setRoomId(const QString& roomId); + //! \brief Fill the pending event object with the sender id void setSender(const QString& senderId); - - /** - * Sets the transaction id for locally created events. This should be - * done before the event is exposed to any code using the respective - * Q_PROPERTY. - * - * \param txnId - transaction id, normally obtained from - * Connection::generateTxnId() - */ + //! \brief Fill the pending event object with the transaction id + //! \param txnId - transaction id, normally obtained from + //! Connection::generateTxnId() void setTransactionId(const QString& txnId); - /** - * Sets event id for locally created events - * - * When a new event is created locally, it has no server id yet. - * This function allows to add the id once the confirmation from - * the server is received. There should be no id set previously - * in the event. It's the responsibility of the code calling addId() - * to notify clients that use Q_PROPERTY(id) about its change - */ + //! \brief Add an event id to locally created events after they are sent + //! + //! When a new event is created locally, it has no id; the homeserver + //! assigns it once the event is sent. This function allows to add the id + //! once the confirmation from the server is received. There should be no id + //! set previously in the event. It's the responsibility of the code calling + //! addId() to notify clients about the change; there's no signal or + //! callback for that in RoomEvent. void addId(const QString& newId); protected: -- cgit v1.2.3 From 0425fd280e7eee7a4c9bcf18f79910f181322c42 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Sat, 27 Nov 2021 20:14:53 +0100 Subject: Event::content() -> contentPart() There's a clash between Event::content() (a template function) and RoomMessageEvent::content() (plain member). Out of these two, the name more fits to the RME's member function - strictly speaking, Event::content() retrieves a part of content, and so is renamed. In addition, contentPart() defaults to QJsonValue now, which is pretty intuitive (the function returns values from a JSON object) and allows to implement more elaborate logic such as if (const auto v = contentPart<>("key"_ls); v.isObject()) { // foo } else if (v.isString()) { // bar } else { // boo } --- lib/events/roomevent.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index a6cd84ca..7f13f6f2 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -78,8 +78,8 @@ public: ~CallEventBase() override = default; bool isCallEvent() const override { return true; } - QString callId() const { return content("call_id"_ls); } - int version() const { return content("version"_ls); } + QString callId() const { return contentPart("call_id"_ls); } + int version() const { return contentPart("version"_ls); } }; } // namespace Quotient Q_DECLARE_METATYPE(Quotient::RoomEvent*) -- cgit v1.2.3 From a0ce17dfe793c924205b449c026f2f776b032ff3 Mon Sep 17 00:00:00 2001 From: Tobias Fella Date: Wed, 8 Dec 2021 23:07:14 +0100 Subject: Store encryptedevent in decrypted roomevents --- lib/events/roomevent.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 7f13f6f2..35527a62 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -60,11 +60,15 @@ public: //! callback for that in RoomEvent. void addId(const QString& newId); + void setOriginalEvent(event_ptr_tt originalEvent); + const QJsonObject encryptedJson() const; + protected: void dumpTo(QDebug dbg) const override; private: event_ptr_tt _redactedBecause; + event_ptr_tt _originalEvent; }; using RoomEventPtr = event_ptr_tt; using RoomEvents = EventsArray; -- cgit v1.2.3 From 58798ce15f0f235d64f9c34b3f8c013678ebf25f Mon Sep 17 00:00:00 2001 From: Tobias Fella Date: Thu, 9 Dec 2021 23:26:24 +0100 Subject: Ifdef all the things --- lib/events/roomevent.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 35527a62..36b45f09 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -60,15 +60,20 @@ public: //! callback for that in RoomEvent. void addId(const QString& newId); +#ifdef Quotient_E2EE_ENABLED void setOriginalEvent(event_ptr_tt originalEvent); const QJsonObject encryptedJson() const; +#endif protected: void dumpTo(QDebug dbg) const override; private: event_ptr_tt _redactedBecause; + +#ifdef Quotient_E2EE_ENABLED event_ptr_tt _originalEvent; +#endif }; using RoomEventPtr = event_ptr_tt; using RoomEvents = EventsArray; -- cgit v1.2.3 From b4a6070d44140a3cbc931b18530721e31f069455 Mon Sep 17 00:00:00 2001 From: Tobias Fella <9750016+TobiasFella@users.noreply.github.com> Date: Fri, 10 Dec 2021 16:15:50 +0100 Subject: Apply suggestions from code review Co-authored-by: Alexey Rusakov --- lib/events/roomevent.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 36b45f09..3d46bf9b 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -61,7 +61,8 @@ public: void addId(const QString& newId); #ifdef Quotient_E2EE_ENABLED - void setOriginalEvent(event_ptr_tt originalEvent); + void setOriginalEvent(event_ptr_tt&& originalEvent); + const RoomEvent* originalEvent() { return _originalEvent.get(); } const QJsonObject encryptedJson() const; #endif -- cgit v1.2.3 From 231c4d723eb53f3ea5f641b743d198584840a963 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Wed, 22 Dec 2021 13:44:39 +0100 Subject: Simplify the code around EventFactory<> The former code assumed that EventFactory<> is just a class-level shell for a bunch of functions and a static data member that only exists to allow specialisations to occur for the whole group together. On top of that, setupFactory() and registerEventType() strived to protect this group from double registration coming from static variables in an anonymous namespace produced by REGISTER_EVENT_TYPE. The whole thing is now de-static-ed: resolving the factory now relies on class-static Event/RoomEvent/StateEventBase::factory variables instead of factory_t type aliases; and REGISTER_EVENT_TYPE produces non-static inline variables instead, obviating the need of registerEventType/setupFactory kludge. --- lib/events/roomevent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 7f13f6f2..8be58481 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -13,7 +13,7 @@ class RedactionEvent; /** This class corresponds to m.room.* events */ class RoomEvent : public Event { public: - using factory_t = EventFactory; + static inline _impl::EventFactory factory { "RoomEvent" }; // RedactionEvent is an incomplete type here so we cannot inline // constructors and destructors and we cannot use 'using'. -- cgit v1.2.3 From 7350fe82953cf6274b8845a890eafb21a09b9931 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Wed, 29 Dec 2021 15:59:58 +0100 Subject: Add QUOTIENT_API throughout non-generated code This include all (hopefully) classes/structures and functions that have non-inline definitions, as well as namespaces with Q_NAMESPACE since those have non-inline (as of Qt 5.15) QMetaObject - for that a new macro, QUO_NAMESPACE, has been devised to accommodate the lack of Q_NAMESPACE_EXPORT in Qt before 5.14. --- lib/events/roomevent.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 8be58481..3fbb247e 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -11,7 +11,7 @@ namespace Quotient { class RedactionEvent; /** This class corresponds to m.room.* events */ -class RoomEvent : public Event { +class QUOTIENT_API RoomEvent : public Event { public: static inline _impl::EventFactory factory { "RoomEvent" }; @@ -70,7 +70,7 @@ using RoomEventPtr = event_ptr_tt; using RoomEvents = EventsArray; using RoomEventsRange = Range; -class CallEventBase : public RoomEvent { +class QUOTIENT_API CallEventBase : public RoomEvent { public: CallEventBase(Type type, event_mtype_t matrixType, const QString& callId, int version, const QJsonObject& contentJson = {}); -- cgit v1.2.3 From 7eda212753057c07f429dfdfb0cf3a18312de054 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Tue, 28 Dec 2021 21:46:57 +0100 Subject: Refactor EventFactory and move it out of _impl:: Strictly speaking, EventFactory can be further instantiated if any client application figures they need a whole new base class for events and respectively a separate EventFactory specialisation for it. Where this whole commit started though was a linkage error because I did not plan to expose Quotient-specific logging categories for linkage (effectively, usage) from the client code - meanwhile the inline code of EventFactory uses qDebug(EVENTS), meaning I had to either add QUOTIENT_API to EVENTS or hide those invocations. This in turn led to trimming the EventFactory constructor back to trivial implementation and dropping the guard variable that was supposed to trace duplicate EventFactory objects for the same BaseEventT - with the reasoning that such situation is not really dangerous (unlike EventTypeRegistry double-initialisation fiasco, see #413), and at the same time it can be easily detected in the logs by duplicated factory method registration messages. And while I was at it, I replaced the meaningless bool in the return type of EventFactory<>::addMethod with the slightly more (but still barely) useful reference to the inserted factory method. One can (in theory) use it now if they need to turn some event JSON into an object of some specific event type or nullptr if the event type in the JSON payload doesn't match - but at the same rate (for now at least) one can call makeIfMatches() directly. With this commit, both Quotest and Quaternion build and link using either Clang or GCC even under -fvisibility=hidden. However, running quotest now reproduces #413, which is a matter of event typeId infrastructure refactoring, coming in further commits. --- lib/events/roomevent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 3fbb247e..dcee1170 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -13,7 +13,7 @@ class RedactionEvent; /** This class corresponds to m.room.* events */ class QUOTIENT_API RoomEvent : public Event { public: - static inline _impl::EventFactory factory { "RoomEvent" }; + static inline EventFactory factory { "RoomEvent" }; // RedactionEvent is an incomplete type here so we cannot inline // constructors and destructors and we cannot use 'using'. -- cgit v1.2.3 From 71eed90fdea8689d237da8de1bf385202b85cffd Mon Sep 17 00:00:00 2001 From: Tobias Fella Date: Thu, 10 Mar 2022 21:19:49 +0100 Subject: More work; Update olm pickle & timestamps in database; Remove TODOs --- lib/events/roomevent.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index c4b0131a..a7d6c428 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -80,6 +80,14 @@ using RoomEventPtr = event_ptr_tt; using RoomEvents = EventsArray; using RoomEventsRange = Range; +template <> +inline EventPtr doLoadEvent(const QJsonObject& json, const QString& matrixType) +{ + if (matrixType == "m.room.encrypted") + return RoomEvent::factory.loadEvent(json, matrixType); + return Event::factory.loadEvent(json, matrixType); +} + class QUOTIENT_API CallEventBase : public RoomEvent { public: CallEventBase(Type type, event_mtype_t matrixType, const QString& callId, -- cgit v1.2.3 From fc3ad90a054e3c674127a0cdd385ddbb98cf2010 Mon Sep 17 00:00:00 2001 From: Tobias Fella Date: Fri, 8 Apr 2022 23:23:30 +0200 Subject: Correctly load EncryptedEvents --- lib/events/roomevent.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index c4b0131a..a7d6c428 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -80,6 +80,14 @@ using RoomEventPtr = event_ptr_tt; using RoomEvents = EventsArray; using RoomEventsRange = Range; +template <> +inline EventPtr doLoadEvent(const QJsonObject& json, const QString& matrixType) +{ + if (matrixType == "m.room.encrypted") + return RoomEvent::factory.loadEvent(json, matrixType); + return Event::factory.loadEvent(json, matrixType); +} + class QUOTIENT_API CallEventBase : public RoomEvent { public: CallEventBase(Type type, event_mtype_t matrixType, const QString& callId, -- cgit v1.2.3 From 16d4f4e48304543a0ab59b235edba07f5f2c2204 Mon Sep 17 00:00:00 2001 From: Tobias Fella Date: Mon, 18 Apr 2022 20:07:12 +0200 Subject: Implement key verification --- lib/events/roomevent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index a7d6c428..5670f55f 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -62,7 +62,7 @@ public: #ifdef Quotient_E2EE_ENABLED void setOriginalEvent(event_ptr_tt&& originalEvent); - const RoomEvent* originalEvent() { return _originalEvent.get(); } + const RoomEvent* originalEvent() const { return _originalEvent.get(); } const QJsonObject encryptedJson() const; #endif -- cgit v1.2.3 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/roomevent.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index a7d6c428..0692ad8a 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -98,6 +98,11 @@ public: QString callId() const { return contentPart("call_id"_ls); } int version() const { return contentPart("version"_ls); } + +protected: + static QJsonObject basicJson(const QString& matrixType, + const QString& callId, int version, + QJsonObject contentJson = {}); }; } // namespace Quotient Q_DECLARE_METATYPE(Quotient::RoomEvent*) -- 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/roomevent.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/events/roomevent.h') 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 From a18f505fe7ca66556d66538a7c9b9ff31d2c1b29 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Tue, 9 Aug 2022 18:42:24 +0200 Subject: EventMetaType, QUO_EVENT, QUO_BASE_EVENT The new metatype framework replaces EventFactory/DEFINE_EVENT_TYPEID/REGISTER_EVENT_TYPE; it is faster, more functional and extensible. Of note: - EventMetaType mostly reproduces the logic of EventFactory but supports custom base event types not just for loading (that part EventFactory also supported) but also for matching - previously you had to have Event::is*Event() for base type matching. Now Quotient::is() can match against both base and leaf types. - Instead of DEFINE_EVENT_TYPEID and REGISTER_EVENT_TYPE there's now a single macro, QUO_EVENT, intended for use in the way similar to Q_OBJECT. Actually, the entire framework borrows heavily from QMetaObject and Q_OBJECT. Making event types full-fledged QObjects is still not considered because half of QObject functions would not be applicable (e.g. signals/slots) while another half (in particular, using Matrix type ids to select event types) would still have to be done on top of QObject. And QML can just access events as const QJsonObjects which is arguably more lightweight as well. - QUO_BASE_EVENT is a new macro replacing EventFactory object definitions. This was necessary for the same reason why Q_OBJECT is a macro: aside from a static object definition, this macro introduces a virtual function override to resolve the metatype at runtime. This very mechanism is used to make event type matching/casting as quick as possible - QUO_BASE_EVENT and QUO_EVENT use the C++20 __VA_OPT__ feature that is only available with the new MSVC preprocessor (see https://docs.microsoft.com/en-us/cpp/preprocessor/preprocessor-experimental-overview); the respective switch was added to CMakeLists.txt. --- lib/events/roomevent.h | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 9461340b..532e72e2 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -10,10 +10,11 @@ namespace Quotient { class RedactionEvent; -/** This class corresponds to m.room.* events */ +// That check could look into Event and find most stuff already deleted... +// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions) class QUOTIENT_API RoomEvent : public Event { public: - static inline EventFactory factory { "RoomEvent" }; + QUO_BASE_EVENT(RoomEvent, {}, Event::BaseMetaType) // RedactionEvent is an incomplete type here so we cannot inline // constructors and destructors and we cannot use 'using'. @@ -80,21 +81,14 @@ using RoomEventPtr = event_ptr_tt; using RoomEvents = EventsArray; using RoomEventsRange = Range; -template <> -inline EventPtr doLoadEvent(const QJsonObject& json, const QString& matrixType) -{ - if (matrixType == "m.room.encrypted") - return RoomEvent::factory.loadEvent(json, matrixType); - return Event::factory.loadEvent(json, matrixType); -} - class QUOTIENT_API CallEventBase : public RoomEvent { public: + QUO_BASE_EVENT(CallEventBase, "m.call.*"_ls, RoomEvent::BaseMetaType) + CallEventBase(Type type, event_mtype_t matrixType, const QString& callId, int version, const QJsonObject& contentJson = {}); CallEventBase(Type type, const QJsonObject& json); ~CallEventBase() override = default; - bool isCallEvent() const override { return true; } QUO_CONTENT_GETTER(QString, callId) QUO_CONTENT_GETTER(int, version) -- cgit v1.2.3 From 17cd3beaefa5501a902e08c7644e8cd97c9091a0 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Fri, 12 Aug 2022 16:46:01 +0200 Subject: Streamline event types This commit introduces a few things to further reduce the boilerplate across event type definitions: - Event type is no more separately stored in Event and therefore no more passed to base event constructors. Until the previous commit, it was used by is() to quickly match the event type; with the new event metatype class, the same is achieved even quicker by comparing metatype pointers. - EventTemplate is a generalisation of StateEvent for all event types providing common constructor signatures and content() for (most) leaf event types. StateEvent therefore has become a partial specialisation of EventTemplate for types derived from StateEventBase; as the known client code base does not use it directly, a compatibility alias is not provided. Also, DEFINE_SIMPLE_EVENT now expands into a class deriving from EventTemplate. - On top of StateEvent->EventTemplate specialisation, KeyedStateEventBase and KeylessStateEventBase types are introduced with appropriate constructor signatures (with or without state_key, respectively) to allow `using` of them from derived event types. To facilitate writing of constraints, concepts for keyed and keyless state event types are also introduced; RoomStateView, e.g., makes use of those to provide appropriate method signatures. - typeId(), unknownEventTypeId(), UnknownEventTypeId are no more provided - they weren't used throughout the known code base (Quaternion, NeoChat), and the concept of "unknown event types" is hereby eliminated entirely. - RoomKeyEvent no more accepts senderId as a parameter; it has never been a good practice as the sender is assigned by Connection anyway. --- lib/events/roomevent.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 532e72e2..830f1d30 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -17,10 +17,8 @@ public: QUO_BASE_EVENT(RoomEvent, {}, Event::BaseMetaType) // RedactionEvent is an incomplete type here so we cannot inline - // constructors and destructors and we cannot use 'using'. - RoomEvent(Type type, event_mtype_t matrixType, - const QJsonObject& contentJson = {}); - RoomEvent(Type type, const QJsonObject& json); + // constructors using it and also destructors (with 'using', in particular). + explicit RoomEvent(const QJsonObject& json); ~RoomEvent() override; QString id() const; @@ -85,10 +83,7 @@ class QUOTIENT_API CallEventBase : public RoomEvent { public: QUO_BASE_EVENT(CallEventBase, "m.call.*"_ls, RoomEvent::BaseMetaType) - CallEventBase(Type type, event_mtype_t matrixType, const QString& callId, - int version, const QJsonObject& contentJson = {}); - CallEventBase(Type type, const QJsonObject& json); - ~CallEventBase() override = default; + explicit CallEventBase(const QJsonObject& json); QUO_CONTENT_GETTER(QString, callId) QUO_CONTENT_GETTER(int, version) @@ -98,6 +93,17 @@ protected: const QString& callId, int version, QJsonObject contentJson = {}); }; + +template +class EventTemplate : public CallEventBase { +public: + using CallEventBase::CallEventBase; + explicit EventTemplate(const QString& callId, + const QJsonObject& contentJson = {}) + : EventTemplate(basicJson(EventT::TypeId, callId, 0, contentJson)) + {} +}; + } // namespace Quotient Q_DECLARE_METATYPE(Quotient::RoomEvent*) Q_DECLARE_METATYPE(const Quotient::RoomEvent*) -- cgit v1.2.3 From 8e58d28ca0517aeeb43c99bd97ec9ba5ada11c95 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Mon, 1 Aug 2022 08:09:40 +0200 Subject: CallEventBase -> CallEvent; pack up all call events These are small enough to comfortably reside in a single translation unit. --- lib/events/roomevent.h | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 830f1d30..47b0b59d 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -79,31 +79,6 @@ using RoomEventPtr = event_ptr_tt; using RoomEvents = EventsArray; using RoomEventsRange = Range; -class QUOTIENT_API CallEventBase : public RoomEvent { -public: - QUO_BASE_EVENT(CallEventBase, "m.call.*"_ls, RoomEvent::BaseMetaType) - - explicit CallEventBase(const QJsonObject& json); - - QUO_CONTENT_GETTER(QString, callId) - QUO_CONTENT_GETTER(int, version) - -protected: - static QJsonObject basicJson(const QString& matrixType, - const QString& callId, int version, - QJsonObject contentJson = {}); -}; - -template -class EventTemplate : public CallEventBase { -public: - using CallEventBase::CallEventBase; - explicit EventTemplate(const QString& callId, - const QJsonObject& contentJson = {}) - : EventTemplate(basicJson(EventT::TypeId, callId, 0, contentJson)) - {} -}; - } // namespace Quotient Q_DECLARE_METATYPE(Quotient::RoomEvent*) Q_DECLARE_METATYPE(const Quotient::RoomEvent*) -- cgit v1.2.3 From 575534e7cca310c6d6195ab16d482bf9dfba755e Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Mon, 1 Aug 2022 18:09:35 +0200 Subject: Disallow direct events construction from JSON Direct construction (using makeEvent() or explicitly constructing an event) from JSON may create an event that has a type conflicting with that stored in JSON. There's no such problem with loadEvent(), even though it's considerably slower. Driven by the fact that almost nowhere in the code direct construction is used on checked JSON (one test is the only valid case), this commit moves all JSON-loading constructors to the protected section, thereby disabling usage of makeEvent() in JSON-loading capacity, and switches such cases across the library to loadEvent(). --- lib/events/roomevent.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/events/roomevent.h') diff --git a/lib/events/roomevent.h b/lib/events/roomevent.h index 47b0b59d..203434f6 100644 --- a/lib/events/roomevent.h +++ b/lib/events/roomevent.h @@ -16,10 +16,7 @@ class QUOTIENT_API RoomEvent : public Event { public: QUO_BASE_EVENT(RoomEvent, {}, Event::BaseMetaType) - // RedactionEvent is an incomplete type here so we cannot inline - // constructors using it and also destructors (with 'using', in particular). - explicit RoomEvent(const QJsonObject& json); - ~RoomEvent() override; + ~RoomEvent() override; // Don't inline this - see the private section QString id() const; QDateTime originTimestamp() const; @@ -66,9 +63,12 @@ public: #endif protected: + explicit RoomEvent(const QJsonObject& json); void dumpTo(QDebug dbg) const override; private: + // RedactionEvent is an incomplete type here so we cannot inline + // constructors using it and also destructors (with 'using', in particular). event_ptr_tt _redactedBecause; #ifdef Quotient_E2EE_ENABLED -- cgit v1.2.3