#pragma once #include #include #include "data_types.h" #include "validation.h" namespace Inlet { template struct SignatureImpl; template<> struct SignatureImpl<> { public: SignatureImpl() { } void execute(std::function unit) { unit(); } void result() const { } void saveTo(int index, datas::IDataObject& object) { } void loadFrom(int index, datas::IDataObject& object) { } }; template struct SignatureImpl { private: Ret _result; public: SignatureImpl() : _result(Ret()) { } Ret execute(std::function unit) { _result = unit(); return _result; } Ret result() const { return _result; } void saveTo(int index, datas::IDataObject& object) { datas::dataSet(object, u8"RetValue", _result); } void loadFrom(int index, datas::IDataObject& object) { _result = datas::dataGet(object, u8"RetValue"); } }; template struct SignatureImpl : public SignatureImpl { private: First _args_value; public: SignatureImpl() : SignatureImpl(), _args_value(First()) { } SignatureImpl(First a0, Args... args) :SignatureImpl(args...), _args_value(a0) { } First getArgs0() { return _args_value; } Ret execute(std::function unit) { auto unit_wrap = [&](Args... args) { return unit(_args_value, args...); }; return SignatureImpl::execute(unit_wrap); } void saveTo(int index, datas::IDataObject& object) { datas::dataSet(object, QString(u8"Args_%1").arg(index), _args_value); SignatureImpl::saveTo(index + 1, object); } void loadFrom(int index, datas::IDataObject& object) { _args_value = datas::dataGet(object, QString(u8"Args_%1").arg(index)); SignatureImpl::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 using Callable = Ret(*)(Args...); template struct CmdsImpl : public IRunbase { private: Callable _func = (Callable)addr; SignatureImpl _args_value; static CmdsImpl* _global_inst; public: CmdsImpl() : _args_value() { } CmdsImpl(Args... args) :_args_value(args...) { } static CmdsImpl* global() { if (!_global_inst) { _global_inst = new CmdsImpl(); } return _global_inst; } Ret execute(Args... args) { _args_value = SignatureImpl(args...); return _args_value.execute(_func); } 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) { _args_value.saveTo(0, object); } virtual void loadFrom(datas::IDataObject& object) { _args_value.loadFrom(0, object); } }; template CmdsImpl* CmdsImpl::_global_inst = nullptr; template struct EventsImpl : public IRunbase { private: Callable _func = (Callable)addr; SignatureImpl _args_value; static EventsImpl* _global_inst; public: EventsImpl() : _args_value() { } EventsImpl(Args... args) : _args_value(args...) { } static EventsImpl* global() { if (!_global_inst) { _global_inst = new EventsImpl(); } return _global_inst; } void execute(Args... args) { _args_value = SignatureImpl(args...); } // IRunbase quint64 address() const { return (quint64) addr; } void run() { _args_value.execute(_func); } virtual void saveTo(datas::IDataObject& object) { _args_value.saveTo(0, object); } virtual void loadFrom(datas::IDataObject& object) { _args_value.loadFrom(0, object); } }; template EventsImpl* EventsImpl::_global_inst = nullptr; }