aboutsummaryrefslogtreecommitdiff
path: root/events/event.h
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2017-12-14 18:41:55 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2017-12-14 18:41:55 +0900
commitc5f480355c7d4c000a4ee73fd7f8107a9a9340c2 (patch)
treed7a8f51e75230aa48cd243ef40b17ced70c0216b /events/event.h
parentbb14969dfa5e9e8a26a005a7f804f21a62460f68 (diff)
downloadlibquotient-c5f480355c7d4c000a4ee73fd7f8107a9a9340c2.tar.gz
libquotient-c5f480355c7d4c000a4ee73fd7f8107a9a9340c2.zip
Move all internal event pointers to std::unique_ptr<>
This causes the following changes along the way: - Owning<> template is decommissioned. - event.h has been rearranged, and Event/RoomEvent::fromJson static methods have been replaced with an external makeEvent<> function template. A side effect of that is that one cannot use a factory with a type other than the one it's defined for (i.e. you cannot call makeEvent<TypingEvent>) but that feature has been out of use for long anyway. - Room::doAddNewMessageEvents() and Room::doAddHistoricalMessageEvents() have been removed, giving place to Room::onAddNewTimelineEvents() and Room::onAddHistoricalTimelineEvents(). The most important difference is that all code that must be executed now resides in addNewMessageEvents() (it moved from Room to Room::Private) and classes inheriting from Room are not obliged to call the overridden function from the overriding function (they can do it but those functions have empty bodies in Room). This was a long overdue change, and owning pointers simply mandated it. Room::onAddNewTimelineEvents/onAddHistoricalTimelineEvents should not do anything with the passed range in terms of ownership, it's just a way to allow the derived class to update his data in due course. - Room::Private::dropDuplicateEvents() and Room::Private::insertEvents(), notably, have been updated to work with owning pointers. insertEvents() move()s pointers to the timeline, while dropDuplicateEvents uses remove_if instead of stable_partition and doesn't explicitly delete event objects. Also, a bugfix: Event accidentally had not virtual destructor for quite a long time. According to the standard, deleting an object through a pointer to a base class without a virtual destructor leads to UB. So the fact that libqmatrixclient clients even worked all these months is mere coincidence and compiler authors good will :-D
Diffstat (limited to 'events/event.h')
-rw-r--r--events/event.h54
1 files changed, 35 insertions, 19 deletions
diff --git a/events/event.h b/events/event.h
index bd33bb50..2b18bb46 100644
--- a/events/event.h
+++ b/events/event.h
@@ -25,8 +25,21 @@
#include "util.h"
+#include <memory>
+
namespace QMatrixClient
{
+ template <typename EventT>
+ using event_ptr_tt = std::unique_ptr<EventT>;
+
+ /** Create an event with proper type from a JSON object
+ * 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 <typename EventT>
+ event_ptr_tt<EventT> makeEvent(const QJsonObject& obj);
+
class Event
{
Q_GADGET
@@ -64,12 +77,6 @@ namespace QMatrixClient
// (and in most cases it will be a combination of other fields
// instead of "content" field).
- /** Create an event with proper type from a JSON object
- * Use this factory to detect the type from the JSON object contents
- * and create an event object of that type.
- */
- static Event* fromJson(const QJsonObject& obj);
-
protected:
const QJsonObject contentJson() const;
@@ -82,6 +89,10 @@ namespace QMatrixClient
Q_PROPERTY(QJsonObject contentJson READ contentJson CONSTANT)
};
using EventType = Event::Type;
+ using EventPtr = event_ptr_tt<Event>;
+
+ template <>
+ EventPtr makeEvent<Event>(const QJsonObject& obj);
/**
* \brief A vector of pointers to events with deserialisation capabilities
@@ -94,7 +105,7 @@ namespace QMatrixClient
* \tparam EventT base type of all events in the vector
*/
template <typename EventT>
- class EventsBatch : public std::vector<EventT*>
+ class EventsBatch : public std::vector<event_ptr_tt<EventT>>
{
public:
/**
@@ -120,8 +131,10 @@ namespace QMatrixClient
for (auto objValue: objs)
{
const auto o = objValue.toObject();
- auto e = EventT::fromJson(o);
- this->push_back(e ? e : new EventT(EventType::Unknown, o));
+ auto e { makeEvent<EventT>(o) };
+ if (!e)
+ e.reset(new EventT(EventType::Unknown, o));
+ this->emplace_back(std::move(e));
}
}
};
@@ -151,10 +164,10 @@ namespace QMatrixClient
const QDateTime& timestamp() const { return _serverTimestamp; }
const QString& roomId() const { return _roomId; }
const QString& senderId() const { return _senderId; }
- bool isRedacted() const { return redactedBecause(); }
- RedactionEvent* redactedBecause() const
+ bool isRedacted() const { return bool(_redactedBecause); }
+ const RedactionEvent* redactedBecause() const
{
- return _redactedBecause.data();
+ return _redactedBecause.get();
}
QString redactionReason() const;
const QString& transactionId() const { return _txnId; }
@@ -180,18 +193,19 @@ namespace QMatrixClient
*/
void addId(const QString& id);
- // "Static override" of the one in Event
- static RoomEvent* fromJson(const QJsonObject& obj);
-
private:
QString _id;
QString _roomId;
QString _senderId;
QDateTime _serverTimestamp;
- QScopedPointer<RedactionEvent> _redactedBecause;
+ event_ptr_tt<RedactionEvent> _redactedBecause;
QString _txnId;
};
using RoomEvents = EventsBatch<RoomEvent>;
+ using RoomEventPtr = event_ptr_tt<RoomEvent>;
+
+ template <>
+ RoomEventPtr makeEvent<RoomEvent>(const QJsonObject& obj);
/**
* Conceptually similar to QStringView (but much more primitive), it's a
@@ -199,10 +213,10 @@ namespace QMatrixClient
* referring to the beginning and the end of a range in a RoomEvents
* container.
*/
- struct RoomEventsView
+ struct RoomEventsRange
{
- RoomEvents::const_iterator from;
- RoomEvents::const_iterator to;
+ RoomEvents::iterator from;
+ RoomEvents::iterator to;
RoomEvents::size_type size() const
{
@@ -212,6 +226,8 @@ namespace QMatrixClient
bool empty() const { return from == to; }
RoomEvents::const_iterator begin() const { return from; }
RoomEvents::const_iterator end() const { return to; }
+ RoomEvents::iterator begin() { return from; }
+ RoomEvents::iterator end() { return to; }
};
template <typename ContentT>