Commit 514ac585 authored by EXT Arnaud Clère's avatar EXT Arnaud Clère
Browse files

Removed generic Utf8Result that relied on utf8 encoding assumption from

TWriter but could be used with QCborWriter
Simplified TextWriter
WIP: using QModelWriter to populate a QStandardModel and view it in
various ways thanks to MetaData
parent 9486cdb8
......@@ -4,7 +4,10 @@
#
#-------------------------------------------------
QT += widgets
TARGET = QBind
CONFIG += console
CONFIG -= app_bundle
......@@ -31,4 +34,5 @@ HEADERS += \
QCbor_impl.h \
QJson_impl.h \
QVariant_impl.h \
QModel_impl.h \
QData_impl.h
......@@ -491,22 +491,6 @@ public:
TResult bind(Val<TResult> v) { return f(std::move(v)); }
};
// //////////////////////////////////////////////////////////////////////////
// Simple Result classes
#include <QtCore/qbuffer.h>
template<class TWriter, typename = IsWriter<TWriter>>
class QUtf8Result
{
public:
template<typename T> QUtf8Result(T&& t) : writer(&result) { result.open(QIODevice::WriteOnly); writer.bind(std::forward<T>(t)); }
operator QUtf8String() const { return result.buffer(); }
private:
QBuffer result;
TWriter writer;
};
// //////////////////////////////////////////////////////////////////////////
// QBind partial specializations (generic on TResult, usually not on TResult::Mode for dynamically-sized or builtin types)
......
......@@ -50,20 +50,23 @@
// //////////////////////////////////////////////////////////////////////////
// QBind<Q*Model,T> support
class ModelWriter : public IWriter
class QModelWriter : public IWriter
{
Q_DISABLE_COPY(ModelWriter)
Q_DISABLE_COPY(QModelWriter)
enum : int {
T=0, //!< nothing called
S=1, //!< sequence() called, expecting out() or item()... calls
R=2, //!< record () called, expecting out() or item(key)... calls
};
public:
ModelWriter(QAbstractItemModel* m) : m(m), b(&item) { Q_ASSERT(m); }
QModelWriter(QAbstractItemModel* m) : m(m) { Q_ASSERT(m); }
Val<Writer> meta(MetaData& m) { return Writer(this).meta(m); }
Val<QWriter> meta(MetaData&& m) { return QWriter(this).meta(m); }
protected:
void _meta(MetaData& meta) {
if (meta.find(qmChildren)!=meta.end()) {
childrenName = meta[qmChildren].toUtf8();
}
if (meta.find(qmColumns)!=meta.end()) {
int i=0;
Q_FOREACH(auto k,meta[qmColumns].split(',')) {
......@@ -71,6 +74,11 @@ protected:
m->setHeaderData(i++,Qt::Horizontal,k);
}
}
if (meta.find(qmSizes)!=meta.end()) {
Q_FOREACH(auto k,meta[qmSizes].split(',')) {
sizes.append(k.toUtf8().toInt());
}
}
}
bool _null( ) { return m->setData(idx, QVariant( )); }
......@@ -88,12 +96,14 @@ protected:
bool _sequence (quint32* s=nullptr) { if (d==T) { ++d; return true; } return false; }
bool _record (quint32* s=nullptr) { if (d==S) { ++d; return true; } return false; }
bool _item ( ) { if (d==S) { m->insertRows (idx.row(),1); idx=idx.siblingAtRow (idx.row()+1 ); return true; } return false; }
bool _item ( QByteArray& k) { if (d==R) { // TODO Handle names.indexOf(k)<0
bool _item ( QByteArray& k) { if (d==R) { // TODO Handle childrenName and names.indexOf(k)<0
idx=idx.siblingAtColumn(names.indexOf(k)); return true; } return false; }
private:
QAbstractItemModel* m;
QModelIndex idx;
QByteArray childrenName;
QByteArrayList names;
QVector<int> sizes;
int d=T; // bind depth wrt successive fluent interface calls
// TODO setHeaderData on 1st item and
......
......@@ -50,9 +50,15 @@
#include "QCbor_impl.h" // QCborWriter demonstrating the performance potential of the approach
#include "QData_impl.h" // QDataReader, QDataWriter demonstrating a QDataStream with implicit types for benchmarking
#include "QVariant_impl.h" // QVariantBuilder, QVariantVisitor and QBind<_,QVariant> support
#include "QModel_impl.h" // Q*ModelWriter support
#include <QtCore/qvariant.h>
#include <QtGui/qstandarditemmodel.h>
#include <QtWidgets/qtreeview.h>
#include <QtWidgets/qtableview.h>
#include <QtWidgets/qapplication.h>
// //////////////////////////////////////////////////////////////////////////
// QBind<_,T> basic example using an internal bind<TResult> method
......@@ -97,19 +103,17 @@ QDataStream &operator<<(QDataStream &out, const Person &p)
#include <QtCore/qiodevice.h>
#include <QtCore/qbuffer.h>
class TextWriter : public QBaseWriter<TextWriter>
class TextWriter : public IWriter
{
Q_PROTECTED_COPY(TextWriter)
Q_DISABLE_COPY(TextWriter)
public:
Q_ENABLE_MOVE_DEFAULT(TextWriter) // for QBaseWriter
TextWriter(QIODevice* io) : io(io) { Q_ASSERT(io); }
operator bool() { return io; } // for QBaseWriter
// Shortcuts
/**/ Seq<QWriter> sequence(quint32* s=nullptr) { return QWriter(this).sequence ( s); }
template<typename T> QWriter bind ( T&& t) { return QWriter(this).bind(std::forward<T>(t)); }
protected:
friend class QBaseWriter<TextWriter>;
template<class T_> friend class Val; // enables calling methods below
template<class T_> friend class Seq;
template<class T_> friend class Rec;
bool _isOk() { return io; }
bool _sequence(quint32* cols=nullptr) { Q_UNUSED(cols); return io->write("["); }
bool _record (quint32* rows=nullptr) { Q_UNUSED(rows); return io->write("["); }
......@@ -124,7 +128,15 @@ private:
};
template<> struct BindSupport<TextWriter,const char*> : BindNative {};
using Text = QUtf8Result<TextWriter>;
#include <QtCore/qbuffer.h>
class Text : public TextWriter
{
QBuffer result;
public:
template<typename T> Text(T&& t) : TextWriter(&result) { result.open(QIODevice::WriteOnly); bind(std::forward<T>(t)); }
operator QUtf8String() const { return result.buffer(); }
};
// //////////////////////////////////////////////////////////////////////////
// Tests and Benchmarks
......@@ -160,8 +172,10 @@ static QElapsedTimer item;
auto usecs=double(item.nsecsElapsed())/1000/123; groupTotal+=usecs; \
if (previousTotal<0.01) { fprintf(results,"|%14s", label); fprintf(samples, "%-14s|%s\n", label, qPrintable(result)); } else fprintf(results,"|%14.1f", usecs); }
int main()
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// Generated files
FILE* results; fopen_s(&results, "results.csv", "w");
FILE* samples; fopen_s(&samples, "samples.txt", "w");
......@@ -457,27 +471,6 @@ int main()
STOP("Writable>Json",QString::fromUtf8(b.buffer()));
}
GROUP_STOP
GROUP("<Persons")
{
QVector<Person> persons;
persons << person << person << person;
START {
b.seek(0); b.buffer().clear();
QCborWriter(&b).meta({{qmChildren,"children" }}).bind(persons);
}
STOP("Cbor trees",QString::fromUtf8(b.buffer().toHex()));
START {
b.seek(0); b.buffer().clear();
QCborWriter(&b).meta({{qmColumns ,"names,age"}}).bind(persons);
}
STOP("Cbor table",QString::fromUtf8(b.buffer().toHex()));
START {
b.seek(0); b.buffer().clear();
QCborWriter(&b).meta({{qmSizes ,"4,4" }}).bind(transform);
}
STOP("Cbor array",QString::fromUtf8(b.buffer().toHex()));
}
GROUP_STOP
GROUP("Read+Write")
{
QBuffer json;
......@@ -531,5 +524,29 @@ int main()
STOP("JsonValue>Cbor",QString::fromUtf8(b.buffer().toHex()));
}
GROUP_STOP
{
QVector<Person> persons;
persons << person << person << person;
QStandardItemModel m;
{
m.clear();
QModelWriter(&m).meta({{qmChildren,"phones" },{qmColumns ,"names,age"}}).bind(persons);
}
QTreeView v;
m.setHorizontalHeaderLabels({"names"});
v.setModel(&m);
v.setUniformRowHeights(true);
v.show();
{
m.clear();
QModelWriter(&m).meta({{qmColumns ,"names,age"}}).bind(persons);
}
{
m.clear();
QModelWriter(&m).meta({{qmSizes ,"4,4" }}).bind(transform);
}
}
return (fclose(samples)==0) &/*anyway*/ (fclose(results)==0);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment