156 lines
3.8 KiB
C++
156 lines
3.8 KiB
C++
#pragma once
|
|
|
|
#include <functional>
|
|
#include <QString>
|
|
#include "data_types.h"
|
|
|
|
namespace Inlet {
|
|
template<typename... Types> struct SignatureImpl;
|
|
template<> struct SignatureImpl<> {
|
|
public:
|
|
SignatureImpl() { }
|
|
|
|
void execute(std::function<void(void)> unit) {
|
|
unit();
|
|
}
|
|
void result() const { }
|
|
|
|
void saveTo(int index, datas::IDataObject& object) { }
|
|
void loadFrom(int index, datas::IDataObject& object) { }
|
|
};
|
|
template<typename Ret> struct SignatureImpl<Ret> {
|
|
private:
|
|
Ret _result;
|
|
|
|
public:
|
|
SignatureImpl() : _result(Ret()) { }
|
|
|
|
Ret execute(std::function<Ret(void)> unit) {
|
|
_result = unit();
|
|
return _result;
|
|
}
|
|
|
|
Ret result() const {
|
|
return _result;
|
|
}
|
|
|
|
void saveTo(int index, datas::IDataObject& object) {
|
|
datas::dataSet<Ret>(object, u8"RetValue", _result);
|
|
}
|
|
void loadFrom(int index, datas::IDataObject& object) {
|
|
_result = datas::dataGet<Ret>(object, u8"RetValue");
|
|
}
|
|
};
|
|
template<typename Ret, typename First, typename... Args>
|
|
struct SignatureImpl<Ret, First, Args...> : public SignatureImpl<Ret, Args...> {
|
|
private:
|
|
First _args_value;
|
|
|
|
public:
|
|
SignatureImpl() : SignatureImpl<Ret, Args...>(), _args_value(First()) { }
|
|
SignatureImpl(First a0, Args... args) :SignatureImpl<Ret, Args...>(args...), _args_value(a0) { }
|
|
|
|
First getArgs0() {
|
|
return _args_value;
|
|
}
|
|
|
|
Ret execute(std::function<Ret(First, Args...)> unit) {
|
|
auto unit_wrap = [&](Args... args) {
|
|
return unit(_args_value, args...);
|
|
};
|
|
return SignatureImpl<Ret, Args...>::execute(unit_wrap);
|
|
}
|
|
|
|
|
|
void saveTo(int index, datas::IDataObject& object) {
|
|
datas::dataSet<First>(object, QString(u8"Args_%1").arg(index), _args_value);
|
|
SignatureImpl<Ret, Args...>::saveTo(index + 1, object);
|
|
}
|
|
void loadFrom(int index, datas::IDataObject& object) {
|
|
_args_value = datas::dataGet<First>(object, QString(u8"Args_%1").arg(index));
|
|
SignatureImpl<Ret, Args...>::loadFrom(index + 1, object);
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
class IRunbase {
|
|
public:
|
|
virtual ~IRunbase() = default;
|
|
|
|
virtual quint64 address() const = 0;
|
|
virtual void run() = 0;
|
|
|
|
virtual void saveTo(datas::IDataObject& object) = 0;
|
|
virtual void loadFrom(datas::IDataObject& object) = 0;
|
|
};
|
|
|
|
template<typename Ret, typename... Args> using Callable = Ret(*)(Args...);
|
|
|
|
template<void* addr, typename Ret, typename... Args> struct CmdsImpl : public IRunbase {
|
|
private:
|
|
Callable<Ret, Args...> _func = (Callable<Ret, Args...>)addr;
|
|
SignatureImpl<Ret, Args...> _args_value;
|
|
|
|
public:
|
|
CmdsImpl() : _args_value() { }
|
|
CmdsImpl(Args... args) :_args_value(args...) { }
|
|
|
|
Ret execute(Args... args) {
|
|
_args_value = SignatureImpl<Ret, Args...>(args...);
|
|
return _args_value.execute(_func);
|
|
}
|
|
|
|
SignatureImpl<Ret, Args...>& getArgSequence() {
|
|
return _args_value;
|
|
}
|
|
|
|
Ret result() const {
|
|
return _args_value.result();
|
|
}
|
|
|
|
// IRunbase
|
|
quint64 address() const {
|
|
return (quint64) addr;
|
|
}
|
|
void run() {
|
|
_args_value.execute(_func);
|
|
}
|
|
virtual void saveTo(datas::IDataObject& object) {
|
|
object.setUInt64(u8"Address", (quint64)addr);
|
|
_args_value.saveTo(0, object);
|
|
}
|
|
virtual void loadFrom(datas::IDataObject& object) {
|
|
_args_value.loadFrom(0, object);
|
|
}
|
|
};
|
|
|
|
template<void* addr, typename Ret, typename... Args> struct EventsImpl : public IRunbase {
|
|
private:
|
|
Callable<Ret, Args...> _func = (Callable<Ret, Args...>)addr;
|
|
SignatureImpl<Ret, Args...> _args_value;
|
|
|
|
public:
|
|
EventsImpl() : _args_value() { }
|
|
EventsImpl(Args... args) : _args_value(args...) { }
|
|
|
|
void execute(Args... args) {
|
|
_args_value = SignatureImpl<Ret, Args...>(args...);
|
|
}
|
|
|
|
// IRunbase
|
|
quint64 address() const {
|
|
return (quint64) addr;
|
|
}
|
|
void run() { }
|
|
virtual void saveTo(datas::IDataObject& object) {
|
|
object.setUInt64(u8"Address", (quint64) addr);
|
|
_args_value.saveTo(0, object);
|
|
}
|
|
virtual void loadFrom(datas::IDataObject& object) {
|
|
_args_value.loadFrom(0, object);
|
|
}
|
|
};
|
|
}
|