From: Junseok, Kim Date: Fri, 28 Aug 2020 11:06:06 +0000 (+0900) Subject: DSSignalBroker: added registerSignal and add DSObject argument for signal methods X-Git-Tag: accepted/tizen/unified/20200902.145526~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dfa70234dfe173becde2db56d89df922ab7b5458;p=platform%2Fcore%2Fuifw%2Flibds.git DSSignalBroker: added registerSignal and add DSObject argument for signal methods Change-Id: I2b97b60b195740b134a2cdd1d7fbcaa082679c9b Signed-off-by: Junseok, Kim --- diff --git a/src/DSSignal/DSSignalBroker.cpp b/src/DSSignal/DSSignalBroker.cpp index f8e4cfa..58c53c2 100644 --- a/src/DSSignal/DSSignalBroker.cpp +++ b/src/DSSignal/DSSignalBroker.cpp @@ -41,7 +41,7 @@ DSSignalBroker::~DSSignalBroker() { for (auto hashpairs : __signalBroker->__signalHash) { - delete hashpairs.second; + delete hashpairs.second.signal; } } } diff --git a/src/DSSignal/DSSignalBroker.h b/src/DSSignal/DSSignalBroker.h index 27a55dd..5674ade 100644 --- a/src/DSSignal/DSSignalBroker.h +++ b/src/DSSignal/DSSignalBroker.h @@ -37,19 +37,38 @@ public: static DSSignalBroker *getInstance(); static void releaseInstance(); - // TODO: needs arguments using signal (now only supports void*) + template + bool registerSignal(std::string signalStr, DSObject *obj); + template + bool emitSignal(std::string signalStr, DSObject *obj, Args...); template bool registerCallback(std::string signalStr, DSObject *slot, std::function func); template bool deregisterCallback(std::string signalStr, DSObject *slot, std::function func); - template - bool emitSignal(std::string signalStr, Args...); private: static std::mutex __mutex; static DSSignalBroker *__signalBroker; - std::unordered_map *> __signalHash; + struct stRegisteredSignal + { + std::string signalName; + std::string className; + DSObject *obj; + DSSignal *signal; + + public: + stRegisteredSignal(std::string sn, DSObject *inpObj, DSSignal *inpSignal) + { + signalName = sn; + className = inpObj->getName(); + obj = inpObj; + signal = inpSignal; + } + + }; + + std::unordered_multimap __signalHash; DSSignalBroker() = delete; ~DSSignalBroker(); @@ -57,56 +76,121 @@ private: }; template -bool DSSignalBroker::registerCallback(std::string signalStr, DSObject *slot, std::function func) +bool DSSignalBroker::registerSignal(std::string signalStr, DSObject *obj) { if (!__signalBroker) return false; - if (__signalBroker->__signalHash.find(signalStr) == __signalBroker->__signalHash.end()) + if (__signalBroker->__signalHash.find(signalStr) != __signalBroker->__signalHash.end()) { - DSLOG_INF("DSSignalBroker","registerCallback:: cannot find signal, add new one %s", signalStr.c_str()); - - __signalBroker->__signalHash[signalStr] = reinterpret_cast *> (new DSSignal()); + auto range = __signalBroker->__signalHash.equal_range(signalStr); + for (auto iter = range.first; + iter != range.second; + iter++) + { + if (iter->second.obj == obj) + { + DSLOG_INF("DSSignalBroker","emitSignal:: already registered signal: %s", signalStr.c_str()); + return false; + } + else + { + DSLOG_DBG("DSSignalBroker", "searching same item: %s, obj(%p):%s", iter->second.signalName.c_str(), iter->second.obj, iter->second.className.c_str()); + } + + } } + DSSignal *signal = reinterpret_cast *> (new DSSignal()); + __signalBroker->__signalHash.insert(std::make_pair(signalStr, stRegisteredSignal(signalStr, obj, signal))); - DSSignal *signal = reinterpret_cast *>(__signalBroker->__signalHash[signalStr]); - if (signal) - signal->connect(slot, func); + DSLOG_DBG("DSSignalBroker","registerSignal:: registered new signal (name:%s, class(%p):%s, signal:%p)", + signalStr.c_str(), obj, obj->getName().c_str(), signal); return true; } template -bool DSSignalBroker::deregisterCallback(std::string signalStr, DSObject *slot, std::function func) +bool DSSignalBroker::emitSignal(std::string signalStr, DSObject *obj, Args... args) { if (!__signalBroker) return false; - if (__signalBroker->__signalHash.find(signalStr) == __signalBroker->__signalHash.end()) + if (__signalBroker->__signalHash.find(signalStr) != __signalBroker->__signalHash.end()) + { + auto range = __signalBroker->__signalHash.equal_range(signalStr); + for (auto iter = range.first; + iter != range.second; + iter++) + { + if (iter->second.obj == obj)// || iter->second.className == obj->getName()) + { + DSSignal *signal = reinterpret_cast *>(iter->second.signal); + if (signal) + { + signal->emit(args...); + DSLOG_DBG("DSSignalBroker","emitSignal:: signal emit (name:%s, class(%p):%s, signal:%p)", + iter->second.signalName.c_str(), iter->second.obj, iter->second.obj->getName().c_str(), iter->second.signal); + } + else + return false; + + return true; + } + } + } + else + { + DSLOG_INF("DSSignalBroker","emitSignal:: cannot find registered signal: %s", signalStr.c_str()); return false; + } - // TODO: have to impl disconnect method in DSSignal - //DSSignal *signal = reinterpret_cast *>(__signalBroker->__signalHash[signalStr]); - //if (signal) - //signal->disconnect(slot, func); - - return true; + return false; } template -bool DSSignalBroker::emitSignal(std::string signalStr, Args... args) +bool DSSignalBroker::registerCallback(std::string signalStr, DSObject *slot, std::function func) { if (!__signalBroker) return false; - if (__signalBroker->__signalHash.find(signalStr) == __signalBroker->__signalHash.end()) + if (__signalBroker->__signalHash.find(signalStr) != __signalBroker->__signalHash.end()) + { + auto range = __signalBroker->__signalHash.equal_range(signalStr); + for (auto iter = range.first; + iter != range.second; + iter++) { - DSLOG_INF("DSSignalBroker","emitSignal:: cannot find signal, add new one %s", signalStr.c_str()); - - __signalBroker->__signalHash[signalStr] = reinterpret_cast *> (new DSSignal()); + DSSignal *signal = reinterpret_cast *>(iter->second.signal); + if (signal) + signal->connect(slot, func); } + } + else + { + DSLOG_INF("DSSignalBroker","registerCallback:: cannot find signal: %s", signalStr.c_str()); + return false; + } + + return true; +} - DSSignal *signal = reinterpret_cast *>(__signalBroker->__signalHash[signalStr]); - if (signal) - signal->emit(args...); +template +bool DSSignalBroker::deregisterCallback(std::string signalStr, DSObject *slot, std::function func) +{ + // TODO: have to impl disconnect method in DSSignal + /* + if (!__signalBroker) return false; + if (__signalBroker->__signalHash.find(signalStr) != __signalBroker->__signalHash.end()) + { + auto range = __signalBroker->__signalHash.equal_range(signalStr); + for (auto iter = range.first; + iter != range.second; + iter++) + { + DSSignal *signal = reinterpret_cast *>(iter->second.signal); + if (signal) + signal->disconnect(slot, func); + } + } + */ return true; } diff --git a/tests/DSSignalBroker-test.cpp b/tests/DSSignalBroker-test.cpp index a4532b9..4484885 100644 --- a/tests/DSSignalBroker-test.cpp +++ b/tests/DSSignalBroker-test.cpp @@ -29,22 +29,19 @@ using namespace display_server; -class DSSignalBrokerTest : public ::testing::Test +struct stItem { -public: - void SetUp(void) override - {} - void TearDown(void) override - {} + std::string str1; + std::string str2; }; -class MockSignalBrokerSender : public DSObject +class MockSender : public DSObject { public: - MockSignalBrokerSender() {} - ~MockSignalBrokerSender() {} + MockSender() {} + ~MockSender() {} - bool sendSignal(std::string signalString) + bool registerSignal(std::string signalString) { DSSignalBroker *sigbro = DSSignalBroker::getInstance(); bool res = false; @@ -52,7 +49,57 @@ public: if (sigbro == nullptr) return false; - res = sigbro->emitSignal(signalString, true); + res = sigbro->registerSignal(signalString, this); + + if (sigbro) + sigbro->releaseInstance(); + + return res; + } + + bool sendSignal1(std::string signalString, int data) + { + DSSignalBroker *sigbro = DSSignalBroker::getInstance(); + bool res = false; + + if (sigbro == nullptr) + return false; + + res = sigbro->emitSignal(signalString, this, data); + + if (sigbro) + sigbro->releaseInstance(); + + return res; + } + + bool sendSignal2(std::string signalString, double data) + { + DSSignalBroker *sigbro = DSSignalBroker::getInstance(); + bool res = false; + + if (sigbro == nullptr) + return false; + + res = sigbro->emitSignal(signalString, this, data); + + if (sigbro) + sigbro->releaseInstance(); + + return res; + } + + bool sendSignal3(std::string signalString, std::string data1, std::string data2, std::string data3) + { + DSSignalBroker *sigbro = DSSignalBroker::getInstance(); + bool res = false; + + if (sigbro == nullptr) + return false; + + struct stItem testItem = {data2, data3}; + + res = sigbro->emitSignal(signalString, this, data1, testItem); if (sigbro) sigbro->releaseInstance(); @@ -61,29 +108,46 @@ public: } }; -class MockSignalBrokerReceiver : public DSObject +class MockReceiver : public DSObject { public: - MockSignalBrokerReceiver() = delete; - MockSignalBrokerReceiver(std::string targetSignal) + MockReceiver() : + result1(0), + result2(0.0), + result3("") { - __targetSignal = targetSignal; } - ~MockSignalBrokerReceiver() {} + ~MockReceiver() {} public: - std::string __targetSignal; - bool __result; + int result1; + double result2; + std::string result3; public: - bool registerCallback() + bool registerCallback1(std::string targetSignal) + { + bool res = false; + DSSignalBroker *sigbro = DSSignalBroker::getInstance(); + if (sigbro == nullptr) return false; + + std::function func = std::bind(&MockReceiver::UserCallback1, this, std::placeholders::_1); + res = sigbro->registerCallback(targetSignal, this, func); + + if (sigbro) + sigbro->releaseInstance(); + + return res; + } + + bool registerCallback2(std::string targetSignal) { bool res = false; DSSignalBroker *sigbro = DSSignalBroker::getInstance(); if (sigbro == nullptr) return false; - std::function func = std::bind(&MockSignalBrokerReceiver::callbackTestSignalBroker, this, std::placeholders::_1); - res = sigbro->registerCallback(__targetSignal, this, func); + std::function func = std::bind(&MockReceiver::UserCallback2, this, std::placeholders::_1); + res = sigbro->registerCallback(targetSignal, this, func); if (sigbro) sigbro->releaseInstance(); @@ -91,18 +155,52 @@ public: return res; } - void callbackTestSignalBroker(bool arg) + bool registerCallback3(std::string targetSignal) + { + bool res = false; + DSSignalBroker *sigbro = DSSignalBroker::getInstance(); + if (sigbro == nullptr) return false; + + std::function func = std::bind(&MockReceiver::UserCallback3, this, std::placeholders::_1, std::placeholders::_2); + res = sigbro->registerCallback(targetSignal, this, func); + + if (sigbro) + sigbro->releaseInstance(); + + return res; + } + + void UserCallback1(int arg) { DSLOG_INF("DSTEST", "%s is invoked!, arg: %d", __func__, arg); - __result = arg; + result1 = arg; } - bool getResult() + void UserCallback2(double arg) { - return __result; + DSLOG_INF("DSTEST", "%s is invoked!, arg: %d", __func__, arg); + result2 = arg; + } + + void UserCallback3(std::string arg1, struct stItem arg2) + { + DSLOG_INF("DSTEST", "%s is invoked!, arg1: %s, arg2{%s, %s}", __func__, arg1.c_str(), arg2.str1.c_str(), arg2.str2.c_str()); + result3 = arg1; } }; +class DSSignalBrokerTest : public ::testing::Test +{ +public: + void SetUp(void) override + {} + void TearDown(void) override + {} +}; + +std::shared_ptr __receiver; +std::shared_ptr __sender; + TEST_F(DSSignalBrokerTest, getInstance) { DSSignalBroker *sigbro = DSSignalBroker::getInstance(); @@ -112,39 +210,78 @@ TEST_F(DSSignalBrokerTest, getInstance) sigbro->releaseInstance(); } +TEST_F(DSSignalBrokerTest, registerSignal) +{ + __sender = std::make_shared(); + ASSERT_TRUE(__sender != nullptr); + + __sender->registerSignal("SampleSignal1"); +} + TEST_F(DSSignalBrokerTest, registerCallback) { - auto receiver = std::make_shared("TestSignalBroker"); - receiver->registerCallback(); + __receiver = std::make_shared(); + ASSERT_TRUE(__receiver != nullptr); + + __receiver->registerCallback1("SampleSignal1"); } TEST_F(DSSignalBrokerTest, emitSignal) { - auto receiver = std::make_shared("TestSignalBroker"); - auto sender = std::make_shared(); - ASSERT_TRUE(receiver != nullptr); - ASSERT_TRUE(sender != nullptr); - - receiver->registerCallback(); - EXPECT_TRUE(sender->sendSignal("TestSignalBroker")); - EXPECT_TRUE(receiver->getResult()); + ASSERT_TRUE(__sender != nullptr); + ASSERT_TRUE(__receiver != nullptr); + + EXPECT_TRUE(__sender->sendSignal1("SampleSignal1", 1)); + EXPECT_TRUE(__receiver->result1 == 1); } -TEST_F(DSSignalBrokerTest, emitSignal2) +TEST_F(DSSignalBrokerTest, registerAndEmit1) { - auto receiver1 = std::make_shared("TestSignalBroker"); - auto receiver2 = std::make_shared("TestSignalBroker2"); - auto sender = std::make_shared(); - ASSERT_TRUE(receiver1 != nullptr); - ASSERT_TRUE(receiver2 != nullptr); - ASSERT_TRUE(sender != nullptr); - - receiver1->registerCallback(); - receiver2->registerCallback(); - EXPECT_TRUE(sender->sendSignal("TestSignalBroker")); - EXPECT_TRUE(receiver1->getResult()); - EXPECT_TRUE(receiver2->getResult() != true); - - EXPECT_TRUE(sender->sendSignal("TestSignalBroker2")); - EXPECT_TRUE(receiver2->getResult()); + auto sender1 = std::make_shared(); + auto sender2 = std::make_shared(); + + auto receiver1 = std::make_shared(); + auto receiver2 = std::make_shared(); + + ASSERT_TRUE(sender1 != nullptr && + sender2 != nullptr && + receiver1 != nullptr && + receiver2 != nullptr); + + // 1. register Signal + EXPECT_TRUE(sender1->registerSignal("SampleSignal1")); + EXPECT_TRUE(sender2->registerSignal("SampleSignal2")); + + // 2. register Callback + EXPECT_TRUE(receiver1->registerCallback1("SampleSignal1")); + EXPECT_TRUE(receiver2->registerCallback2("SampleSignal2")); + + // 3. emit Signal + EXPECT_TRUE(sender1->sendSignal1("SampleSignal1", 11)); + EXPECT_TRUE(sender2->sendSignal2("SampleSignal2", 10.10)); + + // 4. see Changes + EXPECT_TRUE(receiver1->result1 == 11); + EXPECT_TRUE(receiver2->result2 == 10.10); } + +TEST_F(DSSignalBrokerTest, emitMultiItems) +{ + auto sender = std::make_shared(); + auto receiver = std::make_shared(); + + ASSERT_TRUE(sender != nullptr && + receiver != nullptr); + + // 1. register Signal + EXPECT_TRUE(sender->registerSignal("SampleSignal3")); + + // 2. register Callback + EXPECT_TRUE(receiver->registerCallback3("SampleSignal3")); + + // 3. emit Signal + EXPECT_TRUE(sender->sendSignal3("SampleSignal3", "Test", "Hello", "signal")); + + // 4. see Changes + EXPECT_TRUE(receiver->result3 == "Test"); +} \ No newline at end of file