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

View File

@ -3,7 +3,6 @@
#include <functional>
#include <QString>
#include "data_types.h"
#include "validation.h"
namespace Inlet {
template<typename... Types> struct SignatureImpl;
@ -94,17 +93,16 @@ namespace Inlet {
Callable<Ret, Args...> _func = (Callable<Ret, Args...>)addr;
SignatureImpl<Ret, Args...> _args_value;
static CmdsImpl<addr, Ret, Args...>* _global_inst;
static CmdsImpl<addr, Ret, Args...>* _unique_inst;
public:
CmdsImpl() : _args_value() { }
CmdsImpl(Args... args) :_args_value(args...) { }
static CmdsImpl<addr, Ret, Args...>* global() {
if (!_global_inst) {
_global_inst = new CmdsImpl<addr, Ret, Args...>();
}
return _global_inst;
static CmdsImpl<addr, Ret, Args...>* unique() {
if (!_unique_inst)
_unique_inst = new CmdsImpl<addr, Ret, Args...>();
return _unique_inst;
}
Ret execute(Args... args) {
@ -112,6 +110,10 @@ namespace Inlet {
return _args_value.execute(_func);
}
SignatureImpl<Ret, Args...>& getArgSequence() {
return _args_value;
}
Ret result() const {
return _args_value.result();
}
@ -130,7 +132,7 @@ namespace Inlet {
_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 {
@ -138,17 +140,16 @@ namespace Inlet {
Callable<Ret, Args...> _func = (Callable<Ret, Args...>)addr;
SignatureImpl<Ret, Args...> _args_value;
static EventsImpl<addr, Ret, Args...>* _global_inst;
static EventsImpl<addr, Ret, Args...>* _unique_inst;
public:
EventsImpl() : _args_value() { }
EventsImpl(Args... args) : _args_value(args...) { }
static EventsImpl<addr, Ret, Args...>* global() {
if (!_global_inst) {
_global_inst = new EventsImpl<addr, Ret, Args...>();
}
return _global_inst;
static EventsImpl<addr, Ret, Args...>* unique() {
if(!_unique_inst)
_unique_inst = new EventsImpl<addr, Ret, Args...>();
return _unique_inst;
}
void execute(Args... args) {
@ -159,9 +160,7 @@ namespace Inlet {
quint64 address() const {
return (quint64) addr;
}
void run() {
_args_value.execute(_func);
}
void run() { }
virtual void saveTo(datas::IDataObject& object) {
_args_value.saveTo(0, object);
}
@ -169,5 +168,7 @@ namespace Inlet {
_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 Inlet;
Dispatch* Dispatch::_unique_inst = new Dispatch();
Dispatch* dispatch::Dispatch::unique() {
return _unique_inst;
}
QList<quint64> Dispatch::allCmds() const {
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);
}
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 {
return _cmds_map[addr].first;
}
@ -20,5 +38,37 @@ QString Dispatch::getCmdDefault(quint64 addr) const {
}
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();
}
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 <QHash>
#include "cmds_basic.h"
#include "validation.h"
namespace dispatch {
class IOutput {
public:
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 {
private:
QHash<quint64, std::pair<QString, Inlet::IRunbase*>> _cmds_map;
QHash<quint64, validate::IValidatorTemplet*> _cmds_validators;
QHash<quint64, std::pair<QString, Inlet::IRunbase*>> _events_map;
QList<IOutput*> _output_list;
static Dispatch* _unique_inst;
public:
static Dispatch* unique();
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 getCmdDefault(quint64 addr) const;
void runWith(Inlet::IRunbase* unit);
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 getEventDefault(quint64 addr) const;
QString notifyWith(Inlet::IRunbase* unit);
void notifyWith(Inlet::IRunbase* unit);
};
}

View File

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

View File

@ -5,6 +5,7 @@
#include <iostream>
#include <functional>
#include "data_types.h"
#include "cmds_basic.h"
namespace validate {
@ -24,7 +25,13 @@ namespace validate {
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>
struct ValidateTemplet<head_type, rest_type...> : public ValidateTemplet<rest_type...> {
private:
@ -34,12 +41,20 @@ namespace validate {
void add(Validator<head_type> vinst) {
validator_list << vinst;
}
bool check(head_type value) {
bool check(head_type value) const {
for (auto u : validator_list)
if (!u.check(value))
return false;
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 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 {
return (quint64) func;
}
@ -151,6 +171,12 @@ namespace validate {
template<int n> ArgsPosition<n, args_type...> pos() {
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());
}
};
}