AsloEngine/asloengine/headers/aslosignals.hpp
2019-08-29 18:42:28 +02:00

163 lines
3.5 KiB
C++
Executable file

//AsloSignals v1.0.0
#include <functional>
#include <vector>
#include <tuple>
namespace aslosignals
{
class SlotBase
{
public:
virtual void emit() {}
};
template <typename ...Args>
class Slot : public SlotBase
{
public:
void emit() override
{
std::apply(slot, parameters);
}
std::function<void (Args...)> slot;
std::tuple<Args...> parameters;
};
class Signal
{
public:
std::vector<SlotBase *> slots;
// Connect Member Method
template <typename T, typename ...Args>
int connect_member(T *instance, void (T::*slot)(Args...), Args... parameters)
{
return bind((std::function<void (Args...)>)([=](Args...) { (instance->*slot)(parameters...); }));
}
// Connect Const Member Method
template <typename T, typename ...Args>
int connect_member(T *instance, void (T::*slot)(Args...) const, Args... parameters)
{
return bind((std::function<void (Args...)>)([=](Args...) { (instance->*slot)(parameters...); }));
}
// Connect Function
template <typename ...Args>
int connect(void (*slot)(Args...), Args... parameters)
{
return bind((std::function<void (Args...)>)([=](Args...) { (*slot)(parameters...); }));
}
void disconnect(int index)
{
slots.erase(slots.begin() + index);
}
void clear()
{
slots.clear();
}
void operator()()
{
for (SlotBase *& slot : slots)
{
slot->emit();
}
}
private:
template <typename ...Args>
int bind(std::function<void (Args...)> slot)
{
Slot<Args...> *_slot = new Slot<Args...>();
_slot->slot = slot;
slots.emplace_back(_slot);
return slots.size() - 1;
}
};
template <typename ...Args>
class TypeSignal
{
public:
std::vector<std::function<void (Args...)>> slots;
// Connect Member Method
template <typename T>
int connect_member(T *instance, void (T::*slot)(Args...))
{
return connect([=](Args... args) { (instance->*slot)(args...); });
}
// Connect Const Member Method
template <typename T>
int connect_member(T *instance, void (T::*slot)(Args...) const)
{
return connect([=](Args... args) { (instance->*slot)(args...); });
}
// Connect Function
int connect(std::function<void (Args...)> slot)
{
slots.emplace_back(slot);
return slots.size() - 1;
}
void disconnect(int index)
{
slots.erase(slots.begin() + index);
}
void clear()
{
slots.clear();
}
void operator()(Args... args)
{
for (std::function<void (Args...)>& slot : slots)
{
slot(args...);
}
}
};
}