##// END OF EJS Templates
Merge branch 'feature/NetworkController2' into develop
perrinel -
r390:1d8a5cf19c4c merge
parent child
Show More
@@ -1,153 +1,153
1
1
2 ## core - CMakeLists.txt
2 ## core - CMakeLists.txt
3 STRING(TOLOWER ${CMAKE_PROJECT_NAME} LIBRARY_PREFFIX)
3 STRING(TOLOWER ${CMAKE_PROJECT_NAME} LIBRARY_PREFFIX)
4 SET(SQPCORE_LIBRARY_NAME "${LIBRARY_PREFFIX}_core${DEBUG_SUFFIX}")
4 SET(SQPCORE_LIBRARY_NAME "${LIBRARY_PREFFIX}_core${DEBUG_SUFFIX}")
5 SET(SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/")
5 SET(SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/")
6 SET(INCLUDES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/")
6 SET(INCLUDES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/")
7
7
8 # Include core directory
8 # Include core directory
9 include_directories("${INCLUDES_DIR}")
9 include_directories("${INCLUDES_DIR}")
10
10
11 # Set a variable to display a warning in the version files.
11 # Set a variable to display a warning in the version files.
12 SET(SCIQLOP_CMAKE_GENERATION_WARNING "DON'T CHANGE THIS FILE. AUTOGENERATED BY CMAKE.")
12 SET(SCIQLOP_CMAKE_GENERATION_WARNING "DON'T CHANGE THIS FILE. AUTOGENERATED BY CMAKE.")
13 # Generate the version file from the cmake version variables. The version
13 # Generate the version file from the cmake version variables. The version
14 # variables are defined in the cmake/sciqlop_version.cmake file.
14 # variables are defined in the cmake/sciqlop_version.cmake file.
15 CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/resources/Version.h.in"
15 CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/resources/Version.h.in"
16 "${INCLUDES_DIR}/Version.h")
16 "${INCLUDES_DIR}/Version.h")
17 CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/resources/Version.cpp.in"
17 CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/resources/Version.cpp.in"
18 "${SOURCES_DIR}/Version.cpp")
18 "${SOURCES_DIR}/Version.cpp")
19
19
20 # Find dependent modules
20 # Find dependent modules
21 find_package(sciqlop-plugin)
21 find_package(sciqlop-plugin)
22 INCLUDE_DIRECTORIES(${SCIQLOP-PLUGIN_INCLUDE_DIR})
22 INCLUDE_DIRECTORIES(${SCIQLOP-PLUGIN_INCLUDE_DIR})
23
23
24 #
24 #
25 # Find Qt modules
25 # Find Qt modules
26 #
26 #
27 SCIQLOP_FIND_QT(Core)
27 SCIQLOP_FIND_QT(Core Network)
28
28
29 #
29 #
30 # Compile the library library
30 # Compile the library library
31 #
31 #
32 FILE (GLOB_RECURSE MODULE_SOURCES
32 FILE (GLOB_RECURSE MODULE_SOURCES
33 ${INCLUDES_DIR}/*.h
33 ${INCLUDES_DIR}/*.h
34 ${SOURCES_DIR}/*.c
34 ${SOURCES_DIR}/*.c
35 ${SOURCES_DIR}/*.cpp
35 ${SOURCES_DIR}/*.cpp
36 ${SOURCES_DIR}/*.h)
36 ${SOURCES_DIR}/*.h)
37
37
38 ADD_LIBRARY(${SQPCORE_LIBRARY_NAME} ${MODULE_SOURCES})
38 ADD_LIBRARY(${SQPCORE_LIBRARY_NAME} ${MODULE_SOURCES})
39 set_property(TARGET ${SQPCORE_LIBRARY_NAME} PROPERTY CXX_STANDARD 14)
39 set_property(TARGET ${SQPCORE_LIBRARY_NAME} PROPERTY CXX_STANDARD 14)
40 set_property(TARGET ${SQPCORE_LIBRARY_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
40 set_property(TARGET ${SQPCORE_LIBRARY_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
41 TARGET_LINK_LIBRARIES(${SQPCORE_LIBRARY_NAME})
41 TARGET_LINK_LIBRARIES(${SQPCORE_LIBRARY_NAME})
42 qt5_use_modules(${SQPCORE_LIBRARY_NAME} Core)
42 qt5_use_modules(${SQPCORE_LIBRARY_NAME} Core Network)
43
43
44 INSTALL(TARGETS ${SQPCORE_LIBRARY_NAME}
44 INSTALL(TARGETS ${SQPCORE_LIBRARY_NAME}
45 RUNTIME DESTINATION ${INSTALL_BINARY_DIR}
45 RUNTIME DESTINATION ${INSTALL_BINARY_DIR}
46 LIBRARY DESTINATION ${INSTALL_LIBRARY_DIR}
46 LIBRARY DESTINATION ${INSTALL_LIBRARY_DIR}
47 ARCHIVE DESTINATION ${INSTALL_LIBRARY_DIR}
47 ARCHIVE DESTINATION ${INSTALL_LIBRARY_DIR}
48 )
48 )
49
49
50 # From cmake documentation: http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html
50 # From cmake documentation: http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html
51 # Entries in the COMPILE_DEFINITIONS are prefixed with -D or /D and added to the compile line in an unspecified order.
51 # Entries in the COMPILE_DEFINITIONS are prefixed with -D or /D and added to the compile line in an unspecified order.
52 # The DEFINE_SYMBOL target property is also added as a compile definition as a special convenience case for SHARED and MODULE library targets
52 # The DEFINE_SYMBOL target property is also added as a compile definition as a special convenience case for SHARED and MODULE library targets
53 IF(BUILD_SHARED_LIBS)
53 IF(BUILD_SHARED_LIBS)
54 SET_TARGET_PROPERTIES(${SQPCORE_LIBRARY_NAME} PROPERTIES COMPILE_DEFINITIONS "SCIQLOP_EXPORT")
54 SET_TARGET_PROPERTIES(${SQPCORE_LIBRARY_NAME} PROPERTIES COMPILE_DEFINITIONS "SCIQLOP_EXPORT")
55 ELSE()
55 ELSE()
56 TARGET_COMPILE_DEFINITIONS(${SQPCORE_LIBRARY_NAME} PUBLIC "SCIQLOP_STATIC_LIBRARIES")
56 TARGET_COMPILE_DEFINITIONS(${SQPCORE_LIBRARY_NAME} PUBLIC "SCIQLOP_STATIC_LIBRARIES")
57 ENDIF()
57 ENDIF()
58
58
59 # Set the variable to parent scope so that the other projects can copy the
59 # Set the variable to parent scope so that the other projects can copy the
60 # dependent shared libraries
60 # dependent shared libraries
61 SCIQLOP_SET_TO_PARENT_SCOPE(SQPCORE_LIBRARY_NAME)
61 SCIQLOP_SET_TO_PARENT_SCOPE(SQPCORE_LIBRARY_NAME)
62
62
63 # Copy extern shared libraries to the lib folder
63 # Copy extern shared libraries to the lib folder
64 SCIQLOP_COPY_TO_TARGET(LIBRARY ${SQPCORE_LIBRARY_NAME} ${EXTERN_SHARED_LIBRARIES})
64 SCIQLOP_COPY_TO_TARGET(LIBRARY ${SQPCORE_LIBRARY_NAME} ${EXTERN_SHARED_LIBRARIES})
65
65
66 # Add the files to the list of files to be analyzed
66 # Add the files to the list of files to be analyzed
67 LIST(APPEND CHECKSTYLE_INPUT_FILES ${MODULE_SOURCES})
67 LIST(APPEND CHECKSTYLE_INPUT_FILES ${MODULE_SOURCES})
68 SCIQLOP_SET_TO_PARENT_SCOPE(CHECKSTYLE_INPUT_FILES)
68 SCIQLOP_SET_TO_PARENT_SCOPE(CHECKSTYLE_INPUT_FILES)
69 # Vera++ exclusion files
69 # Vera++ exclusion files
70 LIST(APPEND CHECKSTYLE_EXCLUSION_FILES ${CMAKE_CURRENT_SOURCE_DIR}/vera-exclusions/exclusions.txt)
70 LIST(APPEND CHECKSTYLE_EXCLUSION_FILES ${CMAKE_CURRENT_SOURCE_DIR}/vera-exclusions/exclusions.txt)
71 SCIQLOP_SET_TO_PARENT_SCOPE(CHECKSTYLE_EXCLUSION_FILES)
71 SCIQLOP_SET_TO_PARENT_SCOPE(CHECKSTYLE_EXCLUSION_FILES)
72
72
73 #
73 #
74 # Compile the tests
74 # Compile the tests
75 #
75 #
76 IF(BUILD_TESTS)
76 IF(BUILD_TESTS)
77 INCLUDE_DIRECTORIES(${SOURCES_DIR})
77 INCLUDE_DIRECTORIES(${SOURCES_DIR})
78 FILE (GLOB_RECURSE TESTS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Test*.cpp)
78 FILE (GLOB_RECURSE TESTS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Test*.cpp)
79 FILE (GLOB_RECURSE TESTS_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/Test*.h)
79 FILE (GLOB_RECURSE TESTS_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/Test*.h)
80 SET( TEST_LIBRARIES ${SQPCORE_LIBRARY_NAME})
80 SET( TEST_LIBRARIES ${SQPCORE_LIBRARY_NAME})
81
81
82 SET(TARGETS_COV)
82 SET(TARGETS_COV)
83 FOREACH( testFile ${TESTS_SOURCES} )
83 FOREACH( testFile ${TESTS_SOURCES} )
84 GET_FILENAME_COMPONENT( testDirectory ${testFile} DIRECTORY )
84 GET_FILENAME_COMPONENT( testDirectory ${testFile} DIRECTORY )
85 GET_FILENAME_COMPONENT( testName ${testFile} NAME_WE )
85 GET_FILENAME_COMPONENT( testName ${testFile} NAME_WE )
86
86
87 # Add to the list of sources files all the sources in the same
87 # Add to the list of sources files all the sources in the same
88 # directory that aren't another test
88 # directory that aren't another test
89 FILE (GLOB currentTestSources
89 FILE (GLOB currentTestSources
90 ${testDirectory}/*.c
90 ${testDirectory}/*.c
91 ${testDirectory}/*.cpp
91 ${testDirectory}/*.cpp
92 ${testDirectory}/*.h)
92 ${testDirectory}/*.h)
93 LIST (REMOVE_ITEM currentTestSources ${TESTS_SOURCES})
93 LIST (REMOVE_ITEM currentTestSources ${TESTS_SOURCES})
94 # LIST (REMOVE_ITEM currentTestSources ${TESTS_HEADERS})
94 # LIST (REMOVE_ITEM currentTestSources ${TESTS_HEADERS})
95
95
96 ADD_EXECUTABLE(${testName} ${testFile} ${currentTestSources})
96 ADD_EXECUTABLE(${testName} ${testFile} ${currentTestSources})
97 set_property(TARGET ${testName} PROPERTY CXX_STANDARD 14)
97 set_property(TARGET ${testName} PROPERTY CXX_STANDARD 14)
98 set_property(TARGET ${testName} PROPERTY CXX_STANDARD_REQUIRED ON)
98 set_property(TARGET ${testName} PROPERTY CXX_STANDARD_REQUIRED ON)
99 TARGET_LINK_LIBRARIES( ${testName} ${TEST_LIBRARIES} )
99 TARGET_LINK_LIBRARIES( ${testName} ${TEST_LIBRARIES} )
100 qt5_use_modules(${testName} Test)
100 qt5_use_modules(${testName} Test)
101
101
102 ADD_TEST( NAME ${testName} COMMAND ${testName} )
102 ADD_TEST( NAME ${testName} COMMAND ${testName} )
103
103
104 SCIQLOP_COPY_TO_TARGET(RUNTIME ${testName} ${EXTERN_SHARED_LIBRARIES})
104 SCIQLOP_COPY_TO_TARGET(RUNTIME ${testName} ${EXTERN_SHARED_LIBRARIES})
105 set(Coverage_NAME ${testName})
105 set(Coverage_NAME ${testName})
106 if(UNIX)
106 if(UNIX)
107 SETUP_TARGET_FOR_COVERAGE(TARGET ${testName}_coverage OUTPUT ${testFile}-path NAME ${testFile} EXECUTABLE ${testName})
107 SETUP_TARGET_FOR_COVERAGE(TARGET ${testName}_coverage OUTPUT ${testFile}-path NAME ${testFile} EXECUTABLE ${testName})
108 LIST( APPEND TARGETS_COV ${testName}_coverage)
108 LIST( APPEND TARGETS_COV ${testName}_coverage)
109 endif(UNIX)
109 endif(UNIX)
110
110
111 ENDFOREACH( testFile )
111 ENDFOREACH( testFile )
112
112
113 add_custom_target(coverage)
113 add_custom_target(coverage)
114
114
115 FOREACH( target_cov ${TARGETS_COV} )
115 FOREACH( target_cov ${TARGETS_COV} )
116 add_custom_command(TARGET coverage PRE_BUILD COMMAND make ${target_cov})
116 add_custom_command(TARGET coverage PRE_BUILD COMMAND make ${target_cov})
117 ENDFOREACH( target_cov )
117 ENDFOREACH( target_cov )
118
118
119 LIST(APPEND testFilesToFormat ${TESTS_SOURCES})
119 LIST(APPEND testFilesToFormat ${TESTS_SOURCES})
120 LIST(APPEND testFilesToFormat ${TESTS_HEADERS})
120 LIST(APPEND testFilesToFormat ${TESTS_HEADERS})
121 LIST(APPEND FORMATTING_INPUT_FILES ${testFilesToFormat})
121 LIST(APPEND FORMATTING_INPUT_FILES ${testFilesToFormat})
122 SCIQLOP_SET_TO_PARENT_SCOPE(FORMATTING_INPUT_FILES)
122 SCIQLOP_SET_TO_PARENT_SCOPE(FORMATTING_INPUT_FILES)
123 ENDIF(BUILD_TESTS)
123 ENDIF(BUILD_TESTS)
124
124
125 #
125 #
126 # Set the files that must be formatted by clang-format.
126 # Set the files that must be formatted by clang-format.
127 #
127 #
128 LIST (APPEND FORMATTING_INPUT_FILES ${MODULE_SOURCES})
128 LIST (APPEND FORMATTING_INPUT_FILES ${MODULE_SOURCES})
129 SCIQLOP_SET_TO_PARENT_SCOPE(FORMATTING_INPUT_FILES)
129 SCIQLOP_SET_TO_PARENT_SCOPE(FORMATTING_INPUT_FILES)
130
130
131 #
131 #
132 # Set the directories that doxygen must browse to generate the
132 # Set the directories that doxygen must browse to generate the
133 # documentation.
133 # documentation.
134 #
134 #
135 # Source directories:
135 # Source directories:
136 LIST (APPEND DOXYGEN_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/docs")
136 LIST (APPEND DOXYGEN_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/docs")
137 LIST (APPEND DOXYGEN_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src")
137 LIST (APPEND DOXYGEN_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src")
138 SCIQLOP_SET_TO_PARENT_SCOPE(DOXYGEN_INPUT_DIRS)
138 SCIQLOP_SET_TO_PARENT_SCOPE(DOXYGEN_INPUT_DIRS)
139 # Source directories to exclude from the documentation generation
139 # Source directories to exclude from the documentation generation
140 #LIST (APPEND DOXYGEN_EXCLUDE_PATTERNS "${CMAKE_CURRENT_SOURCE_DIR}/path/to/subdir/*")
140 #LIST (APPEND DOXYGEN_EXCLUDE_PATTERNS "${CMAKE_CURRENT_SOURCE_DIR}/path/to/subdir/*")
141 SCIQLOP_SET_TO_PARENT_SCOPE(DOXYGEN_EXCLUDE_PATTERNS)
141 SCIQLOP_SET_TO_PARENT_SCOPE(DOXYGEN_EXCLUDE_PATTERNS)
142
142
143 #
143 #
144 # Set the directories with the sources to analyze and propagate the
144 # Set the directories with the sources to analyze and propagate the
145 # modification to the parent scope
145 # modification to the parent scope
146 #
146 #
147 # Source directories to analyze:
147 # Source directories to analyze:
148 LIST (APPEND ANALYSIS_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src")
148 LIST (APPEND ANALYSIS_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src")
149 LIST (APPEND ANALYSIS_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/tests")
149 LIST (APPEND ANALYSIS_INPUT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/tests")
150 SCIQLOP_SET_TO_PARENT_SCOPE(ANALYSIS_INPUT_DIRS)
150 SCIQLOP_SET_TO_PARENT_SCOPE(ANALYSIS_INPUT_DIRS)
151 # Source directories to exclude from the analysis
151 # Source directories to exclude from the analysis
152 #LIST (APPEND ANALYSIS_EXCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/path/to/subdir")
152 #LIST (APPEND ANALYSIS_EXCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/path/to/subdir")
153 SCIQLOP_SET_TO_PARENT_SCOPE(ANALYSIS_EXCLUDE_DIRS)
153 SCIQLOP_SET_TO_PARENT_SCOPE(ANALYSIS_EXCLUDE_DIRS)
@@ -1,40 +1,60
1 #ifndef SCIQLOP_IDATAPROVIDER_H
1 #ifndef SCIQLOP_IDATAPROVIDER_H
2 #define SCIQLOP_IDATAPROVIDER_H
2 #define SCIQLOP_IDATAPROVIDER_H
3
3
4 #include <memory>
4 #include <memory>
5
5
6 #include <QObject>
6 #include <QObject>
7 #include <QUuid>
7 #include <QUuid>
8
8
9 #include <Common/MetaTypes.h>
9 #include <Common/MetaTypes.h>
10
10
11 #include <Data/SqpDateTime.h>
11 #include <Data/SqpDateTime.h>
12
12
13 class DataProviderParameters;
13 class DataProviderParameters;
14 class IDataSeries;
14 class IDataSeries;
15 class QNetworkReply;
16 class QNetworkRequest;
15
17
16 /**
18 /**
17 * @brief The IDataProvider interface aims to declare a data provider.
19 * @brief The IDataProvider interface aims to declare a data provider.
18 *
20 *
19 * A data provider is an entity that generates data and returns it according to various parameters
21 * A data provider is an entity that generates data and returns it according to various parameters
20 * (time interval, product to retrieve the data, etc.)
22 * (time interval, product to retrieve the data, etc.)
21 *
23 *
22 * @sa IDataSeries
24 * @sa IDataSeries
23 */
25 */
24 class IDataProvider : public QObject {
26 class IDataProvider : public QObject {
25
27
26 Q_OBJECT
28 Q_OBJECT
27 public:
29 public:
28 virtual ~IDataProvider() noexcept = default;
30 virtual ~IDataProvider() noexcept = default;
29
31
30 virtual void requestDataLoading(QUuid token, const QVector<SqpDateTime> &dateTimeList) = 0;
32 /**
33 * @brief requestDataLoading provide datas for the data identified by identifier for all
34 * SqpDateTime of dateTimeList
35 */
36 virtual void requestDataLoading(QUuid identifier, const QVector<SqpDateTime> &dateTimeList) = 0;
31
37
32 signals:
38 signals:
33 void dataProvided(QUuid token, std::shared_ptr<IDataSeries> dateSerie,
39 /**
40 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
41 * identified by identifier
42 */
43 void dataProvided(QUuid identifier, std::shared_ptr<IDataSeries> dateSerie,
34 const SqpDateTime &dateTime);
44 const SqpDateTime &dateTime);
45
46
47 /**
48 * @brief requestConstructed send a request for the data identified by identifier
49 * @callback is the methode call by the reply of the request when it is finished.
50 */
51 void requestConstructed(const QNetworkRequest &request, QUuid identifier,
52 std::function<void(QNetworkReply *, QUuid)> callback);
35 };
53 };
36
54
37 // Required for using shared_ptr in signals/slots
55 // Required for using shared_ptr in signals/slots
38 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_PTR_REGISTRY, std::shared_ptr<IDataProvider>)
56 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_PTR_REGISTRY, std::shared_ptr<IDataProvider>)
57 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_FUNCTION_REGISTRY,
58 std::function<void(QNetworkReply *, QUuid)>)
39
59
40 #endif // SCIQLOP_IDATAPROVIDER_H
60 #endif // SCIQLOP_IDATAPROVIDER_H
@@ -1,30 +1,43
1 #ifndef SCIQLOP_NETWORKCONTROLLER_H
1 #ifndef SCIQLOP_NETWORKCONTROLLER_H
2 #define SCIQLOP_NETWORKCONTROLLER_H
2 #define SCIQLOP_NETWORKCONTROLLER_H
3
3
4 #include <QLoggingCategory>
4 #include <QLoggingCategory>
5 #include <QObject>
5 #include <QObject>
6 #include <QUuid>
6
7
7 #include <Common/spimpl.h>
8 #include <Common/spimpl.h>
9 #include <functional>
8
10
9 Q_DECLARE_LOGGING_CATEGORY(LOG_NetworkController)
11 Q_DECLARE_LOGGING_CATEGORY(LOG_NetworkController)
10
12
13 class QNetworkReply;
14 class QNetworkRequest;
15
11 /**
16 /**
12 * @brief The NetworkController class aims to handle all network connection of SciQlop.
17 * @brief The NetworkController class aims to handle all network connection of SciQlop.
13 */
18 */
14 class NetworkController : public QObject {
19 class NetworkController : public QObject {
15 Q_OBJECT
20 Q_OBJECT
16 public:
21 public:
17 explicit NetworkController(QObject *parent = 0);
22 explicit NetworkController(QObject *parent = 0);
18
23
19
20 void initialize();
24 void initialize();
21 void finalize();
25 void finalize();
22
26
27 public slots:
28 void onProcessRequested(const QNetworkRequest &request, QUuid identifier,
29 std::function<void(QNetworkReply *, QUuid)> callback);
30 void onReplyCanceled(QUuid identifier);
31
32 signals:
33 void replyFinished(QNetworkReply *reply, QUuid identifier);
34 void replyDownloadProgress(QUuid identifier);
35
23 private:
36 private:
24 void waitForFinish();
37 void waitForFinish();
25
38
26 class NetworkControllerPrivate;
39 class NetworkControllerPrivate;
27 spimpl::unique_impl_ptr<NetworkControllerPrivate> impl;
40 spimpl::unique_impl_ptr<NetworkControllerPrivate> impl;
28 };
41 };
29
42
30 #endif // SCIQLOP_NETWORKCONTROLLER_H
43 #endif // SCIQLOP_NETWORKCONTROLLER_H
@@ -1,33 +1,88
1 #include "Network/NetworkController.h"
1 #include "Network/NetworkController.h"
2
2
3 #include <QMutex>
3 #include <QMutex>
4 #include <QNetworkAccessManager>
5 #include <QNetworkReply>
6 #include <QNetworkRequest>
4 #include <QThread>
7 #include <QThread>
5
8
9 #include <unordered_map>
10
6 Q_LOGGING_CATEGORY(LOG_NetworkController, "NetworkController")
11 Q_LOGGING_CATEGORY(LOG_NetworkController, "NetworkController")
7
12
8 struct NetworkController::NetworkControllerPrivate {
13 struct NetworkController::NetworkControllerPrivate {
9 explicit NetworkControllerPrivate(NetworkController *parent) : m_WorkingMutex{} {}
14 explicit NetworkControllerPrivate(NetworkController *parent) : m_WorkingMutex{} {}
10 QMutex m_WorkingMutex;
15 QMutex m_WorkingMutex;
16
17 std::unordered_map<QNetworkReply *, QUuid> m_NetworkReplyToVariableId;
18 std::unique_ptr<QNetworkAccessManager> m_AccessManager{nullptr};
11 };
19 };
12
20
13 NetworkController::NetworkController(QObject *parent)
21 NetworkController::NetworkController(QObject *parent)
14 : QObject(parent), impl{spimpl::make_unique_impl<NetworkControllerPrivate>(this)}
22 : QObject(parent), impl{spimpl::make_unique_impl<NetworkControllerPrivate>(this)}
15 {
23 {
16 }
24 }
17
25
26 void NetworkController::onProcessRequested(const QNetworkRequest &request, QUuid identifier,
27 std::function<void(QNetworkReply *, QUuid)> callback)
28 {
29 qCDebug(LOG_NetworkController()) << tr("NetworkController registered")
30 << QThread::currentThread();
31 auto reply = impl->m_AccessManager->get(request);
32
33 // Store the couple reply id
34 impl->m_NetworkReplyToVariableId[reply] = identifier;
35
36 auto onReplyFinished = [reply, this, identifier, callback]() {
37
38 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished")
39 << QThread::currentThread();
40 auto it = impl->m_NetworkReplyToVariableId.find(reply);
41 if (it != impl->m_NetworkReplyToVariableId.cend()) {
42 callback(reply, identifier);
43 }
44 };
45
46 auto onReplyDownloadProgress = [reply, this]() {
47
48 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyDownloadProgress")
49 << QThread::currentThread();
50 auto it = impl->m_NetworkReplyToVariableId.find(reply);
51 if (it != impl->m_NetworkReplyToVariableId.cend()) {
52 emit this->replyDownloadProgress(it->second);
53 }
54 };
55
56
57 connect(reply, &QNetworkReply::finished, this, onReplyFinished);
58 connect(reply, &QNetworkReply::downloadProgress, this, onReplyDownloadProgress);
59 }
60
18 void NetworkController::initialize()
61 void NetworkController::initialize()
19 {
62 {
20 qCDebug(LOG_NetworkController()) << tr("NetworkController init") << QThread::currentThread();
63 qCDebug(LOG_NetworkController()) << tr("NetworkController init") << QThread::currentThread();
21 impl->m_WorkingMutex.lock();
64 impl->m_WorkingMutex.lock();
65 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
22 qCDebug(LOG_NetworkController()) << tr("NetworkController init END");
66 qCDebug(LOG_NetworkController()) << tr("NetworkController init END");
23 }
67 }
24
68
25 void NetworkController::finalize()
69 void NetworkController::finalize()
26 {
70 {
27 impl->m_WorkingMutex.unlock();
71 impl->m_WorkingMutex.unlock();
28 }
72 }
29
73
74 void NetworkController::onReplyCanceled(QUuid identifier)
75 {
76 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
77
78 auto end = impl->m_NetworkReplyToVariableId.cend();
79 auto it = std::find_if(impl->m_NetworkReplyToVariableId.cbegin(), end, findReply);
80 if (it != end) {
81 it->first->abort();
82 }
83 }
84
30 void NetworkController::waitForFinish()
85 void NetworkController::waitForFinish()
31 {
86 {
32 QMutexLocker locker{&impl->m_WorkingMutex};
87 QMutexLocker locker{&impl->m_WorkingMutex};
33 }
88 }
@@ -1,205 +1,205
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableCacheController.h>
2 #include <Variable/VariableCacheController.h>
3 #include <Variable/VariableController.h>
3 #include <Variable/VariableController.h>
4 #include <Variable/VariableModel.h>
4 #include <Variable/VariableModel.h>
5
5
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Data/IDataProvider.h>
7 #include <Data/IDataProvider.h>
8 #include <Data/IDataSeries.h>
8 #include <Data/IDataSeries.h>
9 #include <Time/TimeController.h>
9 #include <Time/TimeController.h>
10
10
11 #include <QDateTime>
11 #include <QDateTime>
12 #include <QMutex>
12 #include <QMutex>
13 #include <QThread>
13 #include <QThread>
14 #include <QUuid>
14 #include <QUuid>
15 #include <QtCore/QItemSelectionModel>
15 #include <QtCore/QItemSelectionModel>
16
16
17 #include <unordered_map>
17 #include <unordered_map>
18
18
19 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
19 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
20
20
21 struct VariableController::VariableControllerPrivate {
21 struct VariableController::VariableControllerPrivate {
22 explicit VariableControllerPrivate(VariableController *parent)
22 explicit VariableControllerPrivate(VariableController *parent)
23 : m_WorkingMutex{},
23 : m_WorkingMutex{},
24 m_VariableModel{new VariableModel{parent}},
24 m_VariableModel{new VariableModel{parent}},
25 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
25 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
26 m_VariableCacheController{std::make_unique<VariableCacheController>()}
26 m_VariableCacheController{std::make_unique<VariableCacheController>()}
27 {
27 {
28 }
28 }
29
29
30 QMutex m_WorkingMutex;
30 QMutex m_WorkingMutex;
31 /// Variable model. The VariableController has the ownership
31 /// Variable model. The VariableController has the ownership
32 VariableModel *m_VariableModel;
32 VariableModel *m_VariableModel;
33 QItemSelectionModel *m_VariableSelectionModel;
33 QItemSelectionModel *m_VariableSelectionModel;
34
34
35
35
36 TimeController *m_TimeController{nullptr};
36 TimeController *m_TimeController{nullptr};
37 std::unique_ptr<VariableCacheController> m_VariableCacheController;
37 std::unique_ptr<VariableCacheController> m_VariableCacheController;
38
38
39 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
39 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
40 m_VariableToProviderMap;
40 m_VariableToProviderMap;
41 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToToken;
41 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifier;
42 };
42 };
43
43
44 VariableController::VariableController(QObject *parent)
44 VariableController::VariableController(QObject *parent)
45 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
45 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
46 {
46 {
47 qCDebug(LOG_VariableController()) << tr("VariableController construction")
47 qCDebug(LOG_VariableController()) << tr("VariableController construction")
48 << QThread::currentThread();
48 << QThread::currentThread();
49 }
49 }
50
50
51 VariableController::~VariableController()
51 VariableController::~VariableController()
52 {
52 {
53 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
53 qCDebug(LOG_VariableController()) << tr("VariableController destruction")
54 << QThread::currentThread();
54 << QThread::currentThread();
55 this->waitForFinish();
55 this->waitForFinish();
56 }
56 }
57
57
58 VariableModel *VariableController::variableModel() noexcept
58 VariableModel *VariableController::variableModel() noexcept
59 {
59 {
60 return impl->m_VariableModel;
60 return impl->m_VariableModel;
61 }
61 }
62
62
63 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
63 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
64 {
64 {
65 return impl->m_VariableSelectionModel;
65 return impl->m_VariableSelectionModel;
66 }
66 }
67
67
68 void VariableController::setTimeController(TimeController *timeController) noexcept
68 void VariableController::setTimeController(TimeController *timeController) noexcept
69 {
69 {
70 impl->m_TimeController = timeController;
70 impl->m_TimeController = timeController;
71 }
71 }
72
72
73 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
73 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
74 {
74 {
75 if (!variable) {
75 if (!variable) {
76 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
76 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
77 return;
77 return;
78 }
78 }
79
79
80 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
80 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
81 // make some treatments before the deletion
81 // make some treatments before the deletion
82 emit variableAboutToBeDeleted(variable);
82 emit variableAboutToBeDeleted(variable);
83
83
84 // Deletes provider
84 // Deletes provider
85 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
85 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
86 qCDebug(LOG_VariableController())
86 qCDebug(LOG_VariableController())
87 << tr("Number of providers deleted for variable %1: %2")
87 << tr("Number of providers deleted for variable %1: %2")
88 .arg(variable->name(), QString::number(nbProvidersDeleted));
88 .arg(variable->name(), QString::number(nbProvidersDeleted));
89
89
90 // Clears cache
90 // Clears cache
91 impl->m_VariableCacheController->clear(variable);
91 impl->m_VariableCacheController->clear(variable);
92
92
93 // Deletes from model
93 // Deletes from model
94 impl->m_VariableModel->deleteVariable(variable);
94 impl->m_VariableModel->deleteVariable(variable);
95 }
95 }
96
96
97 void VariableController::deleteVariables(
97 void VariableController::deleteVariables(
98 const QVector<std::shared_ptr<Variable> > &variables) noexcept
98 const QVector<std::shared_ptr<Variable> > &variables) noexcept
99 {
99 {
100 for (auto variable : qAsConst(variables)) {
100 for (auto variable : qAsConst(variables)) {
101 deleteVariable(variable);
101 deleteVariable(variable);
102 }
102 }
103 }
103 }
104
104
105 void VariableController::createVariable(const QString &name,
105 void VariableController::createVariable(const QString &name,
106 std::shared_ptr<IDataProvider> provider) noexcept
106 std::shared_ptr<IDataProvider> provider) noexcept
107 {
107 {
108
108
109 if (!impl->m_TimeController) {
109 if (!impl->m_TimeController) {
110 qCCritical(LOG_VariableController())
110 qCCritical(LOG_VariableController())
111 << tr("Impossible to create variable: The time controller is null");
111 << tr("Impossible to create variable: The time controller is null");
112 return;
112 return;
113 }
113 }
114
114
115
115
116 /// @todo : for the moment :
116 /// @todo : for the moment :
117 /// - the provider is only used to retrieve data from the variable for its initialization, but
117 /// - the provider is only used to retrieve data from the variable for its initialization, but
118 /// it will be retained later
118 /// it will be retained later
119 /// - default data are generated for the variable, without taking into account the timerange set
119 /// - default data are generated for the variable, without taking into account the timerange set
120 /// in sciqlop
120 /// in sciqlop
121 auto dateTime = impl->m_TimeController->dateTime();
121 auto dateTime = impl->m_TimeController->dateTime();
122 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime)) {
122 if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime)) {
123 auto token = QUuid::createUuid();
123 auto identifier = QUuid::createUuid();
124
124
125 // store the provider
125 // store the provider
126 impl->m_VariableToProviderMap[newVariable] = provider;
126 impl->m_VariableToProviderMap[newVariable] = provider;
127 impl->m_VariableToToken[newVariable] = token;
127 impl->m_VariableToIdentifier[newVariable] = identifier;
128
128
129 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
129 auto addDateTimeAcquired = [ this, varW = std::weak_ptr<Variable>{newVariable} ](
130 QUuid token, auto dataSeriesAcquired, auto dateTimeToPutInCache)
130 QUuid identifier, auto dataSeriesAcquired, auto dateTimeToPutInCache)
131 {
131 {
132 if (auto variable = varW.lock()) {
132 if (auto variable = varW.lock()) {
133 auto varToken = impl->m_VariableToToken.at(variable);
133 auto varIdentifier = impl->m_VariableToIdentifier.at(variable);
134 if (varToken == token) {
134 if (varIdentifier == identifier) {
135 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
135 impl->m_VariableCacheController->addDateTime(variable, dateTimeToPutInCache);
136 variable->setDataSeries(dataSeriesAcquired);
136 variable->setDataSeries(dataSeriesAcquired);
137 }
137 }
138 }
138 }
139 };
139 };
140
140
141 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
141 connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired);
142 this->onRequestDataLoading(newVariable, dateTime);
142 this->onRequestDataLoading(newVariable, dateTime);
143 }
143 }
144 }
144 }
145
145
146 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
146 void VariableController::onDateTimeOnSelection(const SqpDateTime &dateTime)
147 {
147 {
148 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
148 qCDebug(LOG_VariableController()) << "VariableController::onDateTimeOnSelection"
149 << QThread::currentThread()->objectName();
149 << QThread::currentThread()->objectName();
150 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
150 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
151
151
152 for (const auto &selectedRow : qAsConst(selectedRows)) {
152 for (const auto &selectedRow : qAsConst(selectedRows)) {
153 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
153 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
154 selectedVariable->setDateTime(dateTime);
154 selectedVariable->setDateTime(dateTime);
155 this->onRequestDataLoading(selectedVariable, dateTime);
155 this->onRequestDataLoading(selectedVariable, dateTime);
156 }
156 }
157 }
157 }
158 }
158 }
159
159
160
160
161 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
161 void VariableController::onRequestDataLoading(std::shared_ptr<Variable> variable,
162 const SqpDateTime &dateTime)
162 const SqpDateTime &dateTime)
163 {
163 {
164 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
164 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
165 << QThread::currentThread()->objectName();
165 << QThread::currentThread()->objectName();
166 // we want to load data of the variable for the dateTime.
166 // we want to load data of the variable for the dateTime.
167 // First we check if the cache contains some of them.
167 // First we check if the cache contains some of them.
168 // For the other, we ask the provider to give them.
168 // For the other, we ask the provider to give them.
169 if (variable) {
169 if (variable) {
170
170
171 auto dateTimeListNotInCache
171 auto dateTimeListNotInCache
172 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
172 = impl->m_VariableCacheController->provideNotInCacheDateTimeList(variable, dateTime);
173
173
174 if (!dateTimeListNotInCache.empty()) {
174 if (!dateTimeListNotInCache.empty()) {
175 // Ask the provider for each data on the dateTimeListNotInCache
175 // Ask the provider for each data on the dateTimeListNotInCache
176 auto token = impl->m_VariableToToken.at(variable);
176 auto identifier = impl->m_VariableToIdentifier.at(variable);
177 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
177 impl->m_VariableToProviderMap.at(variable)->requestDataLoading(
178 token, std::move(dateTimeListNotInCache));
178 identifier, std::move(dateTimeListNotInCache));
179 }
179 }
180 else {
180 else {
181 emit variable->updated();
181 emit variable->updated();
182 }
182 }
183 }
183 }
184 else {
184 else {
185 qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
185 qCCritical(LOG_VariableController()) << tr("Impossible to load data of a variable null");
186 }
186 }
187 }
187 }
188
188
189
189
190 void VariableController::initialize()
190 void VariableController::initialize()
191 {
191 {
192 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
192 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
193 impl->m_WorkingMutex.lock();
193 impl->m_WorkingMutex.lock();
194 qCDebug(LOG_VariableController()) << tr("VariableController init END");
194 qCDebug(LOG_VariableController()) << tr("VariableController init END");
195 }
195 }
196
196
197 void VariableController::finalize()
197 void VariableController::finalize()
198 {
198 {
199 impl->m_WorkingMutex.unlock();
199 impl->m_WorkingMutex.unlock();
200 }
200 }
201
201
202 void VariableController::waitForFinish()
202 void VariableController::waitForFinish()
203 {
203 {
204 QMutexLocker locker{&impl->m_WorkingMutex};
204 QMutexLocker locker{&impl->m_WorkingMutex};
205 }
205 }
@@ -1,140 +1,140
1 #include "SqpApplication.h"
1 #include "SqpApplication.h"
2
2
3 #include <Data/IDataProvider.h>
3 #include <Data/IDataProvider.h>
4 #include <DataSource/DataSourceController.h>
4 #include <DataSource/DataSourceController.h>
5 #include <Network/NetworkController.h>
5 #include <Network/NetworkController.h>
6 #include <QThread>
6 #include <QThread>
7 #include <Time/TimeController.h>
7 #include <Time/TimeController.h>
8 #include <Variable/Variable.h>
8 #include <Variable/Variable.h>
9 #include <Variable/VariableController.h>
9 #include <Variable/VariableController.h>
10 #include <Visualization/VisualizationController.h>
10 #include <Visualization/VisualizationController.h>
11
11
12 Q_LOGGING_CATEGORY(LOG_SqpApplication, "SqpApplication")
12 Q_LOGGING_CATEGORY(LOG_SqpApplication, "SqpApplication")
13
13
14 class SqpApplication::SqpApplicationPrivate {
14 class SqpApplication::SqpApplicationPrivate {
15 public:
15 public:
16 SqpApplicationPrivate()
16 SqpApplicationPrivate()
17 : m_DataSourceController{std::make_unique<DataSourceController>()},
17 : m_DataSourceController{std::make_unique<DataSourceController>()},
18 m_NetworkController{std::make_unique<NetworkController>()},
18 m_NetworkController{std::make_unique<NetworkController>()},
19 m_TimeController{std::make_unique<TimeController>()},
19 m_TimeController{std::make_unique<TimeController>()},
20 m_VariableController{std::make_unique<VariableController>()},
20 m_VariableController{std::make_unique<VariableController>()},
21 m_VisualizationController{std::make_unique<VisualizationController>()}
21 m_VisualizationController{std::make_unique<VisualizationController>()}
22 {
22 {
23 // /////////////////////////////// //
23 // /////////////////////////////// //
24 // Connections between controllers //
24 // Connections between controllers //
25 // /////////////////////////////// //
25 // /////////////////////////////// //
26
26
27 // VariableController <-> DataSourceController
27 // VariableController <-> DataSourceController
28 connect(m_DataSourceController.get(),
28 connect(m_DataSourceController.get(),
29 SIGNAL(variableCreationRequested(const QString &, std::shared_ptr<IDataProvider>)),
29 SIGNAL(variableCreationRequested(const QString &, std::shared_ptr<IDataProvider>)),
30 m_VariableController.get(),
30 m_VariableController.get(),
31 SLOT(createVariable(const QString &, std::shared_ptr<IDataProvider>)));
31 SLOT(createVariable(const QString &, std::shared_ptr<IDataProvider>)));
32
32
33 // VariableController <-> VisualizationController
33 // VariableController <-> VisualizationController
34 connect(m_VariableController.get(),
34 connect(m_VariableController.get(),
35 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)),
35 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)),
36 m_VisualizationController.get(),
36 m_VisualizationController.get(),
37 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), Qt::DirectConnection);
37 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), Qt::DirectConnection);
38
38
39
39
40 m_DataSourceController->moveToThread(&m_DataSourceControllerThread);
40 m_DataSourceController->moveToThread(&m_DataSourceControllerThread);
41 m_NetworkController->moveToThread(&m_NetworkControllerThread);
41 m_NetworkController->moveToThread(&m_NetworkControllerThread);
42 m_VariableController->moveToThread(&m_VariableControllerThread);
42 m_VariableController->moveToThread(&m_VariableControllerThread);
43 m_VisualizationController->moveToThread(&m_VisualizationControllerThread);
43 m_VisualizationController->moveToThread(&m_VisualizationControllerThread);
44
44
45
45
46 // Additionnal init
46 // Additionnal init
47 m_VariableController->setTimeController(m_TimeController.get());
47 m_VariableController->setTimeController(m_TimeController.get());
48 }
48 }
49
49
50 virtual ~SqpApplicationPrivate()
50 virtual ~SqpApplicationPrivate()
51 {
51 {
52 qCInfo(LOG_SqpApplication()) << tr("SqpApplicationPrivate destruction");
52 qCInfo(LOG_SqpApplication()) << tr("SqpApplicationPrivate destruction");
53 m_DataSourceControllerThread.quit();
53 m_DataSourceControllerThread.quit();
54 m_DataSourceControllerThread.wait();
54 m_DataSourceControllerThread.wait();
55
55
56 m_NetworkControllerThread.quit();
56 m_NetworkControllerThread.quit();
57 m_NetworkControllerThread.wait();
57 m_NetworkControllerThread.wait();
58
58
59 m_VariableControllerThread.quit();
59 m_VariableControllerThread.quit();
60 m_VariableControllerThread.wait();
60 m_VariableControllerThread.wait();
61
61
62 m_VisualizationControllerThread.quit();
62 m_VisualizationControllerThread.quit();
63 m_VisualizationControllerThread.wait();
63 m_VisualizationControllerThread.wait();
64 }
64 }
65
65
66 std::unique_ptr<DataSourceController> m_DataSourceController;
66 std::unique_ptr<DataSourceController> m_DataSourceController;
67 std::unique_ptr<VariableController> m_VariableController;
67 std::unique_ptr<VariableController> m_VariableController;
68 std::unique_ptr<TimeController> m_TimeController;
68 std::unique_ptr<TimeController> m_TimeController;
69 std::unique_ptr<NetworkController> m_NetworkController;
69 std::unique_ptr<NetworkController> m_NetworkController;
70 std::unique_ptr<VisualizationController> m_VisualizationController;
70 std::unique_ptr<VisualizationController> m_VisualizationController;
71 QThread m_DataSourceControllerThread;
71 QThread m_DataSourceControllerThread;
72 QThread m_NetworkControllerThread;
72 QThread m_NetworkControllerThread;
73 QThread m_VariableControllerThread;
73 QThread m_VariableControllerThread;
74 QThread m_VisualizationControllerThread;
74 QThread m_VisualizationControllerThread;
75 };
75 };
76
76
77
77
78 SqpApplication::SqpApplication(int &argc, char **argv)
78 SqpApplication::SqpApplication(int &argc, char **argv)
79 : QApplication{argc, argv}, impl{spimpl::make_unique_impl<SqpApplicationPrivate>()}
79 : QApplication{argc, argv}, impl{spimpl::make_unique_impl<SqpApplicationPrivate>()}
80 {
80 {
81 qCInfo(LOG_SqpApplication()) << tr("SqpApplication construction");
81 qCDebug(LOG_SqpApplication()) << tr("SqpApplication construction") << QThread::currentThread();
82
82
83 connect(&impl->m_DataSourceControllerThread, &QThread::started,
83 connect(&impl->m_DataSourceControllerThread, &QThread::started,
84 impl->m_DataSourceController.get(), &DataSourceController::initialize);
84 impl->m_DataSourceController.get(), &DataSourceController::initialize);
85 connect(&impl->m_DataSourceControllerThread, &QThread::finished,
85 connect(&impl->m_DataSourceControllerThread, &QThread::finished,
86 impl->m_DataSourceController.get(), &DataSourceController::finalize);
86 impl->m_DataSourceController.get(), &DataSourceController::finalize);
87
87
88 connect(&impl->m_NetworkControllerThread, &QThread::started, impl->m_NetworkController.get(),
88 connect(&impl->m_NetworkControllerThread, &QThread::started, impl->m_NetworkController.get(),
89 &NetworkController::initialize);
89 &NetworkController::initialize);
90 connect(&impl->m_NetworkControllerThread, &QThread::finished, impl->m_NetworkController.get(),
90 connect(&impl->m_NetworkControllerThread, &QThread::finished, impl->m_NetworkController.get(),
91 &NetworkController::finalize);
91 &NetworkController::finalize);
92
92
93 connect(&impl->m_VariableControllerThread, &QThread::started, impl->m_VariableController.get(),
93 connect(&impl->m_VariableControllerThread, &QThread::started, impl->m_VariableController.get(),
94 &VariableController::initialize);
94 &VariableController::initialize);
95 connect(&impl->m_VariableControllerThread, &QThread::finished, impl->m_VariableController.get(),
95 connect(&impl->m_VariableControllerThread, &QThread::finished, impl->m_VariableController.get(),
96 &VariableController::finalize);
96 &VariableController::finalize);
97
97
98 connect(&impl->m_VisualizationControllerThread, &QThread::started,
98 connect(&impl->m_VisualizationControllerThread, &QThread::started,
99 impl->m_VisualizationController.get(), &VisualizationController::initialize);
99 impl->m_VisualizationController.get(), &VisualizationController::initialize);
100 connect(&impl->m_VisualizationControllerThread, &QThread::finished,
100 connect(&impl->m_VisualizationControllerThread, &QThread::finished,
101 impl->m_VisualizationController.get(), &VisualizationController::finalize);
101 impl->m_VisualizationController.get(), &VisualizationController::finalize);
102
102
103 impl->m_DataSourceControllerThread.start();
103 impl->m_DataSourceControllerThread.start();
104 impl->m_NetworkControllerThread.start();
104 impl->m_NetworkControllerThread.start();
105 impl->m_VariableControllerThread.start();
105 impl->m_VariableControllerThread.start();
106 impl->m_VisualizationControllerThread.start();
106 impl->m_VisualizationControllerThread.start();
107 }
107 }
108
108
109 SqpApplication::~SqpApplication()
109 SqpApplication::~SqpApplication()
110 {
110 {
111 }
111 }
112
112
113 void SqpApplication::initialize()
113 void SqpApplication::initialize()
114 {
114 {
115 }
115 }
116
116
117 DataSourceController &SqpApplication::dataSourceController() noexcept
117 DataSourceController &SqpApplication::dataSourceController() noexcept
118 {
118 {
119 return *impl->m_DataSourceController;
119 return *impl->m_DataSourceController;
120 }
120 }
121
121
122 NetworkController &SqpApplication::networkController() noexcept
122 NetworkController &SqpApplication::networkController() noexcept
123 {
123 {
124 return *impl->m_NetworkController;
124 return *impl->m_NetworkController;
125 }
125 }
126
126
127 TimeController &SqpApplication::timeController() noexcept
127 TimeController &SqpApplication::timeController() noexcept
128 {
128 {
129 return *impl->m_TimeController;
129 return *impl->m_TimeController;
130 }
130 }
131
131
132 VariableController &SqpApplication::variableController() noexcept
132 VariableController &SqpApplication::variableController() noexcept
133 {
133 {
134 return *impl->m_VariableController;
134 return *impl->m_VariableController;
135 }
135 }
136
136
137 VisualizationController &SqpApplication::visualizationController() noexcept
137 VisualizationController &SqpApplication::visualizationController() noexcept
138 {
138 {
139 return *impl->m_VisualizationController;
139 return *impl->m_VisualizationController;
140 }
140 }
@@ -1,36 +1,38
1 #ifndef SCIQLOP_AMDAPROVIDER_H
1 #ifndef SCIQLOP_AMDAPROVIDER_H
2 #define SCIQLOP_AMDAPROVIDER_H
2 #define SCIQLOP_AMDAPROVIDER_H
3
3
4 #include "AmdaGlobal.h"
4 #include "AmdaGlobal.h"
5
5
6 #include <Common/spimpl.h>
6 #include <Common/spimpl.h>
7
7
8 #include <Data/IDataProvider.h>
8 #include <Data/IDataProvider.h>
9
9
10 #include <QLoggingCategory>
10 #include <QLoggingCategory>
11
11
12
12
13 Q_DECLARE_LOGGING_CATEGORY(LOG_AmdaProvider)
13 Q_DECLARE_LOGGING_CATEGORY(LOG_AmdaProvider)
14
14
15 class QNetworkReply;
16
15 /**
17 /**
16 * @brief The AmdaProvider class is an example of how a data provider can generate data
18 * @brief The AmdaProvider class is an example of how a data provider can generate data
17 */
19 */
18 class SCIQLOP_AMDA_EXPORT AmdaProvider : public IDataProvider {
20 class SCIQLOP_AMDA_EXPORT AmdaProvider : public IDataProvider {
19 public:
21 public:
20 explicit AmdaProvider();
22 explicit AmdaProvider();
21
23
22 void requestDataLoading(QUuid token, const QVector<SqpDateTime> &dateTimeList) override;
24 void requestDataLoading(QUuid token, const QVector<SqpDateTime> &dateTimeList) override;
23
25
24 private:
26 private:
25 void retrieveData(QUuid token, const DataProviderParameters &parameters) const;
27 void retrieveData(QUuid token, const DataProviderParameters &parameters);
26
28
27 class AmdaProviderPrivate;
29 class AmdaProviderPrivate;
28 spimpl::unique_impl_ptr<AmdaProviderPrivate> impl;
30 spimpl::unique_impl_ptr<AmdaProviderPrivate> impl;
29
31
30 private slots:
32 // private slots:
31 void httpFinished() noexcept;
33 // void httpFinished(QNetworkReply *reply, QUuid dataId) noexcept;
32 void httpDownloadFinished() noexcept;
34 // void httpDownloadFinished(QNetworkReply *reply, QUuid dataId) noexcept;
33 void httpDownloadReadyRead() noexcept;
35 // void httpDownloadReadyRead(QNetworkReply *reply, QUuid dataId) noexcept;
34 };
36 };
35
37
36 #endif // SCIQLOP_AMDAPROVIDER_H
38 #endif // SCIQLOP_AMDAPROVIDER_H
@@ -1,134 +1,128
1 #include "AmdaProvider.h"
1 #include "AmdaProvider.h"
2 #include "AmdaResultParser.h"
2 #include "AmdaResultParser.h"
3
3
4 #include <Data/DataProviderParameters.h>
4 #include <Data/DataProviderParameters.h>
5 #include <Network/NetworkController.h>
6 #include <SqpApplication.h>
7 #include <Variable/Variable.h>
5
8
6 #include <QNetworkAccessManager>
9 #include <QNetworkAccessManager>
7 #include <QNetworkReply>
10 #include <QNetworkReply>
8 #include <QTemporaryFile>
11 #include <QTemporaryFile>
12 #include <QThread>
9
13
10 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
14 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
11
15
12 namespace {
16 namespace {
13
17
14 /// URL format for a request on AMDA server. The parameters are as follows:
18 /// URL format for a request on AMDA server. The parameters are as follows:
15 /// - %1: start date
19 /// - %1: start date
16 /// - %2: end date
20 /// - %2: end date
17 /// - %3: parameter id
21 /// - %3: parameter id
18 const auto AMDA_URL_FORMAT = QStringLiteral(
22 const auto AMDA_URL_FORMAT = QStringLiteral(
19 "http://amda.irap.omp.eu/php/rest/"
23 "http://amda.irap.omp.eu/php/rest/"
20 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&sampling=60&outputFormat=ASCII&"
24 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&sampling=60&outputFormat=ASCII&"
21 "timeFormat=ISO8601&gzip=0");
25 "timeFormat=ISO8601&gzip=0");
22
26
23 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
27 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
24 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:ss");
28 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:ss");
25
29
26 /// Formats a time to a date that can be passed in URL
30 /// Formats a time to a date that can be passed in URL
27 QString dateFormat(double sqpDateTime) noexcept
31 QString dateFormat(double sqpDateTime) noexcept
28 {
32 {
29 auto dateTime = QDateTime::fromMSecsSinceEpoch(sqpDateTime * 1000.);
33 auto dateTime = QDateTime::fromMSecsSinceEpoch(sqpDateTime * 1000.);
30 return dateTime.toString(AMDA_TIME_FORMAT);
34 return dateTime.toString(AMDA_TIME_FORMAT);
31 }
35 }
32
36
37
33 } // namespace
38 } // namespace
34
39
35 struct AmdaProvider::AmdaProviderPrivate {
40 struct AmdaProvider::AmdaProviderPrivate {
36 DataProviderParameters m_Params{};
41 DataProviderParameters m_Params{};
37 std::unique_ptr<QNetworkAccessManager> m_AccessManager{nullptr};
42 std::unique_ptr<QNetworkAccessManager> m_AccessManager{nullptr};
38 QNetworkReply *m_Reply{nullptr};
43 QNetworkReply *m_Reply{nullptr};
39 std::unique_ptr<QTemporaryFile> m_File{nullptr};
44 // std::unique_ptr<QTemporaryFile> m_File{nullptr};
40 QUuid m_Token;
45 QUuid m_Token;
41 };
46 };
42
47
43 AmdaProvider::AmdaProvider() : impl{spimpl::make_unique_impl<AmdaProviderPrivate>()}
48 AmdaProvider::AmdaProvider() : impl{spimpl::make_unique_impl<AmdaProviderPrivate>()}
44 {
49 {
50 qCDebug(LOG_NetworkController()) << tr("AmdaProvider::AmdaProvider")
51 << QThread::currentThread();
52 if (auto app = sqpApp) {
53 auto &networkController = app->networkController();
54 connect(this, &AmdaProvider::requestConstructed, &networkController,
55 &NetworkController::onProcessRequested);
56 }
45 }
57 }
46
58
47 void AmdaProvider::requestDataLoading(QUuid token, const QVector<SqpDateTime> &dateTimeList)
59 void AmdaProvider::requestDataLoading(QUuid token, const QVector<SqpDateTime> &dateTimeList)
48 {
60 {
49 // NOTE: Try to use multithread if possible
61 // NOTE: Try to use multithread if possible
50 for (const auto &dateTime : dateTimeList) {
62 for (const auto &dateTime : dateTimeList) {
51 retrieveData(token, DataProviderParameters{dateTime});
63 retrieveData(token, DataProviderParameters{dateTime});
52 }
64 }
53 }
65 }
54
66
55 void AmdaProvider::retrieveData(QUuid token, const DataProviderParameters &parameters) const
67 void AmdaProvider::retrieveData(QUuid token, const DataProviderParameters &parameters)
56 {
68 {
57 // /////////// //
69 // /////////// //
58 // Creates URL //
70 // Creates URL //
59 // /////////// //
71 // /////////// //
60
72
61 auto startDate = dateFormat(parameters.m_Time.m_TStart);
73 auto startDate = dateFormat(parameters.m_Time.m_TStart);
62 auto endDate = dateFormat(parameters.m_Time.m_TEnd);
74 auto endDate = dateFormat(parameters.m_Time.m_TEnd);
63 auto productId = QStringLiteral("imf(0)");
75 auto productId = QStringLiteral("imf(0)");
64
76
65 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
77 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
66
78
67 // //////////////// //
79 auto tempFile = std::make_shared<QTemporaryFile>();
68 // Executes request //
69 // //////////////// //
70
80
71 impl->m_Token = token;
72 impl->m_Params = parameters;
73 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
74 impl->m_Reply = impl->m_AccessManager->get(QNetworkRequest{url});
75 connect(impl->m_Reply, &QNetworkReply::finished, this, &AmdaProvider::httpFinished);
76 }
77
81
78 void AmdaProvider::httpFinished() noexcept
82 // LAMBDA
79 {
83 auto httpDownloadFinished = [this, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
80 // ////////////////////// //
81 // Gets download file url //
82 // ////////////////////// //
83
84 auto downloadFileUrl = QUrl{QString{impl->m_Reply->readAll()}};
85
86 // ///////////////////////////////////// //
87 // Executes request for downloading file //
88 // ///////////////////////////////////// //
89
90 // Deletes old reply
91 impl->m_Reply->deleteLater();
92 impl->m_Reply = nullptr;
93
94 // Creates destination file
95 impl->m_File = std::make_unique<QTemporaryFile>();
96 if (impl->m_File->open()) {
97 qCDebug(LOG_AmdaProvider()) << "Temp file: " << impl->m_File->fileName();
98
99 // Executes request
100 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
101 impl->m_Reply = impl->m_AccessManager->get(QNetworkRequest{downloadFileUrl});
102 connect(impl->m_Reply, &QNetworkReply::finished, this,
103 &AmdaProvider::httpDownloadReadyRead);
104 connect(impl->m_Reply, &QNetworkReply::finished, this, &AmdaProvider::httpDownloadFinished);
105 }
106 }
107
84
108 void AmdaProvider::httpDownloadFinished() noexcept
85 if (tempFile) {
109 {
86 auto replyReadAll = reply->readAll();
110 if (impl->m_File) {
87 if (!replyReadAll.isEmpty()) {
111 impl->m_File->close();
88 tempFile->write(replyReadAll);
89 }
90 tempFile->close();
112
91
113 // Parse results file
92 // Parse results file
114 if (auto dataSeries = AmdaResultParser::readTxt(impl->m_File->fileName())) {
93 if (auto dataSeries = AmdaResultParser::readTxt(tempFile->fileName())) {
115 emit dataProvided(impl->m_Token, dataSeries, impl->m_Params.m_Time);
94 emit dataProvided(impl->m_Token, dataSeries, impl->m_Params.m_Time);
116 }
95 }
117 else {
96 else {
118 /// @todo ALX : debug
97 /// @todo ALX : debug
98 }
119 }
99 }
120
100
121 impl->m_File = nullptr;
101 // Deletes reply
122 }
102 reply->deleteLater();
103 reply = nullptr;
104 };
105 auto httpFinishedLambda = [this, httpDownloadFinished, tempFile](QNetworkReply *reply,
106 QUuid dataId) noexcept {
123
107
124 // Deletes reply
108 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
125 impl->m_Reply->deleteLater();
109 // Deletes old reply
126 impl->m_Reply = nullptr;
110 reply->deleteLater();
127 }
128
111
129 void AmdaProvider::httpDownloadReadyRead() noexcept
112 // Executes request for downloading file //
130 {
113
131 if (impl->m_File) {
114 // Creates destination file
132 impl->m_File->write(impl->m_Reply->readAll());
115 if (tempFile->open()) {
133 }
116 // Executes request
117 emit requestConstructed(QNetworkRequest{downloadFileUrl}, dataId, httpDownloadFinished);
118 }
119 };
120
121 // //////////////// //
122 // Executes request //
123 // //////////////// //
124
125 impl->m_Token = token;
126 impl->m_Params = parameters;
127 emit requestConstructed(QNetworkRequest{url}, token, httpFinishedLambda);
134 }
128 }
General Comments 0
You need to be logged in to leave comments. Login now