#include <iostream>
#include <list>
#define __EVENTLISTENERBODY(_class_) \
public: virtual ~_class_() {if (m_register) *m_register = false; m_register = nullptr;} \
public: void __register(bool ®) {m_register = ®} \
private: bool *m_register = nullptr; \
class EventResizeEventListener
{
__EVENTLISTENERBODY(EventResizeEventListener);
public:
virtual void Resize(uint32_t w, uint32_t h) = 0;
};
class EventKeyListener
{
__EVENTLISTENERBODY(EventKeyListener);
public:
virtual void Key(uint32_t key, bool press) = 0;
};
template<typename T, typename ... Args>
class EventSignal
{
struct listData
{
void operator()(Args ...args) { (listener->*func)(args ...); }
typedef void(T::*Func)(Args ...);
T *listener = nullptr;
Func func;
bool active = false;
};
public:
template <typename TypeU>
void Connect(TypeU *listener, void(TypeU::*func)(Args ...))
{
if (!listener) return;
listData data = { (T*)listener, (void(T::*)(Args...))func, true };
m_lists.emplace_back(data);
auto &it = m_lists.back();
listener->T::__register(it.active);
}
void operator()(Args ...args) noexcept
{
for (auto i = m_lists.begin(); i != m_lists.end();)
{
if ((*i).active)
{
(*i)(args...);
++i;
}
else
i = m_lists.erase(i);
}
}
private:
std::list<listData> m_lists;
};
class FooB :
public EventResizeEventListener,
public EventKeyListener
{
public:
void Resize(uint32_t w, uint32_t h) final
{
std::cout << w << " " << h << std::endl;
}
void Key(uint32_t key, bool press) final
{
if (press)
std::cout << key << " down" << std::endl;
else
std::cout << key << " up" << std::endl;
}
};
int main() {
FooB *fff = new FooB;
EventSignal<EventResizeEventListener, uint32_t, uint32_t> sigResize;
EventSignal<EventKeyListener, uint32_t, bool> sigKey;
sigResize.Connect(fff, &FooB::Resize);
sigKey.Connect(fff, &FooB::Key);
sigResize(10, 20);
sigKey(10, true);
delete fff; fff = nullptr;
sigResize(40, 50);
sigKey(10, false);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bGlzdD4KCiNkZWZpbmUgX19FVkVOVExJU1RFTkVSQk9EWShfY2xhc3NfKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAoJcHVibGljOiB2aXJ0dWFsIH5fY2xhc3NfKCkge2lmIChtX3JlZ2lzdGVyKSAqbV9yZWdpc3RlciA9IGZhbHNlOyBtX3JlZ2lzdGVyID0gbnVsbHB0cjt9IFwKCXB1YmxpYzogdm9pZCBfX3JlZ2lzdGVyKGJvb2wgJnJlZykge21fcmVnaXN0ZXIgPSAmcmVnO30gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCglwcml2YXRlOiBib29sICptX3JlZ2lzdGVyID0gbnVsbHB0cjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAoJCmNsYXNzIEV2ZW50UmVzaXplRXZlbnRMaXN0ZW5lcgp7CglfX0VWRU5UTElTVEVORVJCT0RZKEV2ZW50UmVzaXplRXZlbnRMaXN0ZW5lcik7CnB1YmxpYzoKCXZpcnR1YWwgdm9pZCBSZXNpemUodWludDMyX3QgdywgdWludDMyX3QgaCkgPSAwOwp9OwoKY2xhc3MgRXZlbnRLZXlMaXN0ZW5lcgp7CglfX0VWRU5UTElTVEVORVJCT0RZKEV2ZW50S2V5TGlzdGVuZXIpOwpwdWJsaWM6Cgl2aXJ0dWFsIHZvaWQgS2V5KHVpbnQzMl90IGtleSwgYm9vbCBwcmVzcykgPSAwOwp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgLi4uIEFyZ3M+CmNsYXNzIEV2ZW50U2lnbmFsCnsKCXN0cnVjdCBsaXN0RGF0YQoJewoJCXZvaWQgb3BlcmF0b3IoKShBcmdzIC4uLmFyZ3MpIHsgKGxpc3RlbmVyLT4qZnVuYykoYXJncyAuLi4pOyB9CgoJCXR5cGVkZWYgdm9pZChUOjoqRnVuYykoQXJncyAuLi4pOwoJCVQgKmxpc3RlbmVyID0gbnVsbHB0cjsKCQlGdW5jIGZ1bmM7CgkJYm9vbCBhY3RpdmUgPSBmYWxzZTsJCQoJfTsKCnB1YmxpYzoKCXRlbXBsYXRlIDx0eXBlbmFtZSBUeXBlVT4KCXZvaWQgQ29ubmVjdChUeXBlVSAqbGlzdGVuZXIsIHZvaWQoVHlwZVU6OipmdW5jKShBcmdzIC4uLikpCgl7CgkJaWYgKCFsaXN0ZW5lcikgcmV0dXJuOwoJCWxpc3REYXRhIGRhdGEgPSB7IChUKilsaXN0ZW5lciwgKHZvaWQoVDo6KikoQXJncy4uLikpZnVuYywgdHJ1ZSB9OwoJCW1fbGlzdHMuZW1wbGFjZV9iYWNrKGRhdGEpOwoKCQlhdXRvICZpdCA9IG1fbGlzdHMuYmFjaygpOwoJCWxpc3RlbmVyLT5UOjpfX3JlZ2lzdGVyKGl0LmFjdGl2ZSk7Cgl9CgoJdm9pZCBvcGVyYXRvcigpKEFyZ3MgLi4uYXJncykgbm9leGNlcHQKCXsKCQlmb3IgKGF1dG8gaSA9IG1fbGlzdHMuYmVnaW4oKTsgaSAhPSBtX2xpc3RzLmVuZCgpOykKCQl7CgkJCWlmICgoKmkpLmFjdGl2ZSkKCQkJewoJCQkJKCppKShhcmdzLi4uKTsKCQkJCSsraTsKCQkJfQoJCQllbHNlCgkJCQlpID0gbV9saXN0cy5lcmFzZShpKTsKCQl9Cgl9Cgpwcml2YXRlOgoJc3RkOjpsaXN0PGxpc3REYXRhPiBtX2xpc3RzOwp9OwoKCmNsYXNzIEZvb0IgOiAKCXB1YmxpYyBFdmVudFJlc2l6ZUV2ZW50TGlzdGVuZXIsIAoJcHVibGljIEV2ZW50S2V5TGlzdGVuZXIKewpwdWJsaWM6Cgl2b2lkIFJlc2l6ZSh1aW50MzJfdCB3LCB1aW50MzJfdCBoKSBmaW5hbAoJewoJCXN0ZDo6Y291dCA8PCB3IDw8ICIgIiA8PCBoIDw8IHN0ZDo6ZW5kbDsKCX0KCgl2b2lkIEtleSh1aW50MzJfdCBrZXksIGJvb2wgcHJlc3MpIGZpbmFsCgl7CgkJaWYgKHByZXNzKQoJCQlzdGQ6OmNvdXQgPDwga2V5IDw8ICIgZG93biIgPDwgc3RkOjplbmRsOwoJCWVsc2UKCQkJc3RkOjpjb3V0IDw8IGtleSA8PCAiIHVwIiA8PCBzdGQ6OmVuZGw7Cgl9Cn07CgppbnQgbWFpbigpIHsKCUZvb0IgKmZmZiA9IG5ldyBGb29COwoKCUV2ZW50U2lnbmFsPEV2ZW50UmVzaXplRXZlbnRMaXN0ZW5lciwgdWludDMyX3QsIHVpbnQzMl90PiBzaWdSZXNpemU7CglFdmVudFNpZ25hbDxFdmVudEtleUxpc3RlbmVyLCB1aW50MzJfdCwgYm9vbD4gc2lnS2V5OwoJCQoJc2lnUmVzaXplLkNvbm5lY3QoZmZmLCAmRm9vQjo6UmVzaXplKTsKCXNpZ0tleS5Db25uZWN0KGZmZiwgJkZvb0I6OktleSk7CgoJc2lnUmVzaXplKDEwLCAyMCk7CglzaWdLZXkoMTAsIHRydWUpOwoJCglkZWxldGUgZmZmOyBmZmYgPSBudWxscHRyOwoJCglzaWdSZXNpemUoNDAsIDUwKTsKCXNpZ0tleSgxMCwgZmFsc2UpOwoJCglyZXR1cm4gMDsKfQ==