background thread for STDIN reading + proxy with signals/slots for passing data to the GUI thread
--- a/nbproject/configurations.xml Fri Sep 28 13:23:21 2018 +0200
+++ b/nbproject/configurations.xml Sat Sep 29 00:43:16 2018 +0200
@@ -60,6 +60,7 @@
projectFiles="true"
root="build/Debug/src/relpipe-out-chart_autogen">
<logicalFolder name="EWIEGA46WW" displayName="EWIEGA46WW" projectFiles="true">
+ <itemPath>build/Debug/src/relpipe-out-chart_autogen/EWIEGA46WW/moc_QtRelationalReaderStringHadler.cpp</itemPath>
<itemPath>build/Debug/src/relpipe-out-chart_autogen/EWIEGA46WW/moc_RelpipeChartMainWindow.cpp</itemPath>
</logicalFolder>
<logicalFolder name="include" displayName="include" projectFiles="true">
@@ -90,9 +91,6 @@
</toolsSet>
<flagsDictionary>
<element flagsID="0" commonFlags="-fsanitize=address -fPIC -std=gnu++11"/>
- <element flagsID="1"
- commonFlags="-mtune=generic -march=x86-64 -std=gnu++11 -fsanitize=address -fPIC -fstack-protector-strong"/>
- <element flagsID="2" commonFlags="-std=c++14"/>
</flagsDictionary>
<codeAssistance>
</codeAssistance>
@@ -102,6 +100,27 @@
<buildCommand>${MAKE} -f Makefile</buildCommand>
<cleanCommand>${MAKE} -f Makefile clean</cleanCommand>
<executablePath>build/Debug/src/relpipe-out-chart</executablePath>
+ <ccTool>
+ <incDir>
+ <pElem>build/Debug/src</pElem>
+ <pElem>src</pElem>
+ <pElem>build/Debug/src/relpipe-out-chart_autogen/include</pElem>
+ <pElem>../relpipe-lib-reader.cpp/include</pElem>
+ <pElem>../relpipe-lib-cli.cpp/include</pElem>
+ <pElem>/usr/include/x86_64-linux-gnu/qt5</pElem>
+ <pElem>/usr/include/x86_64-linux-gnu/qt5/QtWidgets</pElem>
+ <pElem>/usr/include/x86_64-linux-gnu/qt5/QtGui</pElem>
+ <pElem>/usr/include/x86_64-linux-gnu/qt5/QtCore</pElem>
+ <pElem>/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++</pElem>
+ <pElem>/usr/include/x86_64-linux-gnu/qt5/QtCharts</pElem>
+ </incDir>
+ <preprocessorList>
+ <Elem>QT_CHARTS_LIB</Elem>
+ <Elem>QT_CORE_LIB</Elem>
+ <Elem>QT_GUI_LIB</Elem>
+ <Elem>QT_WIDGETS_LIB</Elem>
+ </preprocessorList>
+ </ccTool>
</makeTool>
<preBuild>
<preBuildCommandWorkingDir>build/Debug</preBuildCommandWorkingDir>
@@ -113,8 +132,11 @@
ex="false"
tool="1"
flavor2="11">
- <ccTool flags="2">
- </ccTool>
+ </item>
+ <item path="build/Debug/src/relpipe-out-chart_autogen/EWIEGA46WW/moc_QtRelationalReaderStringHadler.cpp"
+ ex="true"
+ tool="3"
+ flavor2="0">
</item>
<item path="build/Debug/src/relpipe-out-chart_autogen/EWIEGA46WW/moc_RelpipeChartMainWindow.cpp"
ex="true"
@@ -125,87 +147,22 @@
ex="false"
tool="1"
flavor2="8">
- <ccTool flags="1">
+ <ccTool flags="0">
</ccTool>
</item>
<folder path="Modules">
<ccTool>
<incDir>
- <pElem>build/Debug/src</pElem>
- <pElem>src</pElem>
- <pElem>build/Debug/src/relpipe-out-chart_autogen/include</pElem>
- <pElem>../relpipe-lib-reader.cpp/include</pElem>
- <pElem>../relpipe-lib-cli.cpp/include</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5/QtWidgets</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5/QtGui</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5/QtCore</pElem>
- <pElem>/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5/QtCharts</pElem>
<pElem>/usr/include</pElem>
</incDir>
- <preprocessorList>
- <Elem>QT_CHARTS_LIB</Elem>
- <Elem>QT_CORE_LIB</Elem>
- <Elem>QT_GUI_LIB</Elem>
- <Elem>QT_WIDGETS_LIB</Elem>
- </preprocessorList>
- </ccTool>
- </folder>
- <folder path="relpipe-out-chart_autogen">
- <ccTool>
- <incDir>
- <pElem>build/Debug/src/relpipe-out-chart_autogen/EWIEGA46WW</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5/QtCore</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5/QtGui</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5/QtWidgets</pElem>
- <pElem>build/Debug/src/relpipe-out-chart_autogen/include</pElem>
- <pElem>src</pElem>
- <pElem>build/Debug/src/relpipe-out-chart_autogen</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5</pElem>
- <pElem>build/Debug/src</pElem>
- </incDir>
</ccTool>
</folder>
<item path="src/RelpipeChartMainWindow.cpp" ex="false" tool="1" flavor2="8">
<ccTool flags="0">
- <incDir>
- <pElem>build/Debug/src</pElem>
- <pElem>src</pElem>
- <pElem>build/Debug/src/relpipe-out-chart_autogen/include</pElem>
- <pElem>../relpipe-lib-reader.cpp/include</pElem>
- <pElem>../relpipe-lib-cli.cpp/include</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5/QtWidgets</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5/QtGui</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5/QtCore</pElem>
- <pElem>/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5/QtCharts</pElem>
- </incDir>
- <preprocessorList>
- <Elem>QT_CHARTS_LIB</Elem>
- <Elem>QT_CORE_LIB</Elem>
- <Elem>QT_GUI_LIB</Elem>
- <Elem>QT_WIDGETS_LIB</Elem>
- </preprocessorList>
</ccTool>
</item>
<item path="src/relpipe-out-chart.cpp" ex="false" tool="1" flavor2="8">
- <ccTool flags="1">
- <incDir>
- <pElem>../relpipe-lib-cli.cpp/include/relpipe/cli</pElem>
- <pElem>src</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5/QtCore</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5/QtGui</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5/QtWidgets</pElem>
- <pElem>../relpipe-lib-reader.cpp/include/relpipe/reader</pElem>
- <pElem>../relpipe-lib-reader.cpp/include/relpipe/reader/handlers</pElem>
- <pElem>build/Debug/src/relpipe-out-chart_autogen/include</pElem>
- <pElem>../relpipe-lib-cli.cpp/include</pElem>
- <pElem>../relpipe-lib-reader.cpp/include</pElem>
- <pElem>/usr/include/x86_64-linux-gnu/qt5</pElem>
- <pElem>build/Debug/src</pElem>
- </incDir>
+ <ccTool flags="0">
</ccTool>
</item>
</conf>
--- a/src/CMakeLists.txt Fri Sep 28 13:23:21 2018 +0200
+++ b/src/CMakeLists.txt Sat Sep 29 00:43:16 2018 +0200
@@ -21,6 +21,7 @@
# Executable output:
add_executable(
${EXECUTABLE_FILE}
+ QtRelationalReaderStringHadler.h # QObjects must be listed here (including them from other files is not enough)
RelpipeChartMainWindow.ui
RelpipeChartMainWindow.cpp
relpipe-out-chart.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/QtRelationalReaderStringHadler.h Sat Sep 29 00:43:16 2018 +0200
@@ -0,0 +1,70 @@
+#pragma once
+
+#include <QObject>
+
+#include <relpipe/reader/typedefs.h>
+#include <relpipe/reader/TypeId.h>
+#include <relpipe/reader/handlers/RelationalReaderStringHandler.h>
+#include <relpipe/reader/handlers/AttributeMetadata.h>
+
+using namespace relpipe::reader;
+using namespace relpipe::reader::handlers;
+
+// signal/slot parameters must be declared here and registered with qRegisterMetaType()
+
+Q_DECLARE_METATYPE(string_t)
+Q_DECLARE_METATYPE(std::vector<AttributeMetadata>)
+
+class QtRelationalReaderStringHadler : public QObject, public RelationalReaderStringHadler {
+ Q_OBJECT
+private:
+ RelationalReaderStringHadler* target;
+public:
+
+ QtRelationalReaderStringHadler(QObject* parent, RelationalReaderStringHadler* target) :
+ QObject(parent), target(target) {
+
+ // see Q_DECLARE_METATYPE above
+ qRegisterMetaType<string_t>();
+ qRegisterMetaType<std::vector < AttributeMetadata >> ();
+
+ QObject::connect(this, &QtRelationalReaderStringHadler::signal_startRelation, this, &QtRelationalReaderStringHadler::slot_startRelation);
+ QObject::connect(this, &QtRelationalReaderStringHadler::signal_attribute, this, &QtRelationalReaderStringHadler::slot_attribute);
+ QObject::connect(this, &QtRelationalReaderStringHadler::signal_endOfPipe, this, &QtRelationalReaderStringHadler::slot_endOfPipe);
+ }
+
+ virtual ~QtRelationalReaderStringHadler() {
+
+ }
+
+ virtual void startRelation(string_t name, std::vector<AttributeMetadata> attributes) override {
+ emit signal_startRelation(name, attributes);
+ }
+
+ virtual void attribute(const string_t& value) override {
+ emit signal_attribute(value);
+ };
+
+ virtual void endOfPipe() override {
+ emit signal_endOfPipe();
+ };
+
+signals:
+ void signal_startRelation(string_t name, std::vector<AttributeMetadata> attributes);
+ void signal_attribute(const string_t& value);
+ void signal_endOfPipe();
+
+private slots:
+
+ void slot_startRelation(string_t name, std::vector<AttributeMetadata> attributes) {
+ target->startRelation(name, attributes);
+ };
+
+ void slot_attribute(const string_t& value) {
+ target->attribute(value);
+ };
+
+ void slot_endOfPipe() {
+ target->endOfPipe();
+ };
+};
--- a/src/RelpipeChartMainWindow.cpp Fri Sep 28 13:23:21 2018 +0200
+++ b/src/RelpipeChartMainWindow.cpp Sat Sep 29 00:43:16 2018 +0200
@@ -6,20 +6,25 @@
#include "RelpipeChartMainWindow.h"
+using namespace relpipe::reader;
+using namespace relpipe::reader::handlers;
+
RelpipeChartMainWindow::RelpipeChartMainWindow() {
widget.setupUi(this);
- QTabWidget* tabs = new QTabWidget(this);
+ tabs->addTab(new QPushButton("here will be options", tabs), "Options");
+
+ statusBar()->addWidget(new QLabel("Loading relations...", widget.statusbar));
+
- for (int i = 0; i < 5; i++) {
- QSplitter* splitter = new QSplitter(Qt::Orientation::Vertical, tabs);
- splitter->addWidget(new QPushButton("here will be the chart", splitter));
- splitter->addWidget(new QPushButton("here will be the table", splitter));
- tabs->addTab(splitter, "relation_name");
- }
-
- //statusBar()->addWidget(new QPushButton("xxx", widget.statusbar));
- statusBar()->addWidget(new QLabel("Loading relations...", widget.statusbar));
+ // TODO: remove; just demo
+ QPushButton* emitButton = new QPushButton("emit", widget.statusbar);
+ statusBar()->addWidget(emitButton);
+ QObject::connect(
+ emitButton, &QPushButton::pressed,
+ this, &RelpipeChartMainWindow::slot123
+ );
+ // ---
setCentralWidget(tabs);
@@ -27,3 +32,25 @@
RelpipeChartMainWindow::~RelpipeChartMainWindow() {
}
+
+void RelpipeChartMainWindow::slot123() {
+ // TODO: remove; just demo
+ statusBar()->addWidget(new QPushButton("slot123", widget.statusbar));
+}
+
+void RelpipeChartMainWindow::startRelation(string_t name, std::vector<AttributeMetadata> attributes) {
+ // TODO: chart and table
+ QSplitter* splitter = new QSplitter(Qt::Orientation::Vertical, tabs);
+ splitter->addWidget(new QPushButton("here will be the chart", splitter));
+ splitter->addWidget(new QPushButton("here will be the table", splitter));
+ tabs->addTab(splitter, QString::fromWCharArray(name.c_str()));
+}
+
+void RelpipeChartMainWindow::attribute(const string_t& value) {
+ // TODO: fill table and draw chart
+}
+
+void RelpipeChartMainWindow::endOfPipe() {
+ // TODO: just display a message
+ statusBar()->addWidget(new QPushButton("endOfPipe", widget.statusbar));
+}
--- a/src/RelpipeChartMainWindow.h Fri Sep 28 13:23:21 2018 +0200
+++ b/src/RelpipeChartMainWindow.h Sat Sep 29 00:43:16 2018 +0200
@@ -2,11 +2,27 @@
#include "ui_RelpipeChartMainWindow.h"
-class RelpipeChartMainWindow : public QMainWindow {
+#include <relpipe/reader/typedefs.h>
+#include <relpipe/reader/TypeId.h>
+#include <relpipe/reader/handlers/RelationalReaderStringHandler.h>
+#include <relpipe/reader/handlers/AttributeMetadata.h>
+
+using namespace relpipe::reader;
+using namespace relpipe::reader::handlers;
+
+class RelpipeChartMainWindow : public QMainWindow, public RelationalReaderStringHadler {
Q_OBJECT
public:
RelpipeChartMainWindow();
virtual ~RelpipeChartMainWindow();
+ virtual void startRelation(string_t name, std::vector<AttributeMetadata> attributes) override;
+ virtual void attribute(const string_t& value) override;
+ virtual void endOfPipe() override;
private:
Ui::RelpipeChartMainWindow widget;
+ QTabWidget* tabs = new QTabWidget(this);
+public slots:
+ void slot123();
+signals:
+ void signal123();
};
--- a/src/relpipe-out-chart.cpp Fri Sep 28 13:23:21 2018 +0200
+++ b/src/relpipe-out-chart.cpp Sat Sep 29 00:43:16 2018 +0200
@@ -1,6 +1,7 @@
#include <iostream>
#include <QApplication>
+#include <QThread>
#include <relpipe/cli/CLI.h>
#include <relpipe/cli/RelpipeCLIException.h>
@@ -9,24 +10,60 @@
#include <relpipe/reader/RelpipeReaderException.h>
#include "RelpipeChartMainWindow.h"
+#include "QtRelationalReaderStringHadler.h"
using namespace relpipe::cli;
using namespace relpipe::reader;
+class WorkerThread : public QThread {
+private:
+ std::shared_ptr<RelationalReader> reader;
+public:
+
+ // TODO: better background thread; lambda?
+
+ WorkerThread(std::shared_ptr<RelationalReader> reader) :
+ reader(reader) {
+ }
+
+ void run() {
+ try {
+ reader->process();
+ } catch (RelpipeReaderException& e) {
+ // TODO: handle exception, show error dialog
+ }
+ }
+};
+
int main(int argc, char**argv) {
CLI cli(argc, argv);
// TODO: argument name collisions? Filter arguments? Use prefix for Qt? Qt: -title, -style, -geometry
QApplication app(argc, argv);
-
+
std::cout << "TODO: relpipe-out-chart..." << std::endl;
-
+
std::shared_ptr<RelationalReader> reader(Factory::create(std::cin));
+
int resultCode = CLI::EXIT_CODE_UNEXPECTED_ERROR;
-
+
RelpipeChartMainWindow window;
+
+ // TODO: remove; just demo
+ QObject::connect(&window, &RelpipeChartMainWindow::signal123, &window, &RelpipeChartMainWindow::slot123);
+
window.show();
-
+
+ QtRelationalReaderStringHadler handler(&app, &window);
+ reader->addHandler(&handler);
+
+ // Start background thread
+ WorkerThread t(reader);
+ t.start();
+ // ---
+
+ // window.signal123();
+
app.exec();
//return app.exec();