From 34a29fd2d57d97fd5520fdf2acfe6c6e392e0b60 Mon Sep 17 00:00:00 2001 From: Vitalii Arteev Date: Wed, 14 Oct 2020 17:35:24 +0200 Subject: [PATCH] Add auxiliary API for Proxy --- src/ipc/ipc-common/CMakeLists.txt | 1 + src/ipc/ipc-common/IPCProxyBase.h | 4 +- src/ipc/ipc-common/observer.h | 103 ++++++++++++++++++ tests/CMakeLists.txt | 1 + tests/unittest_observer/CMakeLists.txt | 23 ++++ .../FaceliftObserverTest.cpp | 43 ++++++++ 6 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 src/ipc/ipc-common/observer.h create mode 100644 tests/unittest_observer/CMakeLists.txt create mode 100644 tests/unittest_observer/FaceliftObserverTest.cpp diff --git a/src/ipc/ipc-common/CMakeLists.txt b/src/ipc/ipc-common/CMakeLists.txt index 42413c67..f0cd1417 100644 --- a/src/ipc/ipc-common/CMakeLists.txt +++ b/src/ipc/ipc-common/CMakeLists.txt @@ -48,6 +48,7 @@ facelift_add_library(FaceliftIPCCommonLib SerializeParameterFunction.h StaticArrayReference.h ipc-common.h + observer.h LINK_LIBRARIES FaceliftModelLib FaceliftCommonLib MONOLITHIC_SUPPORTED ) diff --git a/src/ipc/ipc-common/IPCProxyBase.h b/src/ipc/ipc-common/IPCProxyBase.h index 25701b8d..cef22db4 100644 --- a/src/ipc/ipc-common/IPCProxyBase.h +++ b/src/ipc/ipc-common/IPCProxyBase.h @@ -33,7 +33,7 @@ #include "ipc-common.h" #include "IPCProxyBaseBase.h" #include "IPCProxyBinderBase.h" - +#include "observer.h" #if defined(FaceliftIPCCommonLib_LIBRARY) # define FaceliftIPCCommonLib_EXPORT Q_DECL_EXPORT @@ -49,10 +49,12 @@ class IPCProxyBase : public AdapterType, protected IPCProxyBaseBase public: using InterfaceType = AdapterType; + IsReadyObserver m_readyObserver{}; public: IPCProxyBase(QObject *parent) : AdapterType(parent) { + QObject::connect(this, &InterfaceBase::readyChanged, &m_readyObserver, &IsReadyObserver::onReadyChanged); } template diff --git a/src/ipc/ipc-common/observer.h b/src/ipc/ipc-common/observer.h new file mode 100644 index 00000000..3d374f70 --- /dev/null +++ b/src/ipc/ipc-common/observer.h @@ -0,0 +1,103 @@ +/********************************************************************** +** +** Copyright (C) 2020 Luxoft Sweden AB +** +** This file is part of the FaceLift project +** +** Permission is hereby granted, freIPCServiceAdapterBasee of charge, to any person +** obtaining a copy of this software and associated documentation files +** (the "Software"), to deal in the Software without restriction, +** including without limitation the rights to use, copy, modify, merge, +** publish, distribute, sublicense, and/or sell copies of the Software, +** and to permit persons to whom the Software is furnished to do so, +** subject to the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +** BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +** ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** SPDX-License-Identifier: MIT +** +**********************************************************************/ +#pragma once + +#include +#include +#include + +namespace facelift { + +class IObserver : public QObject +{ + Q_OBJECT +public: + virtual void onReadyChanged(std::shared_ptr connection) = 0; +}; + +class IsReadyObserver: public QObject +{ + Q_OBJECT + std::vector m_observers; + std::shared_ptr connection; +public: + IsReadyObserver() : connection{std::make_shared()} + { + *connection = QObject::connect(this, &IsReadyObserver::readyChanged, this, [ this ](){ + for (auto observer : m_observers) { + observer->onReadyChanged( connection ); + } + }); + } + // Set observers + void setObservers(const std::vector &observers){ + m_observers = observers; + } + + // Get observers + const std::vector& getObservers() const { + return m_observers; + } + + Q_SIGNAL void readyChanged(); + void onReadyChanged(){ + emit readyChanged(); + }; +}; + +// Single-time observer which will unregister itself when done +template +class SingleTimeObserver : public IObserver +{ + Function m_func; +public: + explicit SingleTimeObserver(Function func) : m_func{func} {} + ~SingleTimeObserver() = default; + + void onReadyChanged(std::shared_ptr connection) override { + m_func(); + QObject::disconnect(*connection); + } +}; + +// Standard observer which will work for each signal +template +class StandartObserver : public IObserver +{ + Function m_func; +public: + explicit StandartObserver(Function func) : m_func{func} {} + ~StandartObserver() = default; + + void onReadyChanged(std::shared_ptr ) override { + m_func(); + } +}; +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6dafed20..bb95e7f6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -76,6 +76,7 @@ add_test(NAME benchmarking-inprocess.cpp COMMAND test-driver.sh benchmarking/tst if(NOT ${FACELIFT_DISABLE_GTEST}) add_subdirectory(unittest) + add_subdirectory(unittest_observer) endif() add_subdirectory(objectregistry) diff --git a/tests/unittest_observer/CMakeLists.txt b/tests/unittest_observer/CMakeLists.txt new file mode 100644 index 00000000..1ee3263d --- /dev/null +++ b/tests/unittest_observer/CMakeLists.txt @@ -0,0 +1,23 @@ + +find_package(GTest) +if(${GTEST_FOUND}) + find_library(GMOCK_LIBRARY gmock REQUIRED HINTS "${CMAKE_SYSTEM_PREFIX_PATH}") + if(NOT ${GMOCK_LIBRARY} STREQUAL "GMOCK_LIBRARY-NOTFOUND") + add_library(GTest::GMock UNKNOWN IMPORTED) + set_target_properties(GTest::GMock PROPERTIES IMPORTED_LOCATION ${GMOCK_LIBRARY}) + else() + message(WARNING "Google test/mock not found.") + endif() + + find_package(Threads REQUIRED) + set(FACELIFT_GTEST_LIBRARIES ${GTEST_BOTH_LIBRARIES} GTest::GMock Threads::Threads) + include_directories(${GTEST_INCLUDE_DIRS}) + + facelift_add_test(UnitTestsObserver + SOURCES FaceliftObserverTest.cpp + LINK_LIBRARIES ${FACELIFT_GTEST_LIBRARIES} FaceliftIPCCommonLib) + +else() + message(WARNING "Required package google test not found!") +endif() + diff --git a/tests/unittest_observer/FaceliftObserverTest.cpp b/tests/unittest_observer/FaceliftObserverTest.cpp new file mode 100644 index 00000000..5d78b88f --- /dev/null +++ b/tests/unittest_observer/FaceliftObserverTest.cpp @@ -0,0 +1,43 @@ +#include +#include "IPCProxyBase.h" +#include "InterfaceBase.h" +#include + +using namespace facelift; + +class Counter +{ +public: + Counter() { m_value = 0; } + int value() const { return m_value; } + + void setValue1(){ + qDebug() << "Counter setValue1() "; + } + void setValue2(){ + qDebug() << "Counter setValue2() "; + } +private: + int m_value; +}; + +class IPCProxyBaseTest : public testing::Test +{ +public: + Counter c1; + Counter c2; + StandartObserver < std::function > * obs1 = new StandartObserver < std::function >(std::bind(&Counter::setValue1, &c1) ); + SingleTimeObserver< std::function > * obs2 = new SingleTimeObserver< std::function >(std::bind(&Counter::setValue2, &c2) ); + + IPCProxyBase proxyBase{nullptr}; +}; + +TEST_F(IPCProxyBaseTest, setObservers) +{ + const auto expected = std::vector{obs1, obs2,}; + proxyBase.m_readyObserver.setObservers(expected); + const auto actual = proxyBase.m_readyObserver.getObservers(); + EXPECT_EQ(expected.size(), actual.size()); + EXPECT_EQ(expected[0], actual[0]); + EXPECT_EQ(expected[1], actual[1]); +}