diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-01-14 18:32:26 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-01-15 09:33:35 +0900 |
commit | 525be6dce815f88ed9cc97480bff461741665e8f (patch) | |
tree | 7f099b7b50b4854ac57a5bdd6212fb335b95c5e8 /events | |
parent | 93b170ceaced07a3de64708094bb68303a3d4440 (diff) | |
download | libquotient-525be6dce815f88ed9cc97480bff461741665e8f.tar.gz libquotient-525be6dce815f88ed9cc97480bff461741665e8f.zip |
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.
Diffstat (limited to 'events')
-rw-r--r-- | events/eventcontent.cpp | 14 | ||||
-rw-r--r-- | events/eventcontent.h | 66 | ||||
-rw-r--r-- | events/roommessageevent.cpp | 17 | ||||
-rw-r--r-- | events/roommessageevent.h | 28 |
4 files changed, 73 insertions, 52 deletions
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<ImageInfo>(*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 <QtCore/QUrl> #include <QtCore/QSize> +#include <functional> + namespace QMatrixClient { namespace EventContent @@ -144,6 +146,14 @@ namespace QMatrixClient QString originalName; }; + template <typename InfoT> + 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 InfoT, class... InfoMixinTs> - class UrlBasedContent : - public TypedBase, public InfoT, public InfoMixinTs... + template <class InfoT> + class UrlBasedContent : public TypedBase, public InfoT { public: + UrlBasedContent(QUrl url, InfoT&& info, QString filename = {}) + : InfoT(url, std::forward<InfoT>(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<InfoT>(*this)); + } + }; + + template <typename InfoT> + class UrlWithThumbnailContent : public UrlBasedContent<InfoT> + { + public: + // TODO: POD constructor + UrlWithThumbnailContent(const QJsonObject& json) + : UrlBasedContent<InfoT>(json) + , thumbnail(InfoT::originalInfoJson) + { } + + public: + Thumbnail thumbnail; + + protected: + void fillJson(QJsonObject* json) const override + { + UrlBasedContent<InfoT>::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<ImageInfo, WithThumbnail>; + using ImageContent = UrlWithThumbnailContent<ImageInfo>; /** * 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<FileInfo, WithThumbnail>; + using FileContent = UrlWithThumbnailContent<FileInfo>; } // 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 <typename ContentT> + 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<ImageInfo, WithThumbnail, WithDuration>; + using VideoContent = PlayableContent<UrlWithThumbnailContent<ImageInfo>>; /** * Content class for m.audio @@ -177,6 +187,6 @@ namespace QMatrixClient * - mimeType ("mimetype" in JSON) * - duration */ - using AudioContent = UrlBasedContent<FileInfo, WithDuration>; + using AudioContent = PlayableContent<UrlBasedContent<FileInfo>>; } // namespace EventContent } // namespace QMatrixClient |