/******************************************************************************
Welcome to GDB Online.
GDB online is an online compiler and debugger tool for C, C++, Python, Java, PHP, Ruby, Perl,
C#, OCaml, VB, Swift, Pascal, Fortran, Haskell, Objective-C, Assembly, HTML, CSS, JS, SQLite, Prolog.
Code, Compile, Run and Debug online from anywhere in world.
*******************************************************************************/
#include <iostream>
using namespace std;
int main()
{
cout<<"Hello World";
return 0;
}
#pragma once
#include <unordered_map>
#include <functional>
#include <typeindex>
#include "EBHandle.h"
struct BaseEvent {
BaseEvent() = default;
virtual ~BaseEvent() = default;
};
class EventBus {
std::unordered_map<std::type_index, std::unordered_map<int, std::function<void(const BaseEvent &)>>> m_callbacks;
int m_keyCounter = 0;
public:
EventBus() = default;
template<typename EventType>
EBHandle addEventListener(const std::function<void(const EventType &)> &callback) {
// passing m_callback by copy is necessary. otherwise if callback passed to addEventListener by reference and it is destroyed, lambda will have dangling reference
auto wrapper = [callback](const BaseEvent &baseEvent) {
callback(static_cast<const EventType &>(baseEvent));
};
std::type_index type = typeid(EventType);
m_callbacks[type][m_keyCounter] = wrapper;
return {this, type, m_keyCounter++};
};
template<typename EventType>
void removeEventListener(int key) {
m_callbacks[typeid(EventType)].erase(key);
};
void removeEventListener(std::type_index type, int key) {
m_callbacks[type].erase(key);
};
void emit(const BaseEvent &event) {
auto &eventTypeCallbacks = m_callbacks[typeid(event)];
for (auto &pair: eventTypeCallbacks) {
pair.second(event);
}
};
};
#pragma once
#include <typeindex>
class EventBus;
class EBHandle {
private:
int m_key = -1;
bool isRemoved = false;
std::type_index m_type = typeid(int);
EventBus* m_eventBus = nullptr;
public:
EBHandle(EventBus *eventBus, std::type_index type, int key);
void remove();
};
//#include "EBHandle.h" //this is not strictly needed here
#include "EventBus.h"
EBHandle::EBHandle(EventBus *eventBus, std::type_index type, int key) : m_key(key), m_type(type), m_eventBus(eventBus) {};
void EBHandle::remove() {
m_eventBus->removeEventListener(m_type, m_key);
isRemoved = true;
}