From 525be6dce815f88ed9cc97480bff461741665e8f Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 14 Jan 2018 18:32:26 +0900 Subject: EventContent: rewrite without mixins MSVC is not good at dealing with type parameter packs of member functions, which is what the whole mixin magic in UrlBasedContent<> relied on. So it's one more level of inheritance instead of mixins now. --- events/eventcontent.cpp | 14 +++++----- events/eventcontent.h | 66 ++++++++++++++++++++++++++++++--------------- events/roommessageevent.cpp | 17 +++--------- events/roommessageevent.h | 28 ++++++++++++------- 4 files changed, 73 insertions(+), 52 deletions(-) (limited to 'events') diff --git a/events/eventcontent.cpp b/events/eventcontent.cpp index 271669e2..c96da9b3 100644 --- a/events/eventcontent.cpp +++ b/events/eventcontent.cpp @@ -74,15 +74,13 @@ void ImageInfo::fillInfoJson(QJsonObject* infoJson) const infoJson->insert("h", imageSize.height()); } -WithThumbnail::WithThumbnail(const QJsonObject& infoJson) - : thumbnail(infoJson["thumbnail_url"].toString(), - infoJson["thumbnail_info"].toObject()) +Thumbnail::Thumbnail(const QJsonObject& infoJson) + : ImageInfo(infoJson["thumbnail_url"].toString(), + infoJson["thumbnail_info"].toObject()) { } -void WithThumbnail::fillInfoJson(QJsonObject* infoJson) const +void Thumbnail::fillInfoJson(QJsonObject* infoJson) const { - infoJson->insert("thumbnail_url", thumbnail.url.toString()); - QJsonObject thumbnailInfoJson; - thumbnail.fillInfoJson(&thumbnailInfoJson); - infoJson->insert("thumbnail_info", thumbnailInfoJson); + infoJson->insert("thumbnail_url", url.toString()); + infoJson->insert("thumbnail_info", toInfoJson(*this)); } diff --git a/events/eventcontent.h b/events/eventcontent.h index b37dc923..91e4ca94 100644 --- a/events/eventcontent.h +++ b/events/eventcontent.h @@ -27,6 +27,8 @@ #include #include +#include + namespace QMatrixClient { namespace EventContent @@ -144,6 +146,14 @@ namespace QMatrixClient QString originalName; }; + template + QJsonObject toInfoJson(const InfoT& info) + { + QJsonObject infoJson; + info.fillInfoJson(&infoJson); + return infoJson; + } + /** * A content info class for image content types: image, thumbnail, video */ @@ -163,18 +173,18 @@ namespace QMatrixClient }; /** - * A mixin class for an info type that carries a thumbnail + * An auxiliary class for an info type that carries a thumbnail * * This class saves/loads a thumbnail to/from "info" subobject of * the JSON representation of event content; namely, * "info/thumbnail_url" and "info/thumbnail_info" fields are used. */ - class WithThumbnail + class Thumbnail : public ImageInfo { public: - WithThumbnail(const QJsonObject& infoJson); - WithThumbnail(const ImageInfo& info) - : thumbnail(info) + Thumbnail(const QJsonObject& infoJson); + Thumbnail(const ImageInfo& info) + : ImageInfo(info) { } /** @@ -182,9 +192,6 @@ namespace QMatrixClient * and thumbnail URL to "thumbnail_url" node inside "info". */ void fillInfoJson(QJsonObject* infoJson) const; - - public: - ImageInfo thumbnail; }; class TypedBase: public Base @@ -204,18 +211,18 @@ namespace QMatrixClient * the parameter type. * * \tparam InfoT base info class - * \tparam InfoMixinTs... additional info mixin classes (e.g. WithThumbnail) */ - template - class UrlBasedContent : - public TypedBase, public InfoT, public InfoMixinTs... + template + class UrlBasedContent : public TypedBase, public InfoT { public: + UrlBasedContent(QUrl url, InfoT&& info, QString filename = {}) + : InfoT(url, std::forward(info), filename) + { } explicit UrlBasedContent(const QJsonObject& json) : TypedBase(json) , InfoT(json["url"].toString(), json["info"].toObject(), json["filename"].toString()) - , InfoMixinTs(InfoT::originalInfoJson)... { } QMimeType type() const override { return InfoT::mimeType; } @@ -228,12 +235,29 @@ namespace QMatrixClient json->insert("url", InfoT::url.toString()); if (!InfoT::originalName.isEmpty()) json->insert("filename", InfoT::originalName); - QJsonObject infoJson; - InfoT::fillInfoJson(&infoJson); - // http://en.cppreference.com/w/cpp/language/parameter_pack#Brace-enclosed_initializers - // Looking forward to C++17 and its folding awesomeness. - int d[] = { (InfoMixinTs::fillInfoJson(&infoJson), 0)... }; - Q_UNUSED(d); + json->insert("info", toInfoJson(*this)); + } + }; + + template + class UrlWithThumbnailContent : public UrlBasedContent + { + public: + // TODO: POD constructor + UrlWithThumbnailContent(const QJsonObject& json) + : UrlBasedContent(json) + , thumbnail(InfoT::originalInfoJson) + { } + + public: + Thumbnail thumbnail; + + protected: + void fillJson(QJsonObject* json) const override + { + UrlBasedContent::fillJson(json); + auto infoJson = json->take("info").toObject(); + thumbnail.fillInfoJson(&infoJson); json->insert("info", infoJson); } }; @@ -256,7 +280,7 @@ namespace QMatrixClient * - mimeType * - imageSize */ - using ImageContent = UrlBasedContent; + using ImageContent = UrlWithThumbnailContent; /** * Content class for m.file @@ -274,6 +298,6 @@ namespace QMatrixClient * - thumbnail.mimeType * - thumbnail.imageSize (QSize for "h" and "w" in JSON) */ - using FileContent = UrlBasedContent; + using FileContent = UrlWithThumbnailContent; } // namespace EventContent } // namespace QMatrixClient diff --git a/events/roommessageevent.cpp b/events/roommessageevent.cpp index 20e81564..3c5d10ad 100644 --- a/events/roommessageevent.cpp +++ b/events/roommessageevent.cpp @@ -159,13 +159,13 @@ void TextContent::fillJson(QJsonObject* json) const } LocationContent::LocationContent(const QString& geoUri, const ImageInfo& thumbnail) - : WithThumbnail(thumbnail), geoUri(geoUri) + : geoUri(geoUri), thumbnail(thumbnail) { } LocationContent::LocationContent(const QJsonObject& json) : TypedBase(json) - , WithThumbnail(json["info"].toObject()) , geoUri(json["geo_uri"].toString()) + , thumbnail(json["info"].toObject()) { } QMimeType LocationContent::type() const @@ -177,16 +177,5 @@ void LocationContent::fillJson(QJsonObject* o) const { Q_ASSERT(o); o->insert("geo_uri", geoUri); - QJsonObject infoJson; - WithThumbnail::fillInfoJson(&infoJson); - o->insert("info", infoJson); -} - -WithDuration::WithDuration(const QJsonObject& infoJson) - : duration(infoJson["duration"].toInt()) -{ } - -void WithDuration::fillInfoJson(QJsonObject* infoJson) const -{ - infoJson->insert("duration", duration); + o->insert("info", toInfoJson(thumbnail)); } diff --git a/events/roommessageevent.h b/events/roommessageevent.h index 6b551b76..867d8880 100644 --- a/events/roommessageevent.h +++ b/events/roommessageevent.h @@ -112,7 +112,7 @@ namespace QMatrixClient * - thumbnail.mimeType * - thumbnail.imageSize */ - class LocationContent: public TypedBase, public WithThumbnail + class LocationContent: public TypedBase { public: LocationContent(const QString& geoUri, @@ -123,21 +123,32 @@ namespace QMatrixClient public: QString geoUri; + Thumbnail thumbnail; protected: void fillJson(QJsonObject* o) const override; }; /** - * A mixin class for info types that include duration: audio and video + * A base class for info types that include duration: audio and video */ - class WithDuration + template + class PlayableContent : public ContentT { public: - explicit WithDuration(int duration) : duration(duration) { } - WithDuration(const QJsonObject& infoJson); + PlayableContent(const QJsonObject& json) + : ContentT(json) + , duration(ContentT::originalInfoJson["duration"].toInt()) + { } - void fillInfoJson(QJsonObject* infoJson) const; + protected: + void fillJson(QJsonObject* json) const override + { + ContentT::fillJson(json); + auto infoJson = json->take("info").toObject(); + infoJson.insert("duration", duration); + json->insert("info", infoJson); + } public: int duration; @@ -162,8 +173,7 @@ namespace QMatrixClient * - mimeType * - imageSize */ - using VideoContent = - UrlBasedContent; + using VideoContent = PlayableContent>; /** * Content class for m.audio @@ -177,6 +187,6 @@ namespace QMatrixClient * - mimeType ("mimetype" in JSON) * - duration */ - using AudioContent = UrlBasedContent; + using AudioContent = PlayableContent>; } // namespace EventContent } // namespace QMatrixClient -- cgit v1.2.3