#include "commandsdispatcher.h" using namespace Schedule; /** * @brief 命令执行相关Exception */ class Impl_CmdException : public CmdException { public: explicit Impl_CmdException(const QString& type, const QString &reason); virtual ~Impl_CmdException() = default; virtual QString type() const override; virtual QString reason() const override; // exception interface public: virtual const char *what() const noexcept override; private: QString ex_string; int title_length; }; Impl_CmdException::Impl_CmdException(const QString &type, const QString &reason) { title_length = type.length(); ex_string = QString("%1:%2").arg(type, reason); } QString Impl_CmdException::type() const { return ex_string.mid(0, title_length); } QString Impl_CmdException::reason() const { return ex_string.mid(title_length+1); } const char *Impl_CmdException::what() const noexcept { return ex_string.toLocal8Bit(); } CommandsDispatcher::CommandsDispatcher(const QDir &script_out, bool record) : record_execute(record), bout(nullptr), tout(nullptr) { start_time = QDateTime::currentDateTime(); if(record){ auto path = script_out.filePath(QString("commands_%1").arg(start_time.toSecsSinceEpoch())); bout = new QFile(path); if(!bout->open(QIODevice::WriteOnly|QIODevice::Text)){ delete bout; bout = nullptr; throw new Impl_CmdException("文件创建失败", "指定宏记录文件创建失败:" + path); } tout = new QTextStream(bout); tout->setCodec("UTF-8"); } } CommandsDispatcher::~CommandsDispatcher() { if(tout){ tout->flush(); delete tout; } if(bout){ bout->flush(); bout->close(); delete bout; } } void CommandsDispatcher::execute_script(const QString &filepath) { throw new Impl_CmdException("执行过程错误", "未实现函数:execute_script"); } void CommandsDispatcher::registerMember(AccessibleObject *obj) { if(object_instances.contains(obj->name())) throw new Impl_CmdException("参数错误", "重复注册命名对象"); object_instances[obj->name()] = obj; } void CommandsDispatcher::registerCommand(GeCommand *type) { if(command_types.contains(type->name())) throw new Impl_CmdException("参数错误", "重复注册该命名命令:" + type->name()); command_types[type->name()] = type; } QList CommandsDispatcher::listCommands() const { return command_types.values(); } void CommandsDispatcher::postCommand(const GeCommand &c) { if(!command_types.contains(c.name())) throw new Impl_CmdException("参数错误", "指定的命令类型未注册:" + c.name()); if(record_execute) *tout << QString("[%1]%2#").arg(QDateTime::currentDateTime().msecsTo(start_time)).arg(c.name()) << c.toText() << endl; try{ c.run(this); }catch(...){ *tout << QString("<<<<<< 该命令执行过程中出现异常 >>>>>>") << endl; tout->flush(); throw; } } void CommandsDispatcher::postCommandText(const QString &line) { auto split_index = line.indexOf("#"); auto name = line.mid(0, split_index).trimmed(); if(!command_types.contains(name)) throw new Impl_CmdException("参数错误", "指定的命令类型未注册:" + name); auto content = line.mid(split_index+1); auto ins = command_types[name]; ins->fromText(content); postCommand(*ins); }