11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
21PROMEKI_NAMESPACE_BEGIN
55template <
typename... Args>
class Signal {
58 using Function = promeki::Function<void(Args...)>;
61 template <
typename T>
struct removeConstAndRef {
62 using type = std::remove_const_t<std::remove_reference_t<T>>;
66 template <
typename T>
using RemoveConstAndRef =
typename removeConstAndRef<T>::type;
86 static VariantList pack(Args... args);
93 Signal(
void *owner =
nullptr,
const char *prototype =
nullptr) : _owner(owner), _prototype(prototype) {}
98 void *owner()
const {
return _owner; }
103 const char *prototype()
const {
return _prototype; }
118 size_t connect(Function slot,
void *ptr =
nullptr) {
119 size_t slotID = nextSlotId();
120 Mutex::Locker lock(_slotsMutex);
121 _slots += Info(slotID, slot, ptr);
182 size_t connect(Function slot, ObjectBase *owner);
200 template <
typename T>
size_t connect(T *obj,
void (T::*memberFunction)(Args...)) {
201 size_t slotID = nextSlotId();
202 Mutex::Locker lock(_slotsMutex);
203 _slots += Info(slotID,
204 ([obj, memberFunction](Args... args) { (obj->*memberFunction)(args...); }), obj);
218 void disconnect(
size_t slotID) {
219 Mutex::Locker lock(_slotsMutex);
220 _slots.removeIf([slotID](
const Info &info) {
return info.id == slotID; });
236 template <
typename T>
void disconnect(
const T *
object,
void (T::*memberFunction)(Args...)) {
237 Mutex::Locker lock(_slotsMutex);
238 _slots.removeIf([
object, memberFunction](
const Info &info) {
239 return static_cast<const T *
>(info.object) ==
object && info.func == memberFunction;
250 template <
typename T>
void disconnectFromObject(
const T *
object) {
251 Mutex::Locker lock(_slotsMutex);
253 [
object](
const Info &info) {
return static_cast<const T *
>(info.object) ==
object; });
265 void emit(Args... args)
const {
275 Mutex::Locker lock(_slotsMutex);
278 for (
const auto &slot : snapshot) slot.func(args...);
287 const void *
object =
nullptr;
289 Info(
size_t id, Function f,
const void *obj =
nullptr) : id(id), func(f), object(obj) {}
292 void *_owner =
nullptr;
293 const char *_prototype =
nullptr;
295 mutable Mutex _slotsMutex;
302 static size_t nextSlotId() {
303 static Atomic<size_t> counter{0};