validate-cmd_register

This commit is contained in:
codeboss 2024-11-17 22:08:08 +08:00
parent ba7ac2503d
commit acfa763c62
6 changed files with 136 additions and 51 deletions

View File

@ -4,44 +4,45 @@
namespace cmds { namespace cmds {
template<typename... Types> struct T; template<typename... Types> struct T;
template<typename Ret, typename... Args> struct T<Ret(Args...)> { template<typename Ret, typename... Args> struct T<Ret(Args...)> {
public:
template<Inlet::Callable<Ret, Args...> func> struct Cmd { template<Inlet::Callable<Ret, Args...> func> struct Cmd {
private: private:
dispatch::Dispatch* _core_bind;
QString _name_value; QString _name_value;
dispatch::Dispatch* core = dispatch::Dispatch::unique();
public: public:
Cmd(dispatch::Dispatch* core, const QString& name) Cmd(const QString& name) : _name_value(name) {
: _core_bind(core), _name_value(name) { auto g_inst = Inlet::CmdsImpl<(void*) func, Ret, Args...>::unique();
auto inst = Inlet::CmdsImpl<(void*) func, Ret, Args...>::global(); core->registerCmd(g_inst->address(), g_inst);
core->registerCmd(inst->address(), inst, name); core->setCmdAlias(g_inst->address(), name);
} }
Ret operator()(Args... args) { Ret operator()(Args... args) {
Inlet::CmdsImpl<(void*) func, Ret, Args...> new_inst(args...); Inlet::CmdsImpl<(void*) func, Ret, Args...> new_inst(args...);
_core_bind->runWith(&new_inst); core->runWith(&new_inst);
return new_inst.result(); return new_inst.result();
} }
}; };
template<Inlet::Callable<Ret, Args...> func> struct Event { template<Inlet::Callable<Ret, Args...> func> struct Event {
private: private:
dispatch::Dispatch* _core_bind;
QString _name_value; QString _name_value;
dispatch::Dispatch* core = dispatch::Dispatch::unique();
public: public:
Event(dispatch::Dispatch* core, const QString& name) Event(const QString& name) : _name_value(name) {
: _core_bind(core), _name_value(name) { auto g_inst = Inlet::EventsImpl<(void*)func, Ret, Args...>::unique();
auto inst = Inlet::EventsImpl<(void*) func, Ret, Args...>::global(); core->registerEvent(g_inst->address(), g_inst);
core->registerEvent(inst->address(), inst, name); core->setEventAlias(g_inst->address(), name);
} }
void operator()(Args... args) { void operator()(Args... args) {
Inlet::EventsImpl<(void*)func, Ret, Args...> new_inst(args...); Inlet::EventsImpl<(void*) func, Ret, Args...> new_inst(args...);
_core_bind->notifyWith(&new_inst); core->notifyWith(&new_inst);
} }
}; };
}; };
} }

View File

@ -3,7 +3,6 @@
#include <functional> #include <functional>
#include <QString> #include <QString>
#include "data_types.h" #include "data_types.h"
#include "validation.h"
namespace Inlet { namespace Inlet {
template<typename... Types> struct SignatureImpl; template<typename... Types> struct SignatureImpl;
@ -94,17 +93,16 @@ namespace Inlet {
Callable<Ret, Args...> _func = (Callable<Ret, Args...>)addr; Callable<Ret, Args...> _func = (Callable<Ret, Args...>)addr;
SignatureImpl<Ret, Args...> _args_value; SignatureImpl<Ret, Args...> _args_value;
static CmdsImpl<addr, Ret, Args...>* _global_inst; static CmdsImpl<addr, Ret, Args...>* _unique_inst;
public: public:
CmdsImpl() : _args_value() { } CmdsImpl() : _args_value() { }
CmdsImpl(Args... args) :_args_value(args...) { } CmdsImpl(Args... args) :_args_value(args...) { }
static CmdsImpl<addr, Ret, Args...>* global() { static CmdsImpl<addr, Ret, Args...>* unique() {
if (!_global_inst) { if (!_unique_inst)
_global_inst = new CmdsImpl<addr, Ret, Args...>(); _unique_inst = new CmdsImpl<addr, Ret, Args...>();
} return _unique_inst;
return _global_inst;
} }
Ret execute(Args... args) { Ret execute(Args... args) {
@ -112,6 +110,10 @@ namespace Inlet {
return _args_value.execute(_func); return _args_value.execute(_func);
} }
SignatureImpl<Ret, Args...>& getArgSequence() {
return _args_value;
}
Ret result() const { Ret result() const {
return _args_value.result(); return _args_value.result();
} }
@ -130,7 +132,7 @@ namespace Inlet {
_args_value.loadFrom(0, object); _args_value.loadFrom(0, object);
} }
}; };
template<void* addr, typename Ret, typename... Args> CmdsImpl<addr, Ret, Args...>* CmdsImpl<addr, Ret, Args...>::_global_inst = nullptr; template<void* addr, typename Ret, typename... Args> CmdsImpl<addr, Ret, Args...>* CmdsImpl<addr, Ret, Args...>::_unique_inst = nullptr;
template<void* addr, typename Ret, typename... Args> struct EventsImpl : public IRunbase { template<void* addr, typename Ret, typename... Args> struct EventsImpl : public IRunbase {
@ -138,17 +140,16 @@ namespace Inlet {
Callable<Ret, Args...> _func = (Callable<Ret, Args...>)addr; Callable<Ret, Args...> _func = (Callable<Ret, Args...>)addr;
SignatureImpl<Ret, Args...> _args_value; SignatureImpl<Ret, Args...> _args_value;
static EventsImpl<addr, Ret, Args...>* _global_inst; static EventsImpl<addr, Ret, Args...>* _unique_inst;
public: public:
EventsImpl() : _args_value() { } EventsImpl() : _args_value() { }
EventsImpl(Args... args) : _args_value(args...) { } EventsImpl(Args... args) : _args_value(args...) { }
static EventsImpl<addr, Ret, Args...>* global() { static EventsImpl<addr, Ret, Args...>* unique() {
if (!_global_inst) { if(!_unique_inst)
_global_inst = new EventsImpl<addr, Ret, Args...>(); _unique_inst = new EventsImpl<addr, Ret, Args...>();
} return _unique_inst;
return _global_inst;
} }
void execute(Args... args) { void execute(Args... args) {
@ -159,9 +160,7 @@ namespace Inlet {
quint64 address() const { quint64 address() const {
return (quint64) addr; return (quint64) addr;
} }
void run() { void run() { }
_args_value.execute(_func);
}
virtual void saveTo(datas::IDataObject& object) { virtual void saveTo(datas::IDataObject& object) {
_args_value.saveTo(0, object); _args_value.saveTo(0, object);
} }
@ -169,5 +168,7 @@ namespace Inlet {
_args_value.loadFrom(0, object); _args_value.loadFrom(0, object);
} }
}; };
template<void* addr, typename Ret, typename... Args> EventsImpl<addr, Ret, Args...>* EventsImpl<addr, Ret, Args...>::_global_inst = nullptr;
template<void* addr, typename Ret, typename... Args> EventsImpl<addr, Ret, Args...>* EventsImpl<addr, Ret, Args...>::_unique_inst = nullptr;
} }

View File

@ -3,14 +3,32 @@
using namespace dispatch; using namespace dispatch;
using namespace Inlet; using namespace Inlet;
Dispatch* Dispatch::_unique_inst = new Dispatch();
Dispatch* dispatch::Dispatch::unique() {
return _unique_inst;
}
QList<quint64> Dispatch::allCmds() const { QList<quint64> Dispatch::allCmds() const {
return _cmds_map.keys(); return _cmds_map.keys();
} }
void Dispatch::registerCmd(quint64 addr, IRunbase* unit, const QString& alias) { void Dispatch::registerCmd(quint64 addr, IRunbase* unit) {
auto alias = QString("CMD_%1").arg(addr);
_cmds_map[addr] = std::make_pair(alias, unit); _cmds_map[addr] = std::make_pair(alias, unit);
} }
void dispatch::Dispatch::setCmdAlias(quint64 addr, const QString& alias) {
if (_cmds_map.contains(addr)) {
auto tuple = _cmds_map[addr];
_cmds_map[addr] = std::make_pair(alias, tuple.second);
}
}
void dispatch::Dispatch::setCmdValidator(quint64 addr, validate::IValidatorTemplet* inst) {
_cmds_validators[addr] = inst;
}
QString Dispatch::getCmdAlias(quint64 addr) const { QString Dispatch::getCmdAlias(quint64 addr) const {
return _cmds_map[addr].first; return _cmds_map[addr].first;
} }
@ -20,5 +38,37 @@ QString Dispatch::getCmdDefault(quint64 addr) const {
} }
void Dispatch::runWith(IRunbase* unit) { void Dispatch::runWith(IRunbase* unit) {
auto addrs = unit->address();
if (_cmds_validators.contains(addrs)) {
auto validate_templet = _cmds_validators[addrs];
if (!validate_templet->doValidate(unit))
return;
}
unit->run(); unit->run();
} }
QList<quint64> dispatch::Dispatch::allEvents() const {
return _events_map.keys();
}
void dispatch::Dispatch::registerEvent(quint64 addr, Inlet::IRunbase* unit) {
auto alias = QString("Event_%1").arg(addr);
_events_map[addr] = std::make_pair(alias, unit);
}
void dispatch::Dispatch::setEventAlias(quint64 addr, const QString& alias) {
if (_events_map.contains(addr)) {
auto tuple = _events_map[addr];
_events_map[addr] = std::make_pair(alias, tuple.second);
}
}
QString dispatch::Dispatch::getEventAlias(quint64 addr) const {
return _events_map[addr].first;
}
QString dispatch::Dispatch::getEventDefault(quint64 addr) const {
return QString();
}
void dispatch::Dispatch::notifyWith(Inlet::IRunbase* unit) { }

View File

@ -3,35 +3,45 @@
#include <QString> #include <QString>
#include <QHash> #include <QHash>
#include "cmds_basic.h" #include "cmds_basic.h"
#include "validation.h"
namespace dispatch { namespace dispatch {
class IOutput { class IOutput {
public: public:
virtual ~IOutput() = default; virtual ~IOutput() = default;
virtual void write(const QString &title, const QString& desc) = 0; virtual void write(const QString& title, const QString& desc) = 0;
}; };
class Dispatch { class Dispatch {
private: private:
QHash<quint64, std::pair<QString, Inlet::IRunbase*>> _cmds_map; QHash<quint64, std::pair<QString, Inlet::IRunbase*>> _cmds_map;
QHash<quint64, validate::IValidatorTemplet*> _cmds_validators;
QHash<quint64, std::pair<QString, Inlet::IRunbase*>> _events_map; QHash<quint64, std::pair<QString, Inlet::IRunbase*>> _events_map;
QList<IOutput*> _output_list; QList<IOutput*> _output_list;
static Dispatch* _unique_inst;
public: public:
static Dispatch* unique();
QList<quint64> allCmds() const; QList<quint64> allCmds() const;
void registerCmd(quint64 addr, Inlet::IRunbase* unit, const QString& alias); void registerCmd(quint64 addr, Inlet::IRunbase* unit);
void setCmdAlias(quint64 addr, const QString& alias);
void setCmdValidator(quint64 addr, validate::IValidatorTemplet* inst);
QString getCmdAlias(quint64 addr) const; QString getCmdAlias(quint64 addr) const;
QString getCmdDefault(quint64 addr) const; QString getCmdDefault(quint64 addr) const;
void runWith(Inlet::IRunbase* unit); void runWith(Inlet::IRunbase* unit);
QList<quint64> allEvents() const; QList<quint64> allEvents() const;
void registerEvent(quint64 addr, Inlet::IRunbase* unit, const QString& alias); void registerEvent(quint64 addr, Inlet::IRunbase* unit);
void setEventAlias(quint64 addr, const QString& alias);
QString getEventAlias(quint64 addr) const; QString getEventAlias(quint64 addr) const;
QString getEventDefault(quint64 addr) const; QString getEventDefault(quint64 addr) const;
QString notifyWith(Inlet::IRunbase* unit); void notifyWith(Inlet::IRunbase* unit);
}; };
} }

View File

@ -5,24 +5,23 @@
#include "dispatch.h" #include "dispatch.h"
#include "cmds.h" #include "cmds.h"
dispatch::Dispatch c;
int vp(int c) { int vp(int c) {
qDebug() << c; qDebug() << c;
return c; return c;
} }
cmds::T<int(int)>::Cmd<vp> entry(&c, "hello");
namespace xproc { namespace xproc {
int xmp(int arg) { int xmp(int arg) {
qDebug() << "xmp"; qDebug() << "xmp";
return 3; return 3;
} }
cmds::T<int(int)>::Cmd<xmp> xvv(&c, "sfaf");
} }
cmds::T<int(int)>::Cmd<vp> entry("hello");
cmds::T<int(int)>::Cmd<xproc::xmp> xvv("sfaf");
#include "validation.h"
validate::ValidateHelper<(void*)vp, int, int> helper;
using namespace Inlet; using namespace Inlet;
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
@ -37,9 +36,7 @@ int main(int argc, char* argv[]) {
exec.execute(5); exec.execute(5);
entry(50); entry(50);
xvv(2);
xproc::xvv(2);
return a.exec(); return a.exec();
} }

View File

@ -5,6 +5,7 @@
#include <iostream> #include <iostream>
#include <functional> #include <functional>
#include "data_types.h" #include "data_types.h"
#include "cmds_basic.h"
namespace validate { namespace validate {
@ -24,7 +25,13 @@ namespace validate {
template<typename... args_type> struct ValidateTemplet; template<typename... args_type> struct ValidateTemplet;
template<> struct ValidateTemplet<> { }; template<> struct ValidateTemplet<> {
template<typename Ret>
bool validateFor(Inlet::SignatureImpl<Ret>& value_sequence) const {
return true;
}
};
template<typename head_type, typename... rest_type> template<typename head_type, typename... rest_type>
struct ValidateTemplet<head_type, rest_type...> : public ValidateTemplet<rest_type...> { struct ValidateTemplet<head_type, rest_type...> : public ValidateTemplet<rest_type...> {
private: private:
@ -34,12 +41,20 @@ namespace validate {
void add(Validator<head_type> vinst) { void add(Validator<head_type> vinst) {
validator_list << vinst; validator_list << vinst;
} }
bool check(head_type value) { bool check(head_type value) const {
for (auto u : validator_list) for (auto u : validator_list)
if (!u.check(value)) if (!u.check(value))
return false; return false;
return true; return true;
} }
template<typename Ret>
bool validateFor(Inlet::SignatureImpl<Ret, head_type, rest_type...>& value_sequence) const {
head_type head_value = value_sequence.getArgs0();
if (!check(head_value))
return false;
return ValidateTemplet<rest_type...>::validateFor(value_sequence);
}
}; };
@ -141,9 +156,14 @@ namespace validate {
class IValidatorTemplet {
public:
virtual bool doValidate(Inlet::IRunbase* inst) const = 0;
};
template<void* func, typename... types> struct ValidateHelper; template<void* func, typename... types> struct ValidateHelper;
template<void* func, typename return_type, typename... args_type> template<void* func, typename return_type, typename... args_type>
struct ValidateHelper<func, return_type, args_type...> : public ValidateTemplet<args_type...> { struct ValidateHelper<func, return_type, args_type...> : public ValidateTemplet<args_type...>, public IValidatorTemplet {
quint64 address() const { quint64 address() const {
return (quint64) func; return (quint64) func;
} }
@ -151,6 +171,12 @@ namespace validate {
template<int n> ArgsPosition<n, args_type...> pos() { template<int n> ArgsPosition<n, args_type...> pos() {
return ArgsPosition<n, args_type...>(*this); return ArgsPosition<n, args_type...>(*this);
} }
// Ivalidatortemplet
virtual bool doValidate(Inlet::IRunbase* inst) const {
auto valid_data = dynamic_cast<Inlet::CmdsImpl<func, return_type, args_type...>*>(inst);
return ValidateTemplet<args_type...>::validateFor(valid_data->getArgSequence());
}
}; };
} }