QtNovelUI/GenericConsole/commandsdispatcher.h

156 lines
3.8 KiB
C++

#ifndef COMMANDLIST_H
#define COMMANDLIST_H
#include "GenericConsole_global.h"
#include <QDateTime>
#include <QDir>
#include <QHash>
#include <QString>
#include <QTextStream>
namespace Schedule {
class CommandsDispatcher;
/**
* @brief 命令执行相关Exception
*/
class CmdException : public std::exception
{
public:
virtual ~CmdException() = default;
/**
* @brief 类型名称
* @return
*/
virtual QString type() const = 0;
/**
* @brief 详细内容
* @return
*/
virtual QString reason() const = 0;
};
/**
* @brief 通用命令接口
*/
class GeCommand
{
public:
virtual ~GeCommand() = default;
/**
* @brief 命令名称,全局唯一标识名称
* @return
*/
virtual QString name() const = 0;
/**
* @brief 执行命令逻辑
* @param core 核心实例
*/
virtual void run(CommandsDispatcher *core) const = 0;
/**
* @brief 转换成文本
* @return
*/
virtual QString toText() const = 0;
/**
* @brief 从文本还原
* @param line
* @throw CmdException
*/
virtual void fromText(const QString &line) = 0;
};
/**
* @brief 派发核心内可以访问的对象抽象接口
*/
class AccessibleObject
{
public:
virtual ~AccessibleObject() = default;
virtual QString name() const = 0;
};
/**
* @brief 命令派发中心,负责命令的执行、记录、集中执行
*/
class GENERICCONSOLE_EXPORT CommandsDispatcher
{
private:
QDateTime start_time;
bool record_execute;
QHash<QString, GeCommand*> command_types;
QHash<QString, AccessibleObject*> object_instances;
QFile * bout;
QTextStream * tout;
public:
/**
* @brief 创建调度中心
* @param script_out 脚本输出文件夹,方便调试使用
* @param record 是否记录脚本
*/
CommandsDispatcher(const QDir &script_out, bool record = false);
virtual ~CommandsDispatcher();
/**
* @brief 执行命令脚本
* @param filepath 脚本磁盘路径
*/
virtual void execute_script(const QString &filepath);
// 获取成员 =========================================================
/**
* @brief 注册可以被外部访问的对象实例
* @param obj
*/
virtual void registerMember(AccessibleObject *obj);
/**
* 获取已经注册在内部的对象实例
*/
template<class T>
T *get(const QString &name)
{
if(!object_instances.contains(name))
return nullptr;
return static_cast<T*>(object_instances[name]);
}
// 命令的注册和执行 ==================================
/**
* @brief 注册命令类型
* @param type
*/
virtual void registerCommand(GeCommand* type);
/**
* @brief 罗列内部注册的所有命令
* @return
*/
virtual QList<GeCommand*> listCommands() const;
/**
* @brief 接收命令并执行,不接收内存管理责任,调用者自行管理命令内存
* @param c 命令实体
*/
virtual void postCommand(const GeCommand &c);
/**
* @brief 接收文本形势的命令并执行,主要应用对象是控制台
* @param line 一行命令文本,包含命令名称,作用对象和作用参数
* @throw CmdException
*/
virtual void postCommandText(const QString &line);
};
}
#endif // COMMANDLIST_H