ktsignal
Небольшая библиотека сигналов для C++. Для компиляции потребуется C++17 (на MSVC можно скомпилировать на C++14)Немного примеров кода
Базовое использование:
Пример ниже показывает базовое использование сигналов
C++:
void on_click(int value) { }
class A {
public:
void on_class_click(int value) { }
};
int main() {
// Сигнал с сигнатурой функции в шаблонном параметре
ktsignal::ktsignal<void(int)> click{};
// Подключение обычной функции
click.connect(on_click);
// Подключение member function
A object;
click.connect(&object, &A::on_class_click);
// Подключение лямбда функции
click.connect([](int){ });
// Вызов коллбэков
click.emit(1);
}
C++:
void on_click(int value) { }
class A {
public:
void on_class_click(int value) { }
};
int main() {
ktsignal::ktsignal<void(int)> click{};
{
auto connection = click.scoped_connect(on_click);
A object;
auto method_connection = click.scoped_connect(&object, &A::on_class_click);
click.scoped_connect([](int v){ std::cout << "This will never be printed" << std::endl; });
// on_click and on_class_click are called
click.emit(1);
}
// nothing is called
click.emit(1);
}
Подключение / Отключение коллбэков
C++:
auto connection = click.connect(on_click);
// Подключение лямбда функции
click.connect([](int){ });
// Вызов сигнала (on_click и lambda будут вызваны)
click.emit(1);
// Отключение on_click коллбэка от сигнала
connection.disconnect();
// Только лямбда будет вызвана
click.emit(1);
Несколько важных замечаний об объекте
ktsignal_connection
ktsignal_connection
можно создавать по умолчанию, перемещать, но не копировать.- Вы должны убедиться, что соединение не будет использоваться после уничтожения сигнала.
Итерация через слоты сигнала
Вы можете итерироваться по сигналу через range-based for при этом получая значение возврата
C++:
int on_click(int value) { return 5; }
int on_click_second(int value) { return 1; }
int main() {
ktsignal::ktsignal<int(int)> click{};
click.connect(on_click);
click.connect(on_click_second);
// Будет выведено `emit_iterate returned 5 emit_iterate returned 1`
for (auto returned : signal.emit_iterate(1)) {
std::cout << "emit_iterate returned " << returned << " ";
}
}
Также вы легко можете использовать функции из стандартной библиотеки C++
C++:
int on_click(int value) { return 5; }
int on_click_second(int value) { return 1; }
int main() {
ktsignal::ktsignal<int(int)> click{};
click.connect(on_click);
click.connect(on_click_second);
auto iterate = signal.emit_iterate(0);
auto accumulated = std::accumulate(iterate.begin(), iterate.end(), 0);
// Will display 6
std::cout << "Accumulated: " << accumulated << std::endl;
}
Использование ktsignal в многопоточном коде
Для многопоточного кода вы должны использоватьktsignal_threadsafe
C++:
void func_thread(int v) {
std::cout << "before sleep" << std::endl;
std::this_thread::sleep_for(1000ms);
std::cout << "after sleep" << std::endl;
return 2;
}
int main() {
ktsignal::ktsignal_threadsafe<int(int)> signal{};
signal.connect(func_thread);
// Создание потока который сразу же вызовет emit
std::thread([&signal]() {
// Создание потока который вызовет emit спустя 100мс
std::thread(
[&signal]() {
std::this_thread::sleep_for(100ms);
signal.emit(1);
}
).detach();
signal.emit(2);
}).join();
std::this_thread::sleep_for(1.5s);
}
Код:
Вывод:
[func_thread] - before sleep
[func_thread] - before sleep
[func_thread] - after sleep
[func_thread] - after sleep
C++:
void func_thread(int v) {
std::cout << "before sleep" << std::endl;
std::this_thread::sleep_for(1000ms);
std::cout << "after sleep" << std::endl;
return 2;
}
int main() {
ktsignal::ktsignal_threadsafe_emit<int(int)> signal{};
signal.connect(func_thread);
// Создание потока который сразу же вызовет emit
std::thread([&signal]() {
// Создание потока который вызовет emit спустя 100мс
std::thread(
[&signal]() {
std::this_thread::sleep_for(100ms);
signal.emit(1);
}
).detach();
signal.emit(2);
}).join();
std::this_thread::sleep_for(1.5s);
}
Код:
Вывод:
[func_thread] - before sleep
[func_thread] - after sleep
[func_thread] - before sleep
[func_thread] - after sleep
Download & Source:
GitHub - KiN4StAt/ktsignal
Contribute to KiN4StAt/ktsignal development by creating an account on GitHub.
github.com
Последнее редактирование: