aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2018-01-14 18:32:26 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2018-01-15 09:33:35 +0900
commit525be6dce815f88ed9cc97480bff461741665e8f (patch)
tree7f099b7b50b4854ac57a5bdd6212fb335b95c5e8
parent93b170ceaced07a3de64708094bb68303a3d4440 (diff)
downloadlibquotient-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.
-rw-r--r--events/eventcontent.cpp14
-rw-r--r--events/eventcontent.h66
-rw-r--r--events/roommessageevent.cpp17
-rw-r--r--events/roommessageevent.h28
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