2022-12-07 08:51:01 +00:00
|
|
|
// HARFANG(R) Copyright (C) 2022 NWNC. Released under GPL/LGPL/Commercial Licence, see licence.txt for details.
|
|
|
|
|
|
|
|
#define TEST_NO_MAIN
|
|
|
|
#include "acutest.h"
|
|
|
|
|
|
|
|
#include "foundation/signal.h"
|
2021-10-13 12:40:31 +00:00
|
|
|
|
|
|
|
#include "foundation/format.h"
|
|
|
|
#include "foundation/log.h"
|
|
|
|
#include "foundation/string.h"
|
|
|
|
|
|
|
|
using namespace hg;
|
|
|
|
|
|
|
|
template <typename T> struct ListenerObject {
|
|
|
|
ListenerObject(int _id) : id(_id) {}
|
|
|
|
void OnSignal(T t) { log(format("Instance #%1 received signal: %2").arg(id).arg(t)); }
|
|
|
|
int id;
|
|
|
|
};
|
|
|
|
|
2022-12-07 08:51:01 +00:00
|
|
|
static void test_SignalToInstance() {
|
2021-10-13 12:40:31 +00:00
|
|
|
Signal<void(std::string)> signal;
|
|
|
|
|
|
|
|
ListenerObject<std::string> listener_a(0), listener_b(1);
|
|
|
|
|
|
|
|
auto a = signal.Connect(std::bind(&ListenerObject<std::string>::OnSignal, &listener_a, std::placeholders::_1));
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 1);
|
2021-10-13 12:40:31 +00:00
|
|
|
auto b = signal.Connect(std::bind(&ListenerObject<std::string>::OnSignal, &listener_b, std::placeholders::_1));
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 2);
|
2021-10-13 12:40:31 +00:00
|
|
|
|
|
|
|
signal.Emit("Hello signal!");
|
|
|
|
|
|
|
|
signal.Disconnect(a);
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 1);
|
2021-10-13 12:40:31 +00:00
|
|
|
signal.Disconnect(b);
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 0);
|
2021-10-13 12:40:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
template <typename T> void StaticListener(T t) { log(format("Static listener received signal: %1").arg(t)); }
|
|
|
|
|
2022-12-07 08:51:01 +00:00
|
|
|
static void test_SignalToFunction() {
|
2021-10-13 12:40:31 +00:00
|
|
|
Signal<void(std::string)> signal;
|
|
|
|
|
|
|
|
auto id = signal.Connect(&StaticListener<std::string>);
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 1);
|
2021-10-13 12:40:31 +00:00
|
|
|
|
|
|
|
signal.Emit("Hello signal!");
|
|
|
|
|
|
|
|
signal.Disconnect(id);
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 0);
|
2021-10-13 12:40:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
struct CostlyCopy {
|
|
|
|
std::string s[8];
|
|
|
|
};
|
|
|
|
|
2022-12-07 08:51:01 +00:00
|
|
|
static void RefListener(const CostlyCopy &s) {
|
2021-10-13 12:40:31 +00:00
|
|
|
log("Reference listener received a signal:");
|
|
|
|
for (int n = 0; n < 8; ++n)
|
|
|
|
log(format("[%1]: %2").arg(n).arg(s.s[n]));
|
|
|
|
}
|
|
|
|
|
2022-12-07 08:51:01 +00:00
|
|
|
static void test_SignalByRef() {
|
2021-10-13 12:40:31 +00:00
|
|
|
Signal<void(const CostlyCopy &)> signal;
|
|
|
|
|
|
|
|
auto id = signal.Connect(&RefListener);
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 1);
|
2021-10-13 12:40:31 +00:00
|
|
|
|
|
|
|
CostlyCopy hs;
|
|
|
|
for (int n = 0; n < 8; ++n)
|
|
|
|
hs.s[n] = std::string("This is the string #") + std::to_string(n);
|
|
|
|
|
|
|
|
signal.Emit(hs);
|
|
|
|
|
|
|
|
signal.Disconnect(id);
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 0);
|
2021-10-13 12:40:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
struct VoidListenerObject {
|
|
|
|
VoidListenerObject(int _id) : id(_id) {}
|
|
|
|
void OnSignal() { log(format("Instance #%1 received void signal").arg(id)); }
|
|
|
|
int id;
|
|
|
|
};
|
|
|
|
|
2022-12-07 08:51:01 +00:00
|
|
|
static void test_VoidSignalToInstance() {
|
2021-10-13 12:40:31 +00:00
|
|
|
Signal<void()> signal;
|
|
|
|
|
|
|
|
VoidListenerObject listener_a(0), listener_b(1);
|
|
|
|
|
|
|
|
auto a = signal.Connect(std::bind(&VoidListenerObject::OnSignal, &listener_a));
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 1);
|
2021-10-13 12:40:31 +00:00
|
|
|
auto b = signal.Connect(std::bind(&VoidListenerObject::OnSignal, &listener_b));
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 2);
|
2021-10-13 12:40:31 +00:00
|
|
|
|
|
|
|
signal.Emit();
|
|
|
|
|
|
|
|
signal.Disconnect(a);
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 1);
|
2021-10-13 12:40:31 +00:00
|
|
|
signal.Disconnect(b);
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 0);
|
2021-10-13 12:40:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2022-12-07 08:51:01 +00:00
|
|
|
static void StaticVoidListener() { log("Void listener received signal"); }
|
2021-10-13 12:40:31 +00:00
|
|
|
|
2022-12-07 08:51:01 +00:00
|
|
|
static void test_VoidSignalToFunction() {
|
2021-10-13 12:40:31 +00:00
|
|
|
Signal<void()> signal;
|
|
|
|
|
|
|
|
auto id = signal.Connect(&StaticVoidListener);
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 1);
|
2021-10-13 12:40:31 +00:00
|
|
|
|
|
|
|
signal.Emit();
|
|
|
|
|
|
|
|
signal.Disconnect(id);
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 0);
|
2021-10-13 12:40:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
struct BaseListenerObject {
|
|
|
|
virtual ~BaseListenerObject() {}
|
|
|
|
virtual void OnSignal() = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct InheritedListenerObject : public BaseListenerObject {
|
|
|
|
InheritedListenerObject() : received(false) {}
|
|
|
|
|
|
|
|
void OnSignal() override {
|
|
|
|
log("Virtual member received void signal");
|
|
|
|
received = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool received;
|
|
|
|
};
|
|
|
|
|
2022-12-07 08:51:01 +00:00
|
|
|
static void test_SignalThroughInstanceVirtualMember() {
|
2021-10-13 12:40:31 +00:00
|
|
|
Signal<void()> signal;
|
|
|
|
|
|
|
|
std::unique_ptr<BaseListenerObject> listener(new InheritedListenerObject);
|
|
|
|
|
|
|
|
auto id = signal.Connect(std::bind(&BaseListenerObject::OnSignal, listener.get()));
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 1);
|
2021-10-13 12:40:31 +00:00
|
|
|
|
|
|
|
signal.Emit();
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(static_cast<InheritedListenerObject *>(listener.get())->received);
|
2021-10-13 12:40:31 +00:00
|
|
|
|
|
|
|
signal.Disconnect(id);
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal.GetListenerCount() == 0);
|
2021-10-13 12:40:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2022-12-07 08:51:01 +00:00
|
|
|
static void test_VoidSignalController() {
|
2021-10-13 12:40:31 +00:00
|
|
|
Signal<void()> signal;
|
|
|
|
|
|
|
|
bool signal_called = false;
|
|
|
|
signal.Connect([&signal_called]() { signal_called = true; });
|
|
|
|
|
|
|
|
bool controller_called = false;
|
|
|
|
signal.Emit([&controller_called]() { controller_called = true; });
|
|
|
|
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal_called);
|
|
|
|
TEST_CHECK(controller_called);
|
2021-10-13 12:40:31 +00:00
|
|
|
}
|
|
|
|
|
2022-12-07 08:51:01 +00:00
|
|
|
static void test_SignalController() {
|
2021-10-13 12:40:31 +00:00
|
|
|
Signal<int()> signal;
|
|
|
|
|
|
|
|
bool signal_called = false;
|
|
|
|
signal.Connect([&signal_called]() -> int {
|
|
|
|
signal_called = true;
|
|
|
|
return 66;
|
|
|
|
});
|
|
|
|
|
|
|
|
int controller_result = 0;
|
|
|
|
signal.Emit([&controller_result](int v) { controller_result = v; });
|
|
|
|
|
2022-12-07 08:51:01 +00:00
|
|
|
TEST_CHECK(signal_called);
|
|
|
|
TEST_CHECK(controller_result == 66);
|
2021-10-13 12:40:31 +00:00
|
|
|
}
|
2022-12-07 08:51:01 +00:00
|
|
|
|
|
|
|
void test_signal() {
|
|
|
|
test_SignalToInstance();
|
|
|
|
test_SignalToFunction();
|
|
|
|
test_SignalByRef();
|
|
|
|
test_VoidSignalToInstance();
|
|
|
|
test_VoidSignalToFunction();
|
|
|
|
test_SignalThroughInstanceVirtualMember();
|
|
|
|
test_VoidSignalController();
|
|
|
|
test_SignalController();
|
|
|
|
}
|