This is a single header event manager that I'm using in my game.

### Disclaimer

I ripped everything from these lovely people: 
 - https://austinmorlan.com/posts/entity_component_system/ 
 - https://codereview.stackexchange.com/questions/252884/c-event-system-game-engine 

so give me little to no credit for the ideas used, but I did write every single line myself (using they're implementations as heavy motivation). 

### Looking for

* if it's readable
* if there are any hidden bugs (I'm an amateur C++ hobbiest programmer, ~1 year, little experience with static and used it anyway)
* features I should add (does this cover everything I need to make a small scale game? I have little experience and don't know if I covered everything)
* just an overall review would be nice (:

### The goals of the event manager

* no base event class
* events are just POD structs
* as few virtual methods as possible
* no explicit registering of events
* fast contiguous execution of functions (I dont really mind if subscribing takes longer to achieve this)
* simple api (no std::bind, lambdas, etc...)
* single header

### Example usage:

```
#include <iostream>
#include "EventManager.h"

// events
struct LevelDown {
	int level;
};

struct LevelUp {
	int level;
};

// event handlers / listeners / subscribers
void handleLevelUp(const LevelUp& event) {
	std::cout << "level: " << event.level << '\n';
}
void handleLevelDown(const LevelDown& event) {
	std::cout << "downlevel: " << event.level << '\n';
}
void levelDownConsiquence(const LevelDown& event) {
	std::cout << "downlevel consiquence: " << event.level << '\n';
}

class DownLevelClass {
public:
	explicit DownLevelClass(EventManager* em) {
		em->subscribe<LevelDown>(&DownLevelClass::method, this);
	}
private:
	void method(const LevelDown& event) const {
		std::cout << "method down level: " << event.level << '\n';
	}
};

int main() {
	EventManager em;

	int level{ 0 };

	// use handle to unsubscibe
	auto levelUpHandle = em.subscribe<LevelUp>(&handleLevelUp);
	// it is not neccissary to have it if you plan on never unsubscribing
	em.subscribe<LevelDown>(&handleLevelDown);
	em.subscribe<LevelDown>(&levelDownConsiquence);
	DownLevelClass DLC(&em);

	level--;
	em.publishBlocking<LevelDown>({ level });
	level++;
	em.publishBus<LevelUp>({ level });
	em.publishBlocking<LevelUp>({ level });
	em.pollEvents();

	em.unsubscribe<LevelUp>(levelUpHandle);
}
```

This should output:

```
downlevel: -1
downlevel consiquence: -1
method down level: -1
level: 0
level: 0
```

### Summary of the functionality provided

* you can subscribe with a POD struct type and a raw function pointer
* you can unsubscribe by passing in the handle returned by the subscribe and the event type
* you can publish blocking events with the event type and the same instance of that event type (has to be pod)
* you can publish to the bus (same rules as publishing a blocking event)
* you can poll bus events by calling poll events, this is blocking
* unsubscribing does exactly what it says, needs event type and handle from subscribe.

### Implementation (EventManager.h)

```
#pragma once
#include <vector>
#include <functional>
#include <memory>
#include <unordered_map>
#include <assert.h>

class ICallbackContainer {
public:
	virtual ~ICallbackContainer() = default;

	virtual void callSaved() const = 0;
};

template<typename EventType>
class CallbackContainer : public ICallbackContainer {
public:
	using CallbackType = std::function<void(const EventType&)>;
	using SubscriberHandle = size_t;

	SubscriberHandle addCallback(CallbackType callback);

	void removeCallback(SubscriberHandle handle);

	void operator() (const EventType& event) const {
		for (auto& callback : m_Callbacks) {
			callback(event);
		}
	}

	void save(const EventType& event);
	void callSaved() const override;

private:
	std::vector<CallbackType> m_Callbacks{};
	std::vector<SubscriberHandle> m_FreeHandles{};
	std::unordered_map<SubscriberHandle, size_t> m_HandleToIndex{};
	std::unordered_map<size_t, SubscriberHandle> m_IndexToHandle{};

	EventType m_SavedEvent{};
};

template<typename EventType>
auto CallbackContainer<EventType>::addCallback(CallbackType callback) -> SubscriberHandle {
	SubscriberHandle handle;
	size_t newIndex = m_Callbacks.size();

	if (m_FreeHandles.empty()) {
		handle = m_Callbacks.size();
	}
	else {
		handle = m_FreeHandles.back();
		m_FreeHandles.pop_back();
	}
	m_HandleToIndex[handle] = newIndex;
	m_IndexToHandle[newIndex] = handle;

	if (newIndex >= m_Callbacks.size()) {
		m_Callbacks.resize(newIndex + 1);
	}
	m_Callbacks[newIndex] = callback;
	return handle;
}

template<typename EventType>
void CallbackContainer<EventType>::removeCallback(SubscriberHandle handle) {
	assert(m_HandleToIndex.find(handle) != m_HandleToIndex.end());

	size_t indexOfRemovedHandle = m_HandleToIndex[handle];
	size_t indexOfLastElement = m_Callbacks.size() - 1;

	if (indexOfRemovedHandle != indexOfLastElement) {
		SubscriberHandle handleOfLastElement = m_IndexToHandle[indexOfLastElement];
		m_HandleToIndex[handleOfLastElement] = indexOfRemovedHandle;
		m_IndexToHandle[indexOfRemovedHandle] = handleOfLastElement;
		m_Callbacks[indexOfRemovedHandle] = m_Callbacks[indexOfLastElement];
	}
	else {
		m_Callbacks.pop_back();
	}

	m_HandleToIndex.erase(handle);
	m_IndexToHandle.erase(indexOfLastElement);
	m_FreeHandles.emplace_back(handle);
}

template<typename EventType>
void CallbackContainer<EventType>::save(const EventType& event) {
	m_SavedEvent = event;
}

template<typename EventType>
void CallbackContainer<EventType>::callSaved() const {
	for (auto& callback : m_Callbacks) {
		callback(m_SavedEvent);
	}
}

class EventManager {
public:
	template<typename EventType, typename Function>
	typename CallbackContainer<EventType>::SubscriberHandle subscribe(Function callback);

	template<typename EventType, typename Method, typename Instance>
	typename CallbackContainer<EventType>::SubscriberHandle subscribe(Method callback, Instance instance);

	template<typename EventType>
	void unsubscribe(typename CallbackContainer<EventType>::SubscriberHandle handle);

	template<typename EventType>
	void publishBlocking(const EventType& event) const;

	template<typename EventType>
	void publishBlocking(EventType&& event) const;
	
	template<typename EventType>
	void publishBus(const EventType& event);

	template<typename EventType>
	void publishBus(EventType&& event);

	void pollEvents();

private:
	template<typename EventType>
	static inline CallbackContainer<EventType> s_Callbacks;
	std::vector<const ICallbackContainer*> m_EventBus;
};

template<typename EventType, typename Function>
inline typename CallbackContainer<EventType>::SubscriberHandle EventManager::subscribe(Function callback) {
	return s_Callbacks<EventType>.addCallback(callback);
}

template<typename EventType, typename Method, typename Instance>
typename CallbackContainer<EventType>::SubscriberHandle EventManager::subscribe(Method callback, Instance instance) {
	std::function<void(const EventType&)> function{ std::bind(callback, instance, std::placeholders::_1) };
	return s_Callbacks<EventType>.addCallback(std::move(function));
}

template<typename EventType>
inline void EventManager::unsubscribe(typename CallbackContainer<EventType>::SubscriberHandle handle) {
	s_Callbacks<EventType>.removeCallback(handle);
}

template<typename EventType>
inline void EventManager::publishBlocking(const EventType& event) const {
	s_Callbacks<EventType>(event);
}

template<typename EventType>
inline void EventManager::publishBlocking(EventType&& event) const {
	s_Callbacks<EventType>(std::forward<EventType>(event));
}

template<typename EventType>
void EventManager::publishBus(const EventType& event) {
	s_Callbacks<EventType>.save(event);

	m_EventBus.emplace_back(&s_Callbacks<EventType>);
}

template<typename EventType>
void EventManager::publishBus(EventType&& event) {
	s_Callbacks<EventType>.save(std::forward<EventType>(event));

	m_EventBus.emplace_back(&s_Callbacks<EventType>);
}


inline void EventManager::pollEvents() {
	for (const auto& callback : m_EventBus) {
		callback->callSaved();
	}
	m_EventBus.clear();
}
```

### Questions

* I'm worried the static `s_Callbacks` in the `EventManager` class is bad
* scaleability (in usage and with features)
* features I should add (in the context of OpenGL and windows.h gamedev)
* is there any way to get rid of the base `CallbackContainer` class? do I even need too?