static DSSignalBroker *getInstance();
static void releaseInstance();
- // TODO: needs arguments using signal (now only supports void*)
+ template <typename... Args>
+ bool registerSignal(std::string signalStr, DSObject *obj);
+ template <typename... Args>
+ bool emitSignal(std::string signalStr, DSObject *obj, Args...);
template <typename... Args>
bool registerCallback(std::string signalStr, DSObject *slot, std::function<void(Args...)> func);
template <typename... Args>
bool deregisterCallback(std::string signalStr, DSObject *slot, std::function<void(Args...)> func);
- template <typename... Args>
- bool emitSignal(std::string signalStr, Args...);
private:
static std::mutex __mutex;
static DSSignalBroker *__signalBroker;
- std::unordered_map<std::string, DSSignal<void *> *> __signalHash;
+ struct stRegisteredSignal
+ {
+ std::string signalName;
+ std::string className;
+ DSObject *obj;
+ DSSignal<void *> *signal;
+
+ public:
+ stRegisteredSignal(std::string sn, DSObject *inpObj, DSSignal<void *> *inpSignal)
+ {
+ signalName = sn;
+ className = inpObj->getName();
+ obj = inpObj;
+ signal = inpSignal;
+ }
+
+ };
+
+ std::unordered_multimap<std::string, stRegisteredSignal> __signalHash;
DSSignalBroker() = delete;
~DSSignalBroker();
};
template <typename... Args>
-bool DSSignalBroker::registerCallback(std::string signalStr, DSObject *slot, std::function<void(Args...)> 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<DSSignal<void *> *> (new DSSignal<Args...>());
+ 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<void *> *signal = reinterpret_cast<DSSignal<void *> *> (new DSSignal<Args...>());
+ __signalBroker->__signalHash.insert(std::make_pair(signalStr, stRegisteredSignal(signalStr, obj, signal)));
- DSSignal<Args...> *signal = reinterpret_cast<DSSignal<Args...> *>(__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 <typename... Args>
-bool DSSignalBroker::deregisterCallback(std::string signalStr, DSObject *slot, std::function<void(Args...)> 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<Args...> *signal = reinterpret_cast<DSSignal<Args...> *>(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<Args...> *signal = reinterpret_cast<DSSignal<Args...> *>(__signalBroker->__signalHash[signalStr]);
- //if (signal)
- //signal->disconnect(slot, func);
-
- return true;
+ return false;
}
template <typename... Args>
-bool DSSignalBroker::emitSignal(std::string signalStr, Args... args)
+bool DSSignalBroker::registerCallback(std::string signalStr, DSObject *slot, std::function<void(Args...)> 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<DSSignal<void *> *> (new DSSignal<Args...>());
+ DSSignal<Args...> *signal = reinterpret_cast<DSSignal<Args...> *>(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<Args...> *signal = reinterpret_cast<DSSignal<Args...> *>(__signalBroker->__signalHash[signalStr]);
- if (signal)
- signal->emit(args...);
+template <typename... Args>
+bool DSSignalBroker::deregisterCallback(std::string signalStr, DSObject *slot, std::function<void(Args...)> 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<Args...> *signal = reinterpret_cast<DSSignal<Args...> *>(iter->second.signal);
+ if (signal)
+ signal->disconnect(slot, func);
+ }
+ }
+ */
return true;
}
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;
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();
}
};
-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<void(int)> 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<void(bool)> func = std::bind(&MockSignalBrokerReceiver::callbackTestSignalBroker, this, std::placeholders::_1);
- res = sigbro->registerCallback(__targetSignal, this, func);
+ std::function<void(double)> func = std::bind(&MockReceiver::UserCallback2, this, std::placeholders::_1);
+ res = sigbro->registerCallback(targetSignal, this, func);
if (sigbro)
sigbro->releaseInstance();
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<void(std::string, struct stItem)> 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<MockReceiver> __receiver;
+std::shared_ptr<MockSender> __sender;
+
TEST_F(DSSignalBrokerTest, getInstance)
{
DSSignalBroker *sigbro = DSSignalBroker::getInstance();
sigbro->releaseInstance();
}
+TEST_F(DSSignalBrokerTest, registerSignal)
+{
+ __sender = std::make_shared<MockSender>();
+ ASSERT_TRUE(__sender != nullptr);
+
+ __sender->registerSignal("SampleSignal1");
+}
+
TEST_F(DSSignalBrokerTest, registerCallback)
{
- auto receiver = std::make_shared<MockSignalBrokerReceiver>("TestSignalBroker");
- receiver->registerCallback();
+ __receiver = std::make_shared<MockReceiver>();
+ ASSERT_TRUE(__receiver != nullptr);
+
+ __receiver->registerCallback1("SampleSignal1");
}
TEST_F(DSSignalBrokerTest, emitSignal)
{
- auto receiver = std::make_shared<MockSignalBrokerReceiver>("TestSignalBroker");
- auto sender = std::make_shared<MockSignalBrokerSender>();
- 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<MockSignalBrokerReceiver>("TestSignalBroker");
- auto receiver2 = std::make_shared<MockSignalBrokerReceiver>("TestSignalBroker2");
- auto sender = std::make_shared<MockSignalBrokerSender>();
- 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<MockSender>();
+ auto sender2 = std::make_shared<MockSender>();
+
+ auto receiver1 = std::make_shared<MockReceiver>();
+ auto receiver2 = std::make_shared<MockReceiver>();
+
+ 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<MockSender>();
+ auto receiver = std::make_shared<MockReceiver>();
+
+ 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