├── README.md ├── examples ├── qml │ └── flux_qt_qml │ │ ├── qml.qrc │ │ ├── app │ │ ├── action │ │ │ ├── actiontypes.h │ │ │ ├── actionprovider.cpp │ │ │ └── actionprovider.h │ │ ├── app.pri │ │ ├── service │ │ │ ├── ftpservice.h │ │ │ ├── ftpserviceworker.cpp │ │ │ ├── ftpserviceworker.h │ │ │ └── ftpservice.cpp │ │ ├── middleware │ │ │ ├── ftpmiddleware.h │ │ │ └── ftpmiddleware.cpp │ │ └── store │ │ │ ├── mainstore.h │ │ │ └── mainstore.cpp │ │ ├── flux_qt_qml.pro │ │ ├── main.cpp │ │ └── main.qml └── console │ └── flux_qt_console │ ├── app │ ├── action │ │ └── actiontypes.h │ ├── app.pri │ ├── store │ │ ├── mainstore.h │ │ └── mainstore.cpp │ ├── service │ │ ├── ftpservice.h │ │ ├── ftpserviceworker.cpp │ │ ├── ftpserviceworker.h │ │ └── ftpservice.cpp │ └── middleware │ │ ├── ftpmiddleware.h │ │ └── ftpmiddleware.cpp │ ├── flux_qt_console.pro │ └── main.cpp ├── flux_qt ├── flux_qt.pri └── flux_qt │ ├── store.h │ ├── middleware.h │ ├── action.h │ └── dispatcher.h └── LICENSE /README.md: -------------------------------------------------------------------------------- 1 | # flux_qt 2 | C++ Qt5-based header only implementation of the Facebook Flux-like pattern 3 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/qml.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | main.qml 4 | 5 | 6 | -------------------------------------------------------------------------------- /flux_qt/flux_qt.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += \ 2 | $$PWD 3 | 4 | HEADERS += \ 5 | $$PWD/flux_qt/action.h \ 6 | $$PWD/flux_qt/dispatcher.h \ 7 | $$PWD/flux_qt/middleware.h \ 8 | $$PWD/flux_qt/store.h 9 | -------------------------------------------------------------------------------- /examples/console/flux_qt_console/app/action/actiontypes.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSOLE_ACTION_TYPES_H 2 | #define CONSOLE_ACTION_TYPES_H 3 | 4 | enum class ActionType 5 | { 6 | UploadFtp, 7 | UploadFtpStarted, 8 | UploadFtpProcess, 9 | UploadFtpFinished 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/app/action/actiontypes.h: -------------------------------------------------------------------------------- 1 | #ifndef QML_ACTION_TYPES_H 2 | #define QML_ACTION_TYPES_H 3 | 4 | enum class ActionType 5 | { 6 | ShowFileDialog, 7 | SelectFile, 8 | UploadFtp, 9 | UploadFtpStarted, 10 | UploadFtpProcess, 11 | UploadFtpFinished 12 | }; 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /examples/console/flux_qt_console/app/app.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += \ 2 | $$PWD 3 | 4 | LIBS += 5 | 6 | HEADERS += \ 7 | $$PWD/action/actiontypes.h \ 8 | $$PWD/middleware/ftpmiddleware.h \ 9 | $$PWD/service/ftpservice.h \ 10 | $$PWD/store/mainstore.h \ 11 | $$PWD/service/ftpserviceworker.h 12 | 13 | 14 | SOURCES += \ 15 | $$PWD/middleware/ftpmiddleware.cpp \ 16 | $$PWD/service/ftpservice.cpp \ 17 | $$PWD/store/mainstore.cpp \ 18 | $$PWD/service/ftpserviceworker.cpp 19 | -------------------------------------------------------------------------------- /examples/console/flux_qt_console/flux_qt_console.pro: -------------------------------------------------------------------------------- 1 | QT -= gui 2 | 3 | CONFIG += c++11 console 4 | CONFIG -= app_bundle 5 | 6 | # The following define makes your compiler emit warnings if you use 7 | # any feature of Qt which as been marked deprecated (the exact warnings 8 | # depend on your compiler). Please consult the documentation of the 9 | # deprecated API in order to know how to port your code away from it. 10 | DEFINES += QT_DEPRECATED_WARNINGS 11 | 12 | SOURCES += main.cpp 13 | 14 | include(../../../flux_qt/flux_qt.pri) 15 | include(app/app.pri) 16 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/app/app.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += \ 2 | $$PWD 3 | 4 | LIBS += 5 | 6 | HEADERS += \ 7 | $$PWD/action/actiontypes.h \ 8 | $$PWD/middleware/ftpmiddleware.h \ 9 | $$PWD/service/ftpservice.h \ 10 | $$PWD/store/mainstore.h \ 11 | $$PWD/service/ftpserviceworker.h \ 12 | $$PWD/action/actionprovider.h 13 | 14 | 15 | SOURCES += \ 16 | $$PWD/middleware/ftpmiddleware.cpp \ 17 | $$PWD/service/ftpservice.cpp \ 18 | $$PWD/store/mainstore.cpp \ 19 | $$PWD/service/ftpserviceworker.cpp \ 20 | $$PWD/action/actionprovider.cpp 21 | -------------------------------------------------------------------------------- /flux_qt/flux_qt/store.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUX_QT_STORE_H 2 | #define FLUX_QT_STORE_H 3 | 4 | #include 5 | 6 | namespace flux_qt 7 | { 8 | class Action; 9 | 10 | class Store 11 | { 12 | public: 13 | virtual ~Store() = default; 14 | 15 | virtual void process(const QSharedPointer& action) = 0; 16 | 17 | protected: 18 | Store() = default; 19 | Store(const Store&) = default; 20 | Store(Store&&) = default; 21 | Store& operator=(const Store&) = default; 22 | Store& operator=(Store&&) = default; 23 | }; 24 | 25 | } 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /flux_qt/flux_qt/middleware.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUX_QT_MIDDLEWARE_H 2 | #define FLUX_QT_MIDDLEWARE_H 3 | 4 | #include 5 | 6 | namespace flux_qt 7 | { 8 | class Action; 9 | 10 | class Middleware 11 | { 12 | public: 13 | virtual ~Middleware() = default; 14 | 15 | virtual QSharedPointer process(const QSharedPointer& action) = 0; 16 | 17 | protected: 18 | Middleware() = default; 19 | Middleware(const Middleware&) = default; 20 | Middleware(Middleware&&) = default; 21 | Middleware& operator=(const Middleware&) = default; 22 | Middleware& operator=(Middleware&&) = default; 23 | }; 24 | 25 | } 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/flux_qt_qml.pro: -------------------------------------------------------------------------------- 1 | QT += quick quickcontrols2 2 | CONFIG += c++11 3 | 4 | # The following define makes your compiler emit warnings if you use 5 | # any feature of Qt which as been marked deprecated (the exact warnings 6 | # depend on your compiler). Please consult the documentation of the 7 | # deprecated API in order to know how to port your code away from it. 8 | DEFINES += QT_DEPRECATED_WARNINGSs 9 | 10 | SOURCES += main.cpp 11 | 12 | RESOURCES += qml.qrc 13 | 14 | # Additional import path used to resolve QML modules in Qt Creator's code model 15 | QML_IMPORT_PATH = 16 | 17 | include(../../../flux_qt/flux_qt.pri) 18 | include(app/app.pri) 19 | -------------------------------------------------------------------------------- /examples/console/flux_qt_console/app/store/mainstore.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSOLE_MAIN_STORE_H 2 | #define CONSOLE_MAIN_STORE_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | class MainStore final : public flux_qt::Store 10 | { 11 | public: 12 | MainStore() = default; 13 | MainStore(const MainStore&) = default; 14 | MainStore(MainStore&&) = default; 15 | MainStore& operator=(const MainStore&) = default; 16 | MainStore& operator=(MainStore&&) = default; 17 | ~MainStore() = default; 18 | 19 | void process(const QSharedPointer& action) Q_DECL_OVERRIDE; 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /examples/console/flux_qt_console/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace flux_qt; 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | QCoreApplication a(argc, argv); 15 | 16 | Dispatcher::instance().registerMiddleware(new FtpMiddleware); 17 | Dispatcher::instance().registerStore(new MainStore); 18 | 19 | Dispatcher::instance().dispatch(new Action(ActionType::UploadFtp, QString("ftp://example.com/example.zip"))); 20 | 21 | return a.exec(); 22 | } 23 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/app/action/actionprovider.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | void ActionProvider::showFileDialog(bool show) 8 | { 9 | flux_qt::Dispatcher::instance().dispatch(new flux_qt::Action(ActionType::ShowFileDialog, show)); 10 | } 11 | 12 | void ActionProvider::selectFile(const QString &filename) 13 | { 14 | flux_qt::Dispatcher::instance().dispatch(new flux_qt::Action(ActionType::SelectFile, filename)); 15 | } 16 | 17 | void ActionProvider::uploadFtp(const QString &filename) 18 | { 19 | flux_qt::Dispatcher::instance().dispatch(new flux_qt::Action(ActionType::UploadFtp, filename)); 20 | } 21 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/app/service/ftpservice.h: -------------------------------------------------------------------------------- 1 | #ifndef QML_FTP_SERVICE_H 2 | #define QML_FTP_SERVICE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class FtpService final : public QObject 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | FtpService(); 14 | ~FtpService(); 15 | 16 | void onUploadFtp(const QString& filename); 17 | 18 | signals: 19 | void uploadFtp(const QString& filename); 20 | 21 | private: 22 | FtpService(const FtpService&) = delete; 23 | FtpService(FtpService&&) = delete; 24 | FtpService& operator=(const FtpService&) = delete; 25 | FtpService& operator=(FtpService&&) = delete; 26 | 27 | class FtpServiceImpl; 28 | QScopedPointer impl_; 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /examples/console/flux_qt_console/app/service/ftpservice.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSOLE_FTP_SERVICE_H 2 | #define CONSOLE_FTP_SERVICE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class FtpService final : public QObject 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | FtpService(); 14 | ~FtpService(); 15 | 16 | void onUploadFtp(const QString& filename); 17 | 18 | signals: 19 | void uploadFtp(const QString& filename); 20 | 21 | private: 22 | FtpService(const FtpService&) = delete; 23 | FtpService(FtpService&&) = delete; 24 | FtpService& operator=(const FtpService&) = delete; 25 | FtpService& operator=(FtpService&&) = delete; 26 | 27 | class FtpServiceImpl; 28 | QScopedPointer impl_; 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /examples/console/flux_qt_console/app/store/mainstore.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | void MainStore::process(const QSharedPointer& action) 9 | { 10 | switch (action->getType()) { 11 | 12 | case ActionType::UploadFtpStarted: 13 | qDebug().noquote() << "Start uploading" << action->getPayload(); 14 | break; 15 | 16 | case ActionType::UploadFtpProcess: 17 | qDebug().noquote() << "Uploaded" << QString("%1%").arg(QString::number(action->getPayload())); 18 | break; 19 | 20 | case ActionType::UploadFtpFinished: 21 | qDebug() << "File uploaded successfully"; 22 | break; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/app/service/ftpserviceworker.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | void FtpServiceWorkerThread::run() 11 | { 12 | exec(); 13 | } 14 | 15 | void FtpServiceWorker::onUploadFtp(const QString &filename) 16 | { 17 | Q_UNUSED(filename) 18 | QThread::msleep(2000); 19 | 20 | int percentDone = 0; 21 | for (int i = 0; i < 10; ++i) { 22 | percentDone += 10; 23 | flux_qt::Dispatcher::instance().dispatch(new flux_qt::Action(ActionType::UploadFtpProcess, percentDone)); 24 | 25 | QThread::msleep(1000); 26 | } 27 | 28 | flux_qt::Dispatcher::instance().dispatch(new flux_qt::Action(ActionType::UploadFtpFinished)); 29 | } 30 | -------------------------------------------------------------------------------- /examples/console/flux_qt_console/app/service/ftpserviceworker.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | void FtpServiceWorkerThread::run() 11 | { 12 | exec(); 13 | } 14 | 15 | void FtpServiceWorker::onUploadFtp(const QString &filename) 16 | { 17 | Q_UNUSED(filename) 18 | QThread::msleep(2000); 19 | 20 | int percentDone = 0; 21 | for (int i = 0; i < 10; ++i) { 22 | percentDone += 10; 23 | flux_qt::Dispatcher::instance().dispatch(new flux_qt::Action(ActionType::UploadFtpProcess, percentDone)); 24 | 25 | QThread::msleep(1000); 26 | } 27 | 28 | flux_qt::Dispatcher::instance().dispatch(new flux_qt::Action(ActionType::UploadFtpFinished)); 29 | } 30 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/app/middleware/ftpmiddleware.h: -------------------------------------------------------------------------------- 1 | #ifndef QML_FTP_MIDDLEWARE_H 2 | #define QML_FTP_MIDDLEWARE_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | class FtpMiddleware final : public flux_qt::Middleware 11 | { 12 | public: 13 | FtpMiddleware(); 14 | ~FtpMiddleware(); 15 | 16 | QSharedPointer process(const QSharedPointer& action) override; 17 | 18 | private: 19 | FtpMiddleware(const FtpMiddleware&) = delete; 20 | FtpMiddleware(FtpMiddleware&&) = delete; 21 | FtpMiddleware& operator=(const FtpMiddleware&) = delete; 22 | FtpMiddleware& operator=(FtpMiddleware&&) = delete; 23 | 24 | class FtpMiddlewareImpl; 25 | QScopedPointer impl_; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /examples/console/flux_qt_console/app/middleware/ftpmiddleware.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSOLE_FTP_MIDDLEWARE_H 2 | #define CONSOLE_FTP_MIDDLEWARE_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | class FtpMiddleware final : public flux_qt::Middleware 11 | { 12 | public: 13 | FtpMiddleware(); 14 | ~FtpMiddleware(); 15 | 16 | QSharedPointer process(const QSharedPointer& action) override; 17 | 18 | private: 19 | FtpMiddleware(const FtpMiddleware&) = delete; 20 | FtpMiddleware(FtpMiddleware&&) = delete; 21 | FtpMiddleware& operator=(const FtpMiddleware&) = delete; 22 | FtpMiddleware& operator=(FtpMiddleware&&) = delete; 23 | 24 | class FtpMiddlewareImpl; 25 | QScopedPointer impl_; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/app/action/actionprovider.h: -------------------------------------------------------------------------------- 1 | #ifndef QML_ACTION_PROVIDER_H 2 | #define QML_ACTION_PROVIDER_H 3 | 4 | #include 5 | #include 6 | 7 | class ActionProvider final : public QObject 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | static ActionProvider& instance() { 13 | static ActionProvider self; 14 | return self; 15 | } 16 | 17 | Q_INVOKABLE void showFileDialog(bool show); 18 | Q_INVOKABLE void selectFile(const QString& filename); 19 | Q_INVOKABLE void uploadFtp(const QString& filename); 20 | 21 | private: 22 | ActionProvider() = default; 23 | ActionProvider(const ActionProvider&) = delete; 24 | ActionProvider(ActionProvider&&) = delete; 25 | ActionProvider& operator=(const ActionProvider&) = delete; 26 | ActionProvider& operator=(ActionProvider&&) = delete; 27 | ~ActionProvider() = default; 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 eandritskiy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/app/service/ftpserviceworker.h: -------------------------------------------------------------------------------- 1 | #ifndef QML_FTP_SERVICE_WORKER_H 2 | #define QML_FTP_SERVICE_WORKER_H 3 | 4 | #include 5 | 6 | class FtpServiceWorkerThread final : public QThread 7 | { 8 | public: 9 | FtpServiceWorkerThread() = default; 10 | virtual ~FtpServiceWorkerThread() = default; 11 | 12 | private: 13 | FtpServiceWorkerThread(const FtpServiceWorkerThread&) = delete; 14 | FtpServiceWorkerThread(FtpServiceWorkerThread&&) = delete; 15 | FtpServiceWorkerThread& operator=(const FtpServiceWorkerThread&) = delete; 16 | FtpServiceWorkerThread& operator=(FtpServiceWorkerThread&&) = delete; 17 | 18 | void run() override; 19 | }; 20 | 21 | class FtpServiceWorker final : public QObject 22 | { 23 | Q_OBJECT 24 | 25 | public: 26 | FtpServiceWorker() = default; 27 | ~FtpServiceWorker() = default; 28 | 29 | public slots: 30 | void onUploadFtp(const QString& filename); 31 | 32 | private: 33 | FtpServiceWorker(const FtpServiceWorker&) = delete; 34 | FtpServiceWorker(FtpServiceWorker&&) = delete; 35 | FtpServiceWorker& operator=(const FtpServiceWorker&) = delete; 36 | FtpServiceWorker& operator=(FtpServiceWorker&&) = delete; 37 | }; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /examples/console/flux_qt_console/app/service/ftpserviceworker.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSOLE_FTP_SERVICE_WORKER_H 2 | #define CONSOLE_FTP_SERVICE_WORKER_H 3 | 4 | #include 5 | 6 | class FtpServiceWorkerThread final : public QThread 7 | { 8 | public: 9 | FtpServiceWorkerThread() = default; 10 | virtual ~FtpServiceWorkerThread() = default; 11 | 12 | private: 13 | FtpServiceWorkerThread(const FtpServiceWorkerThread&) = delete; 14 | FtpServiceWorkerThread(FtpServiceWorkerThread&&) = delete; 15 | FtpServiceWorkerThread& operator=(const FtpServiceWorkerThread&) = delete; 16 | FtpServiceWorkerThread& operator=(FtpServiceWorkerThread&&) = delete; 17 | 18 | void run() override; 19 | }; 20 | 21 | class FtpServiceWorker final : public QObject 22 | { 23 | Q_OBJECT 24 | 25 | public: 26 | FtpServiceWorker() = default; 27 | ~FtpServiceWorker() = default; 28 | 29 | public slots: 30 | void onUploadFtp(const QString& filename); 31 | 32 | private: 33 | FtpServiceWorker(const FtpServiceWorker&) = delete; 34 | FtpServiceWorker(FtpServiceWorker&&) = delete; 35 | FtpServiceWorker& operator=(const FtpServiceWorker&) = delete; 36 | FtpServiceWorker& operator=(FtpServiceWorker&&) = delete; 37 | }; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/app/middleware/ftpmiddleware.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class FtpMiddleware::FtpMiddlewareImpl final 8 | { 9 | public: 10 | FtpMiddlewareImpl() 11 | : service_(new FtpService) 12 | { 13 | } 14 | 15 | FtpMiddlewareImpl(const FtpMiddlewareImpl&) = delete; 16 | FtpMiddlewareImpl(FtpMiddlewareImpl&&) = delete; 17 | FtpMiddlewareImpl& operator=(const FtpMiddlewareImpl&) = delete; 18 | FtpMiddlewareImpl& operator=(FtpMiddlewareImpl&&) = delete; 19 | ~FtpMiddlewareImpl() = default; 20 | 21 | QScopedPointer service_; 22 | }; 23 | 24 | FtpMiddleware::FtpMiddleware() 25 | : impl_(new FtpMiddlewareImpl) 26 | { 27 | } 28 | 29 | FtpMiddleware::~FtpMiddleware() 30 | { 31 | } 32 | 33 | QSharedPointer FtpMiddleware::process(const QSharedPointer& action) 34 | { 35 | switch (action->getType()) { 36 | 37 | case ActionType::UploadFtp: 38 | impl_->service_->onUploadFtp(action->getPayload()); 39 | return QSharedPointer(new flux_qt::Action(ActionType::UploadFtpStarted, action->getPayload())); 40 | } 41 | 42 | return action; 43 | } 44 | -------------------------------------------------------------------------------- /examples/console/flux_qt_console/app/middleware/ftpmiddleware.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class FtpMiddleware::FtpMiddlewareImpl final 8 | { 9 | public: 10 | FtpMiddlewareImpl() 11 | : service_(new FtpService) 12 | { 13 | } 14 | 15 | FtpMiddlewareImpl(const FtpMiddlewareImpl&) = delete; 16 | FtpMiddlewareImpl(FtpMiddlewareImpl&&) = delete; 17 | FtpMiddlewareImpl& operator=(const FtpMiddlewareImpl&) = delete; 18 | FtpMiddlewareImpl& operator=(FtpMiddlewareImpl&&) = delete; 19 | ~FtpMiddlewareImpl() = default; 20 | 21 | QScopedPointer service_; 22 | }; 23 | 24 | FtpMiddleware::FtpMiddleware() 25 | : impl_(new FtpMiddlewareImpl) 26 | { 27 | } 28 | 29 | FtpMiddleware::~FtpMiddleware() 30 | { 31 | } 32 | 33 | QSharedPointer FtpMiddleware::process(const QSharedPointer& action) 34 | { 35 | switch (action->getType()) { 36 | 37 | case ActionType::UploadFtp: 38 | impl_->service_->onUploadFtp(action->getPayload()); 39 | return QSharedPointer(new flux_qt::Action(ActionType::UploadFtpStarted, action->getPayload())); 40 | } 41 | 42 | return action; 43 | } 44 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/app/service/ftpservice.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | class FtpService::FtpServiceImpl final 11 | { 12 | public: 13 | FtpServiceImpl() = default; 14 | FtpServiceImpl(const FtpServiceImpl&) = delete; 15 | FtpServiceImpl(FtpServiceImpl&&) = delete; 16 | FtpServiceImpl& operator=(const FtpServiceImpl&) = delete; 17 | FtpServiceImpl& operator=(FtpServiceImpl&&) = delete; 18 | ~FtpServiceImpl() = default; 19 | 20 | QSharedPointer thread_; 21 | }; 22 | 23 | FtpService::FtpService() 24 | : impl_(new FtpServiceImpl) 25 | { 26 | impl_->thread_ = QSharedPointer(new FtpServiceWorkerThread); 27 | 28 | FtpServiceWorker *worker = new FtpServiceWorker(); 29 | worker->moveToThread(impl_->thread_.data()); 30 | 31 | QObject::connect(impl_->thread_.data(), &QThread::finished, worker, &FtpServiceWorker::deleteLater); 32 | QObject::connect(this, &FtpService::uploadFtp, worker, &FtpServiceWorker::onUploadFtp, Qt::QueuedConnection); 33 | 34 | impl_->thread_->start(QThread::Priority::LowPriority); 35 | } 36 | 37 | FtpService::~FtpService() 38 | { 39 | impl_->thread_->quit(); 40 | impl_->thread_->wait(); 41 | } 42 | 43 | void FtpService::onUploadFtp(const QString &filename) 44 | { 45 | emit uploadFtp(filename); 46 | } 47 | -------------------------------------------------------------------------------- /examples/console/flux_qt_console/app/service/ftpservice.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | class FtpService::FtpServiceImpl final 11 | { 12 | public: 13 | FtpServiceImpl() = default; 14 | FtpServiceImpl(const FtpServiceImpl&) = delete; 15 | FtpServiceImpl(FtpServiceImpl&&) = delete; 16 | FtpServiceImpl& operator=(const FtpServiceImpl&) = delete; 17 | FtpServiceImpl& operator=(FtpServiceImpl&&) = delete; 18 | ~FtpServiceImpl() = default; 19 | 20 | QSharedPointer thread_; 21 | }; 22 | 23 | FtpService::FtpService() 24 | : impl_(new FtpServiceImpl) 25 | { 26 | impl_->thread_ = QSharedPointer(new FtpServiceWorkerThread); 27 | 28 | FtpServiceWorker *worker = new FtpServiceWorker(); 29 | worker->moveToThread(impl_->thread_.data()); 30 | 31 | QObject::connect(impl_->thread_.data(), &QThread::finished, worker, &FtpServiceWorker::deleteLater); 32 | QObject::connect(this, &FtpService::uploadFtp, worker, &FtpServiceWorker::onUploadFtp, Qt::QueuedConnection); 33 | 34 | impl_->thread_->start(QThread::Priority::LowPriority); 35 | } 36 | 37 | FtpService::~FtpService() 38 | { 39 | impl_->thread_->quit(); 40 | impl_->thread_->wait(); 41 | } 42 | 43 | void FtpService::onUploadFtp(const QString &filename) 44 | { 45 | emit uploadFtp(filename); 46 | } 47 | -------------------------------------------------------------------------------- /flux_qt/flux_qt/action.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUX_QT_ACTION_H 2 | #define FLUX_QT_ACTION_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace flux_qt 10 | { 11 | 12 | template 13 | using is_scoped_enum = std::integral_constant::value && !std::is_convertible::value>; 14 | 15 | class Action final 16 | { 17 | public: 18 | template ::value>::type> 19 | Action(ScopedEnum type, QVariant& payload, bool error = false) 20 | : type_(static_cast(type)), payload_(payload), error_(error) 21 | { 22 | } 23 | 24 | template ::value>::type> 25 | Action(ScopedEnum type, QVariant&& payload = QVariant(), bool error = false) 26 | : type_(static_cast(type)), payload_(std::move(payload)), error_(error) 27 | { 28 | } 29 | 30 | Action(const Action&) = default; 31 | Action(Action&&) = default; 32 | Action& operator=(const Action&) = default; 33 | Action& operator=(Action&&) = default; 34 | ~Action() = default; 35 | 36 | template ::value>::type> 37 | ScopedEnum getType() const 38 | { 39 | return static_cast(type_); 40 | } 41 | 42 | template 43 | T getPayload() const 44 | { 45 | return qvariant_cast(payload_); 46 | } 47 | 48 | bool getError() const 49 | { 50 | return error_; 51 | } 52 | 53 | private: 54 | int type_; 55 | bool error_; 56 | QVariant payload_; 57 | }; 58 | 59 | } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace flux_qt; 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | QGuiApplication app(argc, argv); 17 | 18 | qmlRegisterSingletonType("Flux", 1, 0, "ActionProvider", 19 | [](QQmlEngine* engine, QJSEngine* scriptEngine) -> QObject* { 20 | Q_UNUSED(engine) 21 | Q_UNUSED(scriptEngine) 22 | 23 | QQmlEngine::setObjectOwnership(&ActionProvider::instance(), QQmlEngine::CppOwnership); 24 | return &ActionProvider::instance(); 25 | }); 26 | 27 | qmlRegisterSingletonType("Flux", 1, 0, "MainStore", 28 | [](QQmlEngine* engine, QJSEngine* scriptEngine) -> QObject* { 29 | Q_UNUSED(engine) 30 | Q_UNUSED(scriptEngine) 31 | 32 | QQmlEngine::setObjectOwnership(&MainStore::instance(), QQmlEngine::CppOwnership); 33 | return &MainStore::instance(); 34 | }); 35 | 36 | Dispatcher::instance().registerMiddleware(new FtpMiddleware); 37 | Dispatcher::instance().registerStore(QSharedPointer(&MainStore::instance(), 38 | [](flux_qt::Store*) {})); 39 | 40 | QQmlApplicationEngine engine; 41 | engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); 42 | if (engine.rootObjects().isEmpty()) 43 | return -1; 44 | 45 | return app.exec(); 46 | } 47 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/app/store/mainstore.h: -------------------------------------------------------------------------------- 1 | #ifndef QML_MAIN_STORE_H 2 | #define QML_MAIN_STORE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | class MainStore final : public QObject, public flux_qt::Store 12 | { 13 | Q_OBJECT 14 | 15 | Q_PROPERTY(bool showFileDialog READ getShowFileDialog NOTIFY showFileDialogChanged) 16 | Q_PROPERTY(QString selectedFilename READ getSelectedFilename NOTIFY selectedFilenameChanged) 17 | Q_PROPERTY(QString uploadStatus READ getUploadStatus NOTIFY uploadStatusChanged) 18 | 19 | public: 20 | static MainStore& instance() { 21 | static MainStore self; 22 | return self; 23 | } 24 | 25 | void process(const QSharedPointer& action) Q_DECL_OVERRIDE; 26 | 27 | bool getShowFileDialog() const; 28 | QString getSelectedFilename() const; 29 | QString getUploadStatus() const; 30 | 31 | signals: 32 | void showFileDialogChanged(); 33 | void selectedFilenameChanged(); 34 | void uploadStatusChanged(); 35 | 36 | private: 37 | MainStore(); 38 | MainStore(const MainStore&) = delete; 39 | MainStore(MainStore&&) = delete; 40 | MainStore& operator=(const MainStore&) = delete; 41 | MainStore& operator=(MainStore&&) = delete; 42 | ~MainStore(); 43 | 44 | void processShowFileDialogAction(const QSharedPointer& action); 45 | void processSelectFileAction(const QSharedPointer& action); 46 | void processUploadFtpStartedAction(const QSharedPointer& action); 47 | void processUploadFtpProcessAction(const QSharedPointer& action); 48 | void processUploadFtpFinishedAction(const QSharedPointer& action); 49 | 50 | class MainStoreImpl; 51 | QScopedPointer impl_; 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.9 2 | import QtQuick.Dialogs 1.2 3 | import QtQuick.Controls 2.2 4 | import QtQuick.Window 2.3 5 | 6 | import Flux 1.0 7 | 8 | Window { 9 | id: root 10 | 11 | visible: true 12 | 13 | width: 640 14 | height: 480 15 | 16 | maximumWidth: width 17 | maximumHeight: height 18 | 19 | Item { 20 | visible: !MainStore.uploadStatus 21 | 22 | anchors { 23 | verticalCenter: parent.verticalCenter 24 | horizontalCenter: parent.horizontalCenter 25 | } 26 | 27 | width: textField.width + button.width + button.anchors.leftMargin 28 | height: textField.height 29 | 30 | TextField { 31 | id: textField 32 | 33 | readOnly: true 34 | selectByMouse: true 35 | 36 | placeholderText: "Select a file to upload" 37 | text: MainStore.selectedFilename 38 | } 39 | 40 | Button { 41 | id: button 42 | 43 | anchors { 44 | verticalCenter: textField.verticalCenter 45 | left: textField.right 46 | leftMargin: 10 47 | } 48 | 49 | text: MainStore.selectedFilename ? "Upload" : "Select" 50 | 51 | onPressed: MainStore.selectedFilename ? ActionProvider.uploadFtp(MainStore.selectedFilename) : 52 | ActionProvider.showFileDialog(true) 53 | 54 | } 55 | } 56 | 57 | Text { 58 | id: uploadStatus 59 | 60 | visible: MainStore.uploadStatus 61 | 62 | anchors { 63 | centerIn: parent 64 | } 65 | 66 | text: MainStore.uploadStatus 67 | } 68 | 69 | Component { 70 | id: fileDialogComponent 71 | 72 | FileDialog { 73 | id: fileDialog 74 | 75 | visible: true 76 | 77 | title: "Please select a file" 78 | folder: shortcuts.home 79 | 80 | onAccepted: { 81 | ActionProvider.selectFile(fileDialog.fileUrls); 82 | } 83 | 84 | onRejected: { 85 | ActionProvider.showFileDialog(false); 86 | } 87 | } 88 | } 89 | 90 | Loader { 91 | id: fileDialogLoader 92 | 93 | sourceComponent: MainStore.showFileDialog ? fileDialogComponent : undefined 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /flux_qt/flux_qt/dispatcher.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUX_QT_DISPATCHER_H 2 | #define FLUX_QT_DISPATCHER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "middleware.h" 21 | #include "store.h" 22 | 23 | namespace flux_qt 24 | { 25 | class Action; 26 | 27 | class Dispatcher final : public QObject 28 | { 29 | Q_OBJECT 30 | 31 | public: 32 | static Dispatcher& instance() { 33 | static Dispatcher self; 34 | return self; 35 | } 36 | 37 | template 38 | void registerMiddleware(Args&&... args) 39 | { 40 | middlewares_.push_back(QSharedPointer(std::forward(args)...)); 41 | } 42 | 43 | template 44 | void registerStore(Args&&... args) 45 | { 46 | stores_.push_back(QSharedPointer(std::forward(args)...)); 47 | } 48 | 49 | template 50 | void dispatch(Args&&... args) 51 | { 52 | QMutexLocker locker(&mutex_); 53 | actions_.enqueue(QSharedPointer(std::forward(args)...)); 54 | 55 | emit newActionAdded(); 56 | } 57 | 58 | signals: 59 | void newActionAdded(); 60 | 61 | private: 62 | Dispatcher() 63 | { 64 | QObject::connect(this, &Dispatcher::newActionAdded, this, [this]() { 65 | this->onNewActionAdded(); 66 | }, Qt::QueuedConnection); 67 | } 68 | 69 | Dispatcher(const Dispatcher&) = delete; 70 | Dispatcher(Dispatcher&&) = delete; 71 | Dispatcher& operator=(const Dispatcher&) = delete; 72 | Dispatcher& operator=(Dispatcher&&) = delete; 73 | ~Dispatcher() = default; 74 | 75 | void onNewActionAdded() 76 | { 77 | mutex_.lock(); 78 | 79 | while (!actions_.empty()) { 80 | auto action = actions_.dequeue(); 81 | 82 | mutex_.unlock(); 83 | 84 | for (const auto& middleware : middlewares_) { 85 | action = middleware->process(action); 86 | } 87 | 88 | for (const auto& store : stores_) { 89 | store->process(action); 90 | } 91 | 92 | mutex_.lock(); 93 | } 94 | 95 | mutex_.unlock(); 96 | } 97 | 98 | QVector > middlewares_; 99 | QVector > stores_; 100 | 101 | QQueue > actions_; 102 | QMutex mutex_; 103 | }; 104 | 105 | } 106 | 107 | #endif 108 | 109 | -------------------------------------------------------------------------------- /examples/qml/flux_qt_qml/app/store/mainstore.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | class MainStore::MainStoreImpl final 9 | { 10 | public: 11 | MainStoreImpl() = default; 12 | MainStoreImpl(const MainStoreImpl&) = delete; 13 | MainStoreImpl(MainStoreImpl&&) = delete; 14 | MainStoreImpl& operator=(const MainStoreImpl&) = delete; 15 | MainStoreImpl& operator=(MainStoreImpl&&) = delete; 16 | ~MainStoreImpl() = default; 17 | 18 | bool showFileDialog_; 19 | QString selectedFilename_; 20 | QString uploadStatus_; 21 | }; 22 | 23 | MainStore::MainStore() 24 | : impl_(new MainStoreImpl) 25 | { 26 | impl_->showFileDialog_ = false; 27 | } 28 | 29 | MainStore::~MainStore() 30 | { 31 | } 32 | 33 | bool MainStore::getShowFileDialog() const 34 | { 35 | return impl_->showFileDialog_; 36 | } 37 | 38 | QString MainStore::getSelectedFilename() const 39 | { 40 | return impl_->selectedFilename_; 41 | } 42 | 43 | QString MainStore::getUploadStatus() const 44 | { 45 | return impl_->uploadStatus_; 46 | } 47 | 48 | void MainStore::process(const QSharedPointer& action) 49 | { 50 | switch (action->getType()) { 51 | 52 | case ActionType::ShowFileDialog: 53 | processShowFileDialogAction(action); 54 | break; 55 | 56 | case ActionType::SelectFile: 57 | processSelectFileAction(action); 58 | break; 59 | 60 | case ActionType::UploadFtpStarted: 61 | processUploadFtpStartedAction(action); 62 | break; 63 | 64 | case ActionType::UploadFtpProcess: 65 | processUploadFtpProcessAction(action); 66 | break; 67 | 68 | case ActionType::UploadFtpFinished: 69 | processUploadFtpFinishedAction(action); 70 | break; 71 | } 72 | } 73 | 74 | void MainStore::processShowFileDialogAction(const QSharedPointer &action) 75 | { 76 | impl_->showFileDialog_ = action->getPayload(); 77 | emit showFileDialogChanged(); 78 | } 79 | 80 | void MainStore::processSelectFileAction(const QSharedPointer &action) 81 | { 82 | impl_->selectedFilename_ = action->getPayload(); 83 | emit selectedFilenameChanged(); 84 | } 85 | 86 | void MainStore::processUploadFtpStartedAction(const QSharedPointer &action) 87 | { 88 | Q_UNUSED(action) 89 | impl_->uploadStatus_ = QStringLiteral("Start uploading..."); 90 | emit uploadStatusChanged(); 91 | } 92 | 93 | void MainStore::processUploadFtpProcessAction(const QSharedPointer &action) 94 | { 95 | impl_->uploadStatus_ = QString("Uploaded %1%").arg(action->getPayload()); 96 | emit uploadStatusChanged(); 97 | } 98 | 99 | void MainStore::processUploadFtpFinishedAction(const QSharedPointer &action) 100 | { 101 | Q_UNUSED(action) 102 | impl_->uploadStatus_ = QStringLiteral("Uploading finished"); 103 | emit uploadStatusChanged(); 104 | } 105 | --------------------------------------------------------------------------------