diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2017-05-22 10:22:28 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2017-05-22 10:22:28 +0900 |
commit | be838b2f4f294a7e1b3f8a771f91d9d1eac14431 (patch) | |
tree | f720ae5a5a52bdd48fdaec17dea3c1c32fe10cd9 /events/event.cpp | |
parent | 34764f3020c360ebc769cfe154e79b9e7e98f0f7 (diff) | |
download | libquotient-be838b2f4f294a7e1b3f8a771f91d9d1eac14431.tar.gz libquotient-be838b2f4f294a7e1b3f8a771f91d9d1eac14431.zip |
Refactored Events
The biggest change is we have no pimpls in Event objects anymore - because it's two new's instead of one per Event, and we have thousands and even more of Events created during initial sync. The other big change is introduction of RoomEvent, so that now the structure of events almost precisely reflects the CS API spec. The refactoring made UnknownEvent unnecessary as a separate class; a respective base class (either RoomEvent or Event) is used for this purpose now. All the other changes are consequences of these (mostly of RoomEvent introduction).
Diffstat (limited to 'events/event.cpp')
-rw-r--r-- | events/event.cpp | 148 |
1 files changed, 63 insertions, 85 deletions
diff --git a/events/event.cpp b/events/event.cpp index 5df816fe..bd7e1b03 100644 --- a/events/event.cpp +++ b/events/event.cpp @@ -18,9 +18,6 @@ #include "event.h" -#include <QtCore/QJsonArray> -#include <QtCore/QJsonDocument> - #include "roommessageevent.h" #include "roomnameevent.h" #include "roomaliasesevent.h" @@ -31,120 +28,101 @@ #include "receiptevent.h" #include "unknownevent.h" #include "logging.h" -#include "util.h" - -using namespace QMatrixClient; - -class Event::Private -{ - public: - EventType type; - QString id; - QDateTime timestamp; - QString roomId; - QString senderId; - QString originalJson; -}; -Event::Event(EventType type) - : d(new Private) -{ - d->type = type; -} +#include <QtCore/QJsonDocument> -Event::~Event() -{ - delete d; -} +using namespace QMatrixClient; -EventType Event::type() const +Event::Event(Type type, const QJsonObject& rep) + : _type(type), _originalJson(rep) { - return d->type; + if (!rep.contains("content")) + { + qCWarning(EVENTS) << "Event without 'content' node"; + qCWarning(EVENTS) << formatJson << rep; + } } -QString Event::id() const +QByteArray Event::originalJson() const { - return d->id; + return QJsonDocument(_originalJson).toJson(); } -QDateTime Event::timestamp() const +QDateTime Event::toTimestamp(const QJsonValue& v) { - return d->timestamp; + Q_ASSERT(v.isDouble()); + return QDateTime::fromMSecsSinceEpoch( + static_cast<long long int>(v.toDouble()), Qt::UTC); } -QString Event::roomId() const +QStringList Event::toStringList(const QJsonValue& v) { - return d->roomId; -} + Q_ASSERT(v.isArray()); -QString Event::senderId() const -{ - return d->senderId; + QStringList l; + for( const QJsonValue& e : v.toArray() ) + l.push_back(e.toString()); + return l; } -QString Event::originalJson() const +const QJsonObject Event::contentJson() const { - return d->originalJson; + return _originalJson["content"].toObject(); } template <typename EventT> -EventT* make(const QJsonObject& obj) +EventT* make(const QJsonObject& o) { - return EventT::fromJson(obj); + return new EventT(o); } Event* Event::fromJson(const QJsonObject& obj) { + // Check more specific event types first + if (auto e = RoomEvent::fromJson(obj)) + return e; + return dispatch<Event*>(obj).to(obj["type"].toString(), - "m.room.message", &make<RoomMessageEvent>, - "m.room.name", &make<RoomNameEvent>, - "m.room.aliases", &make<RoomAliasesEvent>, - "m.room.canonical_alias", &make<RoomCanonicalAliasEvent>, - "m.room.member", &make<RoomMemberEvent>, - "m.room.topic", &make<RoomTopicEvent>, - "m.typing", &make<TypingEvent>, - "m.receipt", &make<ReceiptEvent>, - /* Insert new event types BEFORE this line */ - &make<UnknownEvent> - ); + "m.typing", make<TypingEvent>, + "m.receipt", make<ReceiptEvent>, + /* Insert new event types (except room events) BEFORE this line */ + nullptr + ); } -bool Event::parseJson(const QJsonObject& obj) +RoomEvent::RoomEvent(Type type, const QJsonObject& rep) + : Event(type, rep), _id(rep["event_id"].toString()) + , _serverTimestamp(toTimestamp(rep["origin_server_ts"])) + , _roomId(rep["room_id"].toString()) + , _senderId(rep["sender"].toString()) { - d->originalJson = QString::fromUtf8(QJsonDocument(obj).toJson()); - d->id = obj.value("event_id").toString(); - d->roomId = obj.value("room_id").toString(); - d->senderId = obj.value("sender").toString(); - bool correct = (d->type != EventType::Unknown); - if ( d->type != EventType::Typing && - d->type != EventType::Receipt ) + if (_id.isEmpty()) { - if (d->id.isEmpty()) - { - correct = false; - qCDebug(EVENTS) << "Event: can't find event_id; event dump follows"; - qCDebug(EVENTS) << formatJson << obj; - } - if( obj.contains("origin_server_ts") ) - { - d->timestamp = QDateTime::fromMSecsSinceEpoch( - static_cast<qint64>(obj.value("origin_server_ts").toDouble()), Qt::UTC ); - } - else if (d->type != EventType::Unknown) - { - correct = false; - qCDebug(EVENTS) << "Event: can't find ts; event dump follows"; - qCDebug(EVENTS) << formatJson << obj; - } + qCWarning(EVENTS) << "Can't find event_id in a room event"; + qCWarning(EVENTS) << formatJson << rep; + } + if (!rep.contains("origin_server_ts")) + { + qCWarning(EVENTS) << "Event: can't find server timestamp in a room event"; + qCWarning(EVENTS) << formatJson << rep; + } + if (_senderId.isEmpty()) + { + qCWarning(EVENTS) << "user_id not found in a room event"; + qCWarning(EVENTS) << formatJson << rep; } - return correct; } -Events QMatrixClient::eventsFromJson(const QJsonArray& json) +RoomEvent* RoomEvent::fromJson(const QJsonObject& obj) { - Events evs; - evs.reserve(json.size()); - for (auto event: json) - evs.push_back(Event::fromJson(event.toObject())); - return evs; + return dispatch<RoomEvent*>(obj).to(obj["type"].toString(), + "m.room.message", make<RoomMessageEvent>, + "m.room.name", make<RoomNameEvent>, + "m.room.aliases", make<RoomAliasesEvent>, + "m.room.canonical_alias", make<RoomCanonicalAliasEvent>, + "m.room.member", make<RoomMemberEvent>, + "m.room.topic", make<RoomTopicEvent>, + /* Insert new ROOM event types BEFORE this line */ + nullptr + ); } |