107 lines
2.1 KiB
C++
107 lines
2.1 KiB
C++
//
|
|
// Created by erki on 12/09/23.
|
|
//
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
#include <array>
|
|
#include <cstring>
|
|
|
|
#include <utility_function.hpp>
|
|
#include <utility_ringbuffer.hpp>
|
|
|
|
#include "cpptick/argstore.hpp"
|
|
#include "cpptick/scheduler.hpp"
|
|
|
|
namespace cpptick
|
|
{
|
|
|
|
template<typename>
|
|
struct Slot;
|
|
|
|
template<typename R, SlotArgument... Args>
|
|
struct Slot<R(Args...)>
|
|
{
|
|
std::array<Utility::IFunction<R (Args...)>*, 12> signals;
|
|
Scheduler* scheduler;
|
|
|
|
Utility::FunctionOwned<Slot<R(Args...)>, void (ArgStorage&)> invoke_ptr;
|
|
|
|
Slot() = delete;
|
|
explicit Slot(Scheduler* sched)
|
|
: scheduler(sched)
|
|
, invoke_ptr(*this, &Slot<R(Args...)>::callUp)
|
|
{
|
|
signals.fill(nullptr);
|
|
}
|
|
|
|
Slot(const Slot&) = delete;
|
|
Slot(Slot&&) = delete;
|
|
Slot& operator=(const Slot&) = delete;
|
|
Slot& operator=(Slot&&) = delete;
|
|
|
|
void connect(Utility::IFunction<R (Args...)>* signal)
|
|
{
|
|
for (auto*& callable : signals)
|
|
{
|
|
if (callable == nullptr)
|
|
{
|
|
callable = signal;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
Utility::IFunction<R (Args...)>* connect(R (*func)(Args...))
|
|
{
|
|
auto* f = new Utility::Function<R (Args...)>(func);
|
|
|
|
connect(f);
|
|
|
|
return f;
|
|
}
|
|
|
|
template<typename Source>
|
|
Utility::IFunction<R (Args...)>* connect(Source& src, R (Source::* func)(Args...))
|
|
{
|
|
auto* f = new Utility::FunctionOwned<Source, R (Args...)>(src, func);
|
|
|
|
connect(f);
|
|
|
|
return f;
|
|
}
|
|
|
|
template<size_t... Is>
|
|
void callUpFunction(Utility::IFunction<R (Args...)>* func, ArgStorage& args, std::index_sequence<Is...>)
|
|
{
|
|
(*func)(std::forward<Args>(args.at<Args>(Is))...);
|
|
}
|
|
|
|
void callUpFunction(Utility::IFunction<R (Args...)>* func, ArgStorage& args)
|
|
{
|
|
callUpFunction(func, args, std::make_index_sequence<sizeof...(Args)>{});
|
|
}
|
|
|
|
void callUp(ArgStorage& args)
|
|
{
|
|
for (auto* f : signals)
|
|
{
|
|
if (f)
|
|
callUpFunction(f, args);
|
|
else
|
|
break;
|
|
}
|
|
|
|
args.cleanUp<Args...>();
|
|
}
|
|
|
|
void invoke(Args... args)
|
|
{
|
|
ArgStorage& storage = scheduler->storeCall(&invoke_ptr);
|
|
(storage.pushArg(std::forward<Args>(args)), ...);
|
|
}
|
|
};
|
|
|
|
}
|