diff --git a/src/myx/redis/CMakeLists.txt b/src/myx/redis/CMakeLists.txt index 4e8527d..ec1882f 100644 --- a/src/myx/redis/CMakeLists.txt +++ b/src/myx/redis/CMakeLists.txt @@ -14,10 +14,10 @@ set(TRGT_moc_hpp ${CMAKE_CURRENT_SOURCE_DIR}/client.hpp ${CMAKE_CURRENT_SOURCE_DIR}/lexer.hpp ${CMAKE_CURRENT_SOURCE_DIR}/parser.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/reply.hpp ${CMAKE_CURRENT_SOURCE_DIR}/request.hpp) set(TRGT_hpp + ${CMAKE_CURRENT_SOURCE_DIR}/reply.hpp ${CMAKE_CURRENT_SOURCE_DIR}/client-inl.hpp ${CMAKE_CURRENT_SOURCE_DIR}/lexer-inl.hpp ${CMAKE_CURRENT_SOURCE_DIR}/parser-inl.hpp @@ -26,13 +26,15 @@ set(TRGT_hpp set(TRGT_headers ${TRGT_moc_hpp} ${TRGT_hpp}) # cmake-format: on +qt5_wrap_cpp(TRGT_moc_cpp ${TRGT_moc_hpp}) + add_library(${TRGT}-header-only INTERFACE) target_include_directories( ${TRGT}-header-only SYSTEM INTERFACE "$" "$") if(MYXLIB_BUILD_LIBRARIES) - add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_cpp} ${TRGT_headers}) + add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_moc_cpp} ${TRGT_cpp} ${TRGT_headers}) common_target_properties(${TRGT}) # Создание цели для проверки утилитой clang-tidy diff --git a/src/myx/redis/client.hpp b/src/myx/redis/client.hpp index da914a7..cf93d86 100644 --- a/src/myx/redis/client.hpp +++ b/src/myx/redis/client.hpp @@ -3,7 +3,6 @@ #pragma once -#include #include #include #include @@ -16,6 +15,8 @@ namespace myx { namespace redis { +QT_FORWARD_DECLARE_CLASS( ClientPrivate ) + /** * @brief Provides access to a Redis server */ @@ -111,36 +112,36 @@ public: private: - class ClientPrivate : public QObject - { - Q_OBJECT - - friend class Client; - - explicit ClientPrivate( Client* client = nullptr ) : - m_lexer ( &m_socket ), - m_parser( &m_lexer ) - { - connect( &m_socket, &QTcpSocket::connected, client, &Client::connected ); - connect( &m_socket, &QTcpSocket::disconnected, client, &Client::disconnected ); - connect( &m_parser, &Parser::reply, this, &ClientPrivate::sendReply ); - } - - - QTcpSocket m_socket; - QQueue< Request* > m_queue; - Lexer m_lexer; - Parser m_parser; - - Q_SLOT void sendReply( const myx::redis::Reply& reply ) - { - Q_EMIT m_queue.dequeue()->reply( reply ); - } - }; // class ClientPrivate - const QScopedPointer< ClientPrivate > d; }; // class Client +class ClientPrivate : public QObject +{ + Q_OBJECT + + friend class Client; + + explicit ClientPrivate( Client* client = nullptr ) : + m_lexer ( &m_socket ), + m_parser( &m_lexer ) + { + connect( &m_socket, &QTcpSocket::connected, client, &Client::connected ); + connect( &m_socket, &QTcpSocket::disconnected, client, &Client::disconnected ); + connect( &m_parser, &Parser::reply, this, &ClientPrivate::sendReply ); + } + + + QTcpSocket m_socket; + QQueue< Request* > m_queue; + Lexer m_lexer; + Parser m_parser; + + Q_SLOT void sendReply( const myx::redis::Reply& reply ) + { + Q_EMIT m_queue.dequeue()->reply( reply ); + } +}; // class ClientPrivate + } // namespace redis } // namespace myx diff --git a/src/myx/redis/request.hpp b/src/myx/redis/request.hpp index a4e52e9..ad1dd1b 100644 --- a/src/myx/redis/request.hpp +++ b/src/myx/redis/request.hpp @@ -14,6 +14,18 @@ namespace myx { namespace redis { +class Loop : public QObject +{ + Q_OBJECT + + friend class Request; + explicit Loop( QObject* parent = nullptr ) { Q_UNUSED( parent ) } + + QEventLoop m_loop; + Q_SLOT void quitEventLoop() { m_loop.exit( 1 ); } +}; + + /** * @brief Represents a Redis command and its response */ @@ -54,17 +66,6 @@ public: private: - class Loop : public QObject - { - Q_OBJECT - - friend class Request; - explicit Loop( QObject* parent = nullptr ); - - QEventLoop m_loop; - Q_SLOT void quitEventLoop() { m_loop.exit( 1 ); } - }; - const QScopedPointer< Loop > d; }; // class Request diff --git a/src/myx/redis/request_p-inl.hpp b/src/myx/redis/request_p-inl.hpp new file mode 100644 index 0000000..ed7676c --- /dev/null +++ b/src/myx/redis/request_p-inl.hpp @@ -0,0 +1,46 @@ +#ifndef MYX_REDIS_REQUEST_INL_HPP_ +#define MYX_REDIS_REQUEST_INL_HPP_ + +#pragma once + +#include + +#ifndef MYXLIB_HEADER_ONLY +#include +#endif + +#include + +namespace myx { + +namespace redis { + +MYXLIB_INLINE Request::Request( QObject* parent ) : + QObject( parent ), + d ( new Loop( parent ) ) +{ + connect( this, &Request::reply, this, &Request::deleteLater ); +} + + +MYXLIB_INLINE bool Request::waitForReply( int msecs ) +{ + QTimer timer; + timer.setInterval( msecs ); + timer.setSingleShot( true ); + + connect( &timer, &QTimer::timeout, &d->m_loop, &QEventLoop::quit ); + connect( this, &Request::reply, d.data(), &Loop::quitEventLoop ); + + /* + * If the timer fires, the return value will be 0. + * Otherwise, quitEventLoop() will terminate the loop with 1. + */ + return( ( d->m_loop.exec( QEventLoop::ExcludeUserInputEvents ) != 0 ) ); +} + +} // namespace redis + +} // namespace myx + +#endif // ifndef MYX_REDIS_REQUEST_INL_HPP_