#include <iostream>
#include <forward_list>
using namespace std;
class EventResizeEventListener
{
public:
virtual ~EventResizeEventListener() = default;
virtual void Resize(uint32_t w, uint32_t h) = 0;
};
template<typename T, typename ... Args>
class EventSignal
{
typedef void(T::*Func)(Args ...);
struct listData
{
void operator()(Args ...args) { (listener->*func)(args ...); }
T *listener = nullptr;
Func func;
bool active = false;
};
public:
void Connect(T *listener, void(T::*f)(Args ...))
{
// todo: register id
listData data = { listener, f, true };
m_lists.emplace_front(data);
}
void operator()(Args ...args) noexcept
{
for (auto &i : m_lists)
{
if (i.active)
{
i(args...);
}
else
;// todo: remove
}
}
private:
std::forward_list<listData> m_lists;
};
// кастомный класс
class FooBla : public EventResizeEventListener
{
public:
void Resize(uint32_t w, uint32_t h) final
{
std::cout << w << " " << h << std::endl;
}
};
int main() {
FooBla fff;
// класс оповещения
EventSignal<EventResizeEventListener, uint32_t, uint32_t> siga;
// регистрация слушателя
siga.Connect(&fff, &EventResizeEventListener::Resize);
// оповещение
siga(10, 20);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Zm9yd2FyZF9saXN0Pgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY2xhc3MgRXZlbnRSZXNpemVFdmVudExpc3RlbmVyCnsKcHVibGljOgoJdmlydHVhbCB+RXZlbnRSZXNpemVFdmVudExpc3RlbmVyKCkgPSBkZWZhdWx0OwoJdmlydHVhbCB2b2lkIFJlc2l6ZSh1aW50MzJfdCB3LCB1aW50MzJfdCBoKSA9IDA7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZSAuLi4gQXJncz4KY2xhc3MgRXZlbnRTaWduYWwKewoJdHlwZWRlZiB2b2lkKFQ6OipGdW5jKShBcmdzIC4uLik7CglzdHJ1Y3QgbGlzdERhdGEKCXsKCQl2b2lkIG9wZXJhdG9yKCkoQXJncyAuLi5hcmdzKSB7IChsaXN0ZW5lci0+KmZ1bmMpKGFyZ3MgLi4uKTsgfQoJCQoJCVQgKmxpc3RlbmVyID0gbnVsbHB0cjsKCQlGdW5jIGZ1bmM7CgkJYm9vbCBhY3RpdmUgPSBmYWxzZTsKCX07CgpwdWJsaWM6CgoJdm9pZCBDb25uZWN0KFQgKmxpc3RlbmVyLCB2b2lkKFQ6OipmKShBcmdzIC4uLikpCgl7CgkJLy8gdG9kbzogcmVnaXN0ZXIgaWQKCQlsaXN0RGF0YSBkYXRhID0geyBsaXN0ZW5lciwgZiwgdHJ1ZSB9OwoJCW1fbGlzdHMuZW1wbGFjZV9mcm9udChkYXRhKTsKCX0KCgl2b2lkIG9wZXJhdG9yKCkoQXJncyAuLi5hcmdzKSBub2V4Y2VwdAoJewoJCWZvciAoYXV0byAmaSA6IG1fbGlzdHMpCgkJewoJCQlpZiAoaS5hY3RpdmUpCgkJCXsKCQkJCWkoYXJncy4uLik7CgkJCX0KCQkJZWxzZQoJCQkJOy8vIHRvZG86IHJlbW92ZQoJCX0KCX0KCnByaXZhdGU6CglzdGQ6OmZvcndhcmRfbGlzdDxsaXN0RGF0YT4gbV9saXN0czsKfTsKCgovLyDQutCw0YHRgtC+0LzQvdGL0Lkg0LrQu9Cw0YHRgQpjbGFzcyBGb29CbGEgOiBwdWJsaWMgRXZlbnRSZXNpemVFdmVudExpc3RlbmVyCnsKcHVibGljOgoJdm9pZCBSZXNpemUodWludDMyX3QgdywgdWludDMyX3QgaCkgZmluYWwKCXsKCQlzdGQ6OmNvdXQgPDwgdyA8PCAiICIgPDwgaCA8PCBzdGQ6OmVuZGw7Cgl9Cn07CgoKaW50IG1haW4oKSB7CglGb29CbGEgZmZmOwoKCS8vINC60LvQsNGB0YEg0L7Qv9C+0LLQtdGJ0LXQvdC40Y8KCUV2ZW50U2lnbmFsPEV2ZW50UmVzaXplRXZlbnRMaXN0ZW5lciwgdWludDMyX3QsIHVpbnQzMl90PiBzaWdhOwoKCS8vINGA0LXQs9C40YHRgtGA0LDRhtC40Y8g0YHQu9GD0YjQsNGC0LXQu9GPCglzaWdhLkNvbm5lY3QoJmZmZiwgJkV2ZW50UmVzaXplRXZlbnRMaXN0ZW5lcjo6UmVzaXplKTsKCgkvLyDQvtC/0L7QstC10YnQtdC90LjQtQoJc2lnYSgxMCwgMjApOwoJCglyZXR1cm4gMDsKfQ==