#include <iostream>
#include <list>

namespace _detailEventSystem
{
	template<typename ... Args>
	class BaseFunc
	{
	public:
		virtual ~BaseFunc() = default;
		virtual void operator()(Args ...) = 0;
	};

	template<class Type, typename ... Args>
	class MethodFunc final : public BaseFunc<Args...>
	{
	public:
		typedef void(Type::*Func)(Args ...);

		MethodFunc(Type *t, Func f) : m_t(t), m_f(f) {}

		void operator()(Args ...args) final { (m_t->*m_f)(args ...); }
	private:
		Type *m_t;
		Func m_f;
	};

	template<typename ... Args>
	struct Data
	{
		BaseFunc<Args...> *event = nullptr;
		bool active = false;
	};

} // namespace _detailEventSystem

class EventListener
{
public:
	virtual ~EventListener()
	{
		if (m_reg) *m_reg = false; m_reg = nullptr;
	}

	void _register_(bool &reg)
	{
		m_reg = &reg;
	}
private:
	bool *m_reg = nullptr;
};

template<typename ... Args>
class EventSignal
{
public:
	template<class Type>
	void Connect(Type *t, void(Type::*f)(Args ...))
	{
		_detailEventSystem::Data<Args...> d = {
			new _detailEventSystem::MethodFunc<Type, Args ...>(t, f),
			true
		};
		m_lists.emplace_back(d);

		auto &it = m_lists.back();
		t->_register_(it.active);
	}

	void operator()(Args ...args) noexcept
	{
		for (auto i = m_lists.begin(); i != m_lists.end();)
		{
			if ((*i).active)
			{
				(*(*i).event)(args...);
				++i;
			}
			else
			{
				delete (*i).event;
				i = m_lists.erase(i);
			}				
		}
	}

private:
	using eventData = _detailEventSystem::Data<Args...>;
	std::list<eventData> m_lists;
};

class FooB1 : public EventListener
{
public:
	~FooB1() { delete i; i = 0; }
	void Key(uint32_t key, bool press)
	{
		std::cout << "hell1" << key << *i << std::endl;
	}

	int *i = new int(10);
};

int main() {
	FooB1 *f1 = new FooB1;
	EventSignal<uint32_t, bool> sig3;
	sig3.Connect(f1, &FooB1::Key);
	sig3(10, true);
	sig3(20, true);
	delete f1; f1 = nullptr;
	sig3(30, true);

	return 0;
}