#pragma once

#include <algorithm>
#include <functional>
#include <vector>

namespace td {
namespace utils {

template <typename Listener>
class ObjectNotifier {
protected:
	std::vector<Listener*> m_Listeners;

public:
	void BindListener(Listener* listener) {
		m_Listeners.push_back(listener);
	}

	void UnbindListener(Listener* listener) {
		auto iter = std::find(m_Listeners.begin(), m_Listeners.end(), listener);

		if (iter == m_Listeners.end()) return;

		m_Listeners.erase(iter);
	}

	template <typename Func, typename... Args>
	void NotifyListeners(Func function, Args... args) {
		for (Listener* listener : m_Listeners)
			std::bind(function, listener, args...)();
	}
};

} // namespace utils
} // namespace td
