From 7aa7513660b79c8d2893e63715412d104d390340 Mon Sep 17 00:00:00 2001 From: Sung-Jin Park Date: Mon, 27 Jul 2020 20:57:58 +0900 Subject: [PATCH] DSClient: add basic implementation and tests Change-Id: I27fca5fcd93959353304506c68daee9810beb864 Signed-off-by: Sung-Jin Park --- src/DSClient/DSClient.cpp | 99 +++++++++++++++++++++++ src/DSClient/DSClient.h | 36 +++++++++ src/DSClient/DSClientPrivate.h | 30 +++++++ src/meson.build | 4 + tests/DSClient-test.cpp | 176 +++++++++++++++++++++++++++++++++++++++++ tests/meson.build | 3 +- 6 files changed, 347 insertions(+), 1 deletion(-) create mode 100644 src/DSClient/DSClient.cpp create mode 100644 src/DSClient/DSClient.h create mode 100644 src/DSClient/DSClientPrivate.h create mode 100644 tests/DSClient-test.cpp diff --git a/src/DSClient/DSClient.cpp b/src/DSClient/DSClient.cpp new file mode 100644 index 0000000..45b72ac --- /dev/null +++ b/src/DSClient/DSClient.cpp @@ -0,0 +1,99 @@ +#include "DSClient.h" +#include "DSClientPrivate.h" +#include "DSWaylandCompositor.h" +#include "DSWaylandClient.h" +#include "DSWindow.h" + +namespace display_server +{ + +/* Begin Private Class Implementation */ +DSClientPrivate::DSClientPrivate(DSClient *client, DSWaylandClient *dswlClient) + : DSObjectPrivate(client), + __p_ptr(client), + __dswlComp(nullptr), + __dswlClient(dswlClient), + __numWindows(0) +{ + __windows.clear(); +} + +DSClientPrivate::~DSClientPrivate() +{ + __windows.clear(); +} + +/* Begin Public Class Implementation */ +DSClient::DSClient(DSCompositor *compositor) + : _d_ptr(std::make_unique(this, nullptr)), + __compositor(compositor) +{ + +} +DSClient::DSClient(DSCompositor *compositor, DSWaylandClient *dswlClient) + : _d_ptr(std::make_unique(this, dswlClient)), + __compositor(compositor) +{ + +} + +DSClient::~DSClient() +{ +} + +void DSClient::addWindow(DSWindow *window) +{ + DS_GET_PRIV(DSClient); + + for (auto win : priv->__windows) + { + if (window == win) + { + DSLOG_ERR("DSClient", "Window(%p) exists already.", window); + return; + } + } + + priv->__windows.push_back(window); + return; +} + +bool DSClient::removeWindow(DSWindow *window) +{ + DS_GET_PRIV(DSClient); + + for (auto win : priv->__windows) + { + if (window == win) + { + priv->__windows.remove(window); + DSLOG_ERR("DSClient", "Window(%p) has been removed.", window); + return true; + } + } + + return false; +} + +std::list DSClient::getWindows() +{ + DS_GET_PRIV(DSClient); + + return priv->__windows; +} + +uint32_t DSClient::numWindows() +{ + DS_GET_PRIV(DSClient); + + return priv->__numWindows; +} + +bool DSClient::hasWindow() +{ + DS_GET_PRIV(DSClient); + + return priv->__numWindows ? true : false; +} + +} // namespace display_server diff --git a/src/DSClient/DSClient.h b/src/DSClient/DSClient.h new file mode 100644 index 0000000..9f851ce --- /dev/null +++ b/src/DSClient/DSClient.h @@ -0,0 +1,36 @@ +#ifndef __DS_SEAT_H__ +#define __DS_SEAT_H__ + +#include "DSCore.h" +#include "DSObject.h" + +namespace display_server +{ + +class DSClientPrivate; +class DSWaylandClient; +class DSCompositor; +class DSWindow; + +class DSClient : public DSObject +{ + DS_PIMPL_USE_PRIVATE(DSClient) +public: + DSClient() = delete; + DSClient(DSCompositor *compositor); + DSClient(DSCompositor *compositor, DSWaylandClient *dswlClient); + ~DSClient() override; + + void addWindow(DSWindow *window); + bool removeWindow(DSWindow *window); + std::list getWindows(); + uint32_t numWindows(); + bool hasWindow(); + +private: + DSCompositor *__compositor; +}; + +} + +#endif //__DS_SEAT_H__ \ No newline at end of file diff --git a/src/DSClient/DSClientPrivate.h b/src/DSClient/DSClientPrivate.h new file mode 100644 index 0000000..62ef3b8 --- /dev/null +++ b/src/DSClient/DSClientPrivate.h @@ -0,0 +1,30 @@ +#ifndef __DS_SEAT_PRIVATE_H__ +#define __DS_SEAT_PRIVATE_H__ + +#include "DSCore.h" +#include "DSObjectPrivate.h" + +namespace display_server +{ + +class DSClient; +class DSWaylandCompositor; + +class DSClientPrivate : public DSObjectPrivate +{ + DS_PIMPL_USE_PUBLIC(DSClient); +public: + DSClientPrivate() = delete; + DSClientPrivate(DSClient *client, DSWaylandClient *dswlClient); + ~DSClientPrivate() override; + +private: + DSWaylandCompositor *__dswlComp; + DSWaylandClient *__dswlClient; + std::list __windows;//use if one or more windows in a client + int __numWindows; +}; + +} + +#endif //__DS_SEAT_PRIVATE_H__ \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index 24bfcf4..4a06e85 100644 --- a/src/meson.build +++ b/src/meson.build @@ -53,6 +53,9 @@ libds_srcs = [ 'DSWindowShell/DSWindowShell.cpp', 'DSWindowShell/DSWindowShellPrivate.cpp', 'DSZone/DSZone.cpp', + 'DSClient/DSClientPrivate.h', + 'DSClient/DSClient.h', + 'DSClient/DSClient.cpp', ] libds_wayland_srcs = [ @@ -169,6 +172,7 @@ libds_include_dirs = include_directories( './DSWindow', './DSWindowShell', './DSZone', + './DSClient', ) libds_lib = shared_library( diff --git a/tests/DSClient-test.cpp b/tests/DSClient-test.cpp new file mode 100644 index 0000000..ba5db7d --- /dev/null +++ b/tests/DSClient-test.cpp @@ -0,0 +1,176 @@ +#include "libds-tests.h" +#include "DSObject.h" +#include "DSClient.h" +#include "DSCompositor.h" +#include "DSWaylandCompositor.h" +#include "DSWindow.h" +#include "DSWaylandClient.h" +#include + +using namespace display_server; + +class DSClientTest : public ::testing::Test +{ +public: + void SetUp(void) override + { + setenv("XDG_RUNTIME_DIR", "/run", 1); + } + void TearDown(void) override + { + unsetenv("XDG_RUNTIME_DIR"); + } +}; + +class MockCompositor : public DSCompositor +{ +public: + MockCompositor() {} + ~MockCompositor() {} + + std::shared_ptr _onInitialized() override + { + auto canvas = std::make_shared(); + return canvas; + } + + void _onOutputAdded(std::shared_ptr output) override + {} + + void _onOutputRemoved(std::shared_ptr output) override + {} + + void _onInputAdded(std::shared_ptr input) override + {} + + void _onInputRemoved(std::shared_ptr input) override + {} +}; + +TEST_F(DSClientTest, NewDSClientWithDSWaylandClient) +{ + DSCompositor *comp = new MockCompositor(); + EXPECT_TRUE(comp != nullptr); + + if (comp) + { + DSWaylandCompositor *dswlComp = DSWaylandCompositor::getInstance(); + EXPECT_TRUE(dswlComp != nullptr); + + if (dswlComp) + { + /* client must be created with a valid wl_client ptr later. */ + DSWaylandClient *dswlClient = new DSWaylandClient(dswlComp, (wl_client *)nullptr); + EXPECT_TRUE(dswlClient != nullptr); + + if (dswlClient) + { + DSClient *client = new DSClient(comp, dswlClient); + EXPECT_TRUE(client != nullptr); + + if (client) + delete client; + + delete dswlClient; + } + + DSWaylandCompositor::releaseInstance(); + } + + delete comp; + } +} + +TEST_F(DSClientTest, AddRemoveHasWindow) +{ + DSCompositor *comp = new MockCompositor(); + EXPECT_TRUE(comp != nullptr); + + if (comp) + { + DSWindow *win = new DSWindow(); + EXPECT_TRUE(win != nullptr); + + if (win) + { + DSClient *client = new DSClient(comp); + EXPECT_TRUE(client != nullptr); + + if (client) + { + client->addWindow(win); + EXPECT_TRUE(client->hasWindow() == true); + + client->removeWindow(win); + EXPECT_TRUE(client->hasWindow() != true); + + delete client; + } + + delete win; + } + + delete comp; + } +} + +TEST_F(DSClientTest, GetWindowsNumWindows) +{ + DSCompositor *comp = new MockCompositor(); + EXPECT_TRUE(comp != nullptr); + + if (comp) + { + DSWindow *win1 = new DSWindow(); + EXPECT_TRUE(win1 != nullptr); + + DSWindow *win2 = new DSWindow(); + EXPECT_TRUE(win2 != nullptr); + + DSWindow *win3 = new DSWindow(); + EXPECT_TRUE(win3 != nullptr); + + if (win1 && win2 && win3) + { + DSClient *client = new DSClient(comp); + EXPECT_TRUE(client != nullptr); + + if (client) + { + client->addWindow(win1); + EXPECT_TRUE(client->numWindows() == 1); + client->addWindow(win2); + EXPECT_TRUE(client->numWindows() == 2); + client->addWindow(win3); + EXPECT_TRUE(client->numWindows() == 3); + + int cnt = 3; + std::list winList = client->getWindows(); + for (auto win : winList) + { + if (win == win1 || + win == win2 || + win == win3) + cnt--; + } + + EXPECT_TRUE(cnt == 0); + + client->removeWindow(win1); + EXPECT_TRUE(client->numWindows() == 2); + client->removeWindow(win2); + EXPECT_TRUE(client->numWindows() == 1); + client->removeWindow(win3); + EXPECT_TRUE(client->numWindows() == 0); + + delete client; + } + + delete win1; + delete win2; + delete win3; + } + + delete comp; + } +} diff --git a/tests/meson.build b/tests/meson.build index 22ac7a0..4a741c1 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -35,7 +35,8 @@ libds_tests_srcs = [ 'DSWaylandPointer-test.cpp', 'DSWaylandKeyboard-test.cpp', 'DSWaylandTouch-test.cpp', - 'DSZone-test.cpp' + 'DSZone-test.cpp', + 'DSClient-test.cpp' ] gmock_dep = dependency('gmock', method : 'pkg-config') -- 2.7.4