aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/connection.cpp5
-rw-r--r--lib/events/event.cpp16
-rw-r--r--lib/events/event.h30
-rw-r--r--lib/room.cpp47
-rw-r--r--lib/room.h16
5 files changed, 68 insertions, 46 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index 5f930d57..adeb7929 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -306,9 +306,8 @@ void Connection::onSyncSuccess(SyncData &&data) {
{
if (accountEvent->type() == EventType::DirectChat)
{
- const auto usersToDCs =
- unique_ptr_cast<DirectChatEvent>(accountEvent)
- ->usersToDirectChats();
+ const auto usersToDCs = ptrCast<DirectChatEvent>(move(accountEvent))
+ ->usersToDirectChats();
DirectChatsMap removals =
erase_if(d->directChats, [&usersToDCs] (auto it) {
return !usersToDCs.contains(it.key()->id(), it.value());
diff --git a/lib/events/event.cpp b/lib/events/event.cpp
index 31520fc9..193250de 100644
--- a/lib/events/event.cpp
+++ b/lib/events/event.cpp
@@ -67,16 +67,17 @@ const QJsonObject Event::contentJson() const
}
template <typename BaseEventT>
-inline BaseEventT* makeIfMatches(const QJsonObject&, const QString&)
+inline event_ptr_tt<BaseEventT> makeIfMatches(const QJsonObject&, const QString&)
{
return nullptr;
}
template <typename BaseEventT, typename EventT, typename... EventTs>
-inline BaseEventT* makeIfMatches(const QJsonObject& o, const QString& selector)
+inline event_ptr_tt<BaseEventT> makeIfMatches(const QJsonObject& o,
+ const QString& selector)
{
if (selector == EventT::TypeId)
- return new EventT(o);
+ return _impl::create<EventT>(o);
return makeIfMatches<BaseEventT, EventTs...>(o, selector);
}
@@ -86,11 +87,11 @@ EventPtr _impl::doMakeEvent<Event>(const QJsonObject& obj)
{
// Check more specific event types first
if (auto e = doMakeEvent<RoomEvent>(obj))
- return EventPtr(move(e));
+ return e;
- return EventPtr { makeIfMatches<Event,
+ return makeIfMatches<Event,
TypingEvent, ReceiptEvent, TagEvent, ReadMarkerEvent, DirectChatEvent>(
- obj, obj["type"].toString()) };
+ obj, obj["type"].toString());
}
RoomEvent::RoomEvent(Event::Type type) : Event(type) { }
@@ -118,8 +119,7 @@ RoomEvent::RoomEvent(Type type, const QJsonObject& rep)
auto redaction = unsignedData.value("redacted_because");
if (redaction.isObject())
{
- _redactedBecause =
- std::make_unique<RedactionEvent>(redaction.toObject());
+ _redactedBecause = _impl::create<RedactionEvent>(redaction.toObject());
return;
}
diff --git a/lib/events/event.h b/lib/events/event.h
index 4e2b1071..396406f1 100644
--- a/lib/events/event.h
+++ b/lib/events/event.h
@@ -26,8 +26,32 @@ namespace QMatrixClient
template <typename EventT>
using event_ptr_tt = std::unique_ptr<EventT>;
+ template <typename EventT>
+ inline EventT* rawPtr(const event_ptr_tt<EventT>& ptr)
+ {
+ return ptr.get();
+ }
+
+ template <typename TargetEventT, typename EventT>
+ inline TargetEventT* weakPtr(const event_ptr_tt<EventT>& ptr)
+ {
+ return static_cast<TargetEventT*>(rawPtr(ptr));
+ }
+
+ template <typename TargetT, typename SourceT>
+ inline event_ptr_tt<TargetT> ptrCast(event_ptr_tt<SourceT>&& ptr)
+ {
+ return unique_ptr_cast<TargetT>(ptr);
+ }
+
namespace _impl
{
+ template <typename EventT, typename... ArgTs>
+ inline event_ptr_tt<EventT> create(ArgTs&&... args)
+ {
+ return std::make_unique<EventT>(std::forward<ArgTs>(args)...);
+ }
+
template <typename EventT>
event_ptr_tt<EventT> doMakeEvent(const QJsonObject& obj);
}
@@ -94,7 +118,7 @@ namespace QMatrixClient
{
auto e = _impl::doMakeEvent<EventT>(obj);
if (!e)
- e = std::make_unique<EventT>(EventType::Unknown, obj);
+ e = _impl::create<EventT>(EventType::Unknown, obj);
return e;
}
@@ -174,9 +198,9 @@ namespace QMatrixClient
QString roomId() const;
QString senderId() const;
bool isRedacted() const { return bool(_redactedBecause); }
- const RedactionEvent* redactedBecause() const
+ const event_ptr_tt<RedactionEvent>& redactedBecause() const
{
- return _redactedBecause.get();
+ return _redactedBecause;
}
QString redactionReason() const;
const QString& transactionId() const { return _txnId; }
diff --git a/lib/room.cpp b/lib/room.cpp
index 670c7d7c..a4cfadb4 100644
--- a/lib/room.cpp
+++ b/lib/room.cpp
@@ -205,7 +205,7 @@ class Room::Private
* Tries to find an event in the timeline and redact it; deletes the
* redaction event whether the redacted event was found or not.
*/
- void processRedaction(RoomEventPtr redactionEvent);
+ void processRedaction(RoomEventPtr&& redactionEvent);
void broadcastTagUpdates()
{
@@ -712,7 +712,7 @@ Room::Private::getEventWithFile(const QString& eventId) const
if (evtIt != timeline.rend() &&
evtIt->event()->type() == EventType::RoomMessage)
{
- auto* event = static_cast<const RoomMessageEvent*>(evtIt->event());
+ auto* event = evtIt->viewAs<RoomMessageEvent>();
if (event->hasFileContent())
return event;
}
@@ -1287,11 +1287,10 @@ inline bool isRedaction(const RoomEventPtr& e)
return e->type() == EventType::Redaction;
}
-void Room::Private::processRedaction(RoomEventPtr redactionEvent)
+void Room::Private::processRedaction(RoomEventPtr&& redactionEvent)
{
Q_ASSERT(redactionEvent && isRedaction(redactionEvent));
- const auto& redaction =
- static_cast<const RedactionEvent*>(redactionEvent.get());
+ const auto& redaction = ptrCast<RedactionEvent>(move(redactionEvent));
const auto pIdx = eventsIndex.find(redaction->redactedEvent());
if (pIdx == eventsIndex.end())
@@ -1360,9 +1359,9 @@ void Room::Private::processRedaction(RoomEventPtr redactionEvent)
// notify everyone and delete the old event
RoomEventPtr oldEvent
{ ti.replaceEvent(makeEvent<RoomEvent>(originalJson)) };
- q->onRedaction(oldEvent.get(), ti.event());
+ q->onRedaction(*oldEvent, *ti.event());
qCDebug(MAIN) << "Redacted" << oldEvent->id() << "with" << redaction->id();
- emit q->replacedEvent(ti.event(), oldEvent.get());
+ emit q->replacedEvent(ti.event(), rawPtr(oldEvent));
}
Connection* Room::connection() const
@@ -1456,25 +1455,24 @@ void Room::processStateEvents(const RoomEvents& events)
bool emitNamesChanged = false;
for (const auto& e: events)
{
- auto* event = e.get();
- switch (event->type())
+ switch (e->type())
{
case EventType::RoomName: {
- auto nameEvent = static_cast<RoomNameEvent*>(event);
+ auto* nameEvent = weakPtr<const RoomNameEvent>(e);
d->name = nameEvent->name();
qCDebug(MAIN) << "Room name updated:" << d->name;
emitNamesChanged = true;
break;
}
case EventType::RoomAliases: {
- auto aliasesEvent = static_cast<RoomAliasesEvent*>(event);
+ auto* aliasesEvent = weakPtr<const RoomAliasesEvent>(e);
d->aliases = aliasesEvent->aliases();
qCDebug(MAIN) << "Room aliases updated:" << d->aliases;
emitNamesChanged = true;
break;
}
case EventType::RoomCanonicalAlias: {
- auto aliasEvent = static_cast<RoomCanonicalAliasEvent*>(event);
+ auto* aliasEvent = weakPtr<const RoomCanonicalAliasEvent>(e);
d->canonicalAlias = aliasEvent->alias();
setObjectName(d->canonicalAlias);
qCDebug(MAIN) << "Room canonical alias updated:" << d->canonicalAlias;
@@ -1482,7 +1480,7 @@ void Room::processStateEvents(const RoomEvents& events)
break;
}
case EventType::RoomTopic: {
- auto topicEvent = static_cast<RoomTopicEvent*>(event);
+ auto* topicEvent = weakPtr<const RoomTopicEvent>(e);
d->topic = topicEvent->topic();
qCDebug(MAIN) << "Room topic updated:" << d->topic;
emit topicChanged();
@@ -1490,7 +1488,7 @@ void Room::processStateEvents(const RoomEvents& events)
}
case EventType::RoomAvatar: {
const auto& avatarEventContent =
- static_cast<RoomAvatarEvent*>(event)->content();
+ weakPtr<const RoomAvatarEvent>(e)->content();
if (d->avatar.updateUrl(avatarEventContent.url))
{
qCDebug(MAIN) << "Room avatar URL updated:"
@@ -1500,7 +1498,7 @@ void Room::processStateEvents(const RoomEvents& events)
break;
}
case EventType::RoomMember: {
- auto memberEvent = static_cast<RoomMemberEvent*>(event);
+ auto* memberEvent = weakPtr<const RoomMemberEvent>(e);
auto u = user(memberEvent->userId());
u->processEvent(memberEvent, this);
if (u == localUser() && memberJoinState(u) == JoinState::Invite
@@ -1541,7 +1539,7 @@ void Room::processStateEvents(const RoomEvents& events)
case EventType::RoomEncryption:
{
d->encryptionAlgorithm =
- static_cast<EncryptionEvent*>(event)->algorithm();
+ weakPtr<const EncryptionEvent>(e)->algorithm();
qCDebug(MAIN) << "Encryption switched on in" << displayName();
emit encryption();
break;
@@ -1555,13 +1553,13 @@ void Room::processStateEvents(const RoomEvents& events)
d->updateDisplayname();
}
-void Room::processEphemeralEvent(EventPtr event)
+void Room::processEphemeralEvent(EventPtr&& event)
{
QElapsedTimer et; et.start();
switch (event->type())
{
case EventType::Typing: {
- auto typingEvent = static_cast<TypingEvent*>(event.get());
+ auto typingEvent = ptrCast<TypingEvent>(move(event));
d->usersTyping.clear();
for( const QString& userId: typingEvent->users() )
{
@@ -1576,7 +1574,7 @@ void Room::processEphemeralEvent(EventPtr event)
break;
}
case EventType::Receipt: {
- auto receiptEvent = static_cast<ReceiptEvent*>(event.get());
+ auto receiptEvent = ptrCast<ReceiptEvent>(move(event));
for( const auto &p: receiptEvent->eventsWithReceipts() )
{
{
@@ -1630,13 +1628,13 @@ void Room::processEphemeralEvent(EventPtr event)
}
}
-void Room::processAccountDataEvent(EventPtr event)
+void Room::processAccountDataEvent(EventPtr&& event)
{
switch (event->type())
{
case EventType::Tag:
{
- auto newTags = static_cast<TagEvent*>(event.get())->tags();
+ auto newTags = ptrCast<const TagEvent>(move(event))->tags();
if (newTags == d->tags)
break;
d->tags = newTags;
@@ -1647,16 +1645,15 @@ void Room::processAccountDataEvent(EventPtr event)
}
case EventType::ReadMarker:
{
- const auto* rmEvent = static_cast<ReadMarkerEvent*>(event.get());
- const auto& readEventId = rmEvent->event_id();
+ auto readEventId =
+ ptrCast<const ReadMarkerEvent>(move(event))->event_id();
qCDebug(MAIN) << "Server-side read marker at" << readEventId;
d->serverReadMarker = readEventId;
const auto newMarker = findInTimeline(readEventId);
if (newMarker != timelineEdge())
d->markMessagesAsRead(newMarker);
- else {
+ else
d->setLastReadEvent(localUser(), readEventId);
- }
break;
}
default:
diff --git a/lib/room.h b/lib/room.h
index 86a7b245..288db5fb 100644
--- a/lib/room.h
+++ b/lib/room.h
@@ -46,10 +46,12 @@ namespace QMatrixClient
using index_t = int;
TimelineItem(RoomEventPtr&& e, index_t number)
- : evt(move(e)), idx(number) { }
+ : evt(std::move(e)), idx(number) { }
- RoomEvent* event() const { return evt.get(); }
- RoomEvent* operator->() const { return evt.operator->(); }
+ const RoomEvent* event() const { return rawPtr(evt); }
+ template <typename EventT>
+ const EventT* viewAs() const { return weakPtr<const EventT>(evt); }
+ const RoomEventPtr& operator->() const { return evt; }
index_t index() const { return idx; }
// Used for event redaction
@@ -407,12 +409,12 @@ namespace QMatrixClient
protected:
virtual void processStateEvents(const RoomEvents& events);
- virtual void processEphemeralEvent(EventPtr event);
- virtual void processAccountDataEvent(EventPtr event);
+ virtual void processEphemeralEvent(EventPtr&& event);
+ virtual void processAccountDataEvent(EventPtr&& event);
virtual void onAddNewTimelineEvents(timeline_iter_t from) { }
virtual void onAddHistoricalTimelineEvents(rev_iter_t from) { }
- virtual void onRedaction(const RoomEvent* prevEvent,
- const RoomEvent* after) { }
+ virtual void onRedaction(const RoomEvent& prevEvent,
+ const RoomEvent& after) { }
private:
class Private;