From d6680e3f119745a5391120e363f009c690130b3f Mon Sep 17 00:00:00 2001 From: wingsummer <1326224942@qq.com> Date: Wed, 9 Apr 2025 13:59:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=84=9A=E6=9C=AC=E5=BC=95=E6=93=8E?= =?UTF-8?q?=E5=8D=95=E4=BE=8B=E5=8C=96=EF=BC=9B=E6=9B=B4=E5=90=88=E7=90=86?= =?UTF-8?q?=E7=9A=84=E6=A0=BC=E5=BC=8F=E5=8C=96=E5=8F=82=E6=95=B0=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3rdparty/QJsonModel/CMakeLists.txt | 1 - 3rdparty/cpptrace | 2 +- CMakeLists.txt | 6 +- lang/zh_CN/winghex_zh_CN.ts | 1668 ++++++++++++++-------------- lang/zh_TW/winghex_zh_TW.ts | 1668 ++++++++++++++-------------- src/class/asbuilder.cpp | 25 +- src/class/asbuilder.h | 15 +- src/class/ascompletion.cpp | 15 +- src/class/ascompletion.h | 3 +- src/class/asconsolecompletion.cpp | 5 +- src/class/asconsolecompletion.h | 2 +- src/class/ascontextmgr.cpp | 21 +- src/class/ascontextmgr.h | 2 +- src/class/asdebugger.cpp | 8 + src/class/asdebugger.h | 1 + src/class/clangformatmanager.cpp | 2 +- src/class/pluginsystem.cpp | 3 + src/class/scriptconsolemachine.cpp | 157 --- src/class/scriptconsolemachine.h | 50 - src/class/scriptmachine.cpp | 456 +++++--- src/class/scriptmachine.h | 77 +- src/class/scriptmanager.cpp | 28 +- src/class/scriptmanager.h | 5 - src/class/wingangelapi.cpp | 55 +- src/class/wingangelapi.h | 7 - src/control/scripteditor.cpp | 4 +- src/control/scripteditor.h | 2 +- src/control/scriptingconsole.cpp | 183 ++- src/control/scriptingconsole.h | 17 +- src/define.h | 2 + src/dialog/mainwindow.cpp | 159 ++- src/dialog/mainwindow.h | 14 +- src/dialog/scriptingdialog.cpp | 93 +- src/model/scriptobjmodel.cpp | 119 -- src/model/scriptobjmodel.h | 56 - 35 files changed, 2333 insertions(+), 2598 deletions(-) delete mode 100644 src/class/scriptconsolemachine.cpp delete mode 100644 src/class/scriptconsolemachine.h delete mode 100644 src/model/scriptobjmodel.cpp delete mode 100644 src/model/scriptobjmodel.h diff --git a/3rdparty/QJsonModel/CMakeLists.txt b/3rdparty/QJsonModel/CMakeLists.txt index 46d8665..c655342 100644 --- a/3rdparty/QJsonModel/CMakeLists.txt +++ b/3rdparty/QJsonModel/CMakeLists.txt @@ -15,7 +15,6 @@ find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) if(MSVC) string(APPEND CMAKE_CXX_FLAGS " /utf-8") string(APPEND CMAKE_C_FLAGS " /utf-8") - add_definitions(-D_CRT_SECURE_NO_WARNINGS) endif() include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) diff --git a/3rdparty/cpptrace b/3rdparty/cpptrace index fac4d08..ce639eb 160000 --- a/3rdparty/cpptrace +++ b/3rdparty/cpptrace @@ -1 +1 @@ -Subproject commit fac4d08fd0473a94d99c143c6ba6b1f9e0bd7636 +Subproject commit ce639ebfcec47a7c74233b4bab50017cb34e615b diff --git a/CMakeLists.txt b/CMakeLists.txt index e636ff5..4dd9a42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ option(WINGHEX_USE_FRAMELESS "Use borderless windows to ensure UI uniformity" if(WIN32) find_package(QT NAMES Qt6 Qt5 REQUIRED AxContainer) find_package(Qt${QT_VERSION_MAJOR} REQUIRED AxContainer) - add_definitions(-DNOMINMAX -D_CRT_SECURE_NO_WARNINGS) + add_definitions(-DNOMINMAX) endif() if(${QT_VERSION_MAJOR} EQUAL 5) @@ -239,8 +239,6 @@ set(CLASS_SRC src/class/settingmanager.cpp src/class/asdebugger.h src/class/asdebugger.cpp - src/class/scriptconsolemachine.h - src/class/scriptconsolemachine.cpp src/class/angelobjstring.h src/class/angelobjstring.cpp src/class/scripteditortheme.h @@ -319,8 +317,6 @@ set(MODEL_SRC src/model/checksummodel.cpp src/model/qjsontablemodel.h src/model/qjsontablemodel.cpp - src/model/scriptobjmodel.h - src/model/scriptobjmodel.cpp src/model/dbgcallstackmodel.h src/model/dbgcallstackmodel.cpp src/model/dbgvarshowmodel.h diff --git a/lang/zh_CN/winghex_zh_CN.ts b/lang/zh_CN/winghex_zh_CN.ts index 7f6ba1e..d3cbe3c 100644 --- a/lang/zh_CN/winghex_zh_CN.ts +++ b/lang/zh_CN/winghex_zh_CN.ts @@ -865,18 +865,18 @@ MainWindow - + File 文件 - - + + View 视图 - + About 关于 @@ -897,347 +897,347 @@ 选长: - + Edit 编辑 - + Script 脚本 - - - + + + Plugin 插件 - + Setting 设置 - - + + Log 日志 - + ExportFindResult 导出搜索结果 - + ClearFindResult 清空记录 - - + + FindResult 搜索结果 - - - - - - - + + + + + + + Copy 复制 - - - - - - - - + + + + + + + + CopyToClipBoard 数据已拷贝到粘贴板 - + LittleEndian 小端 - + BigEndian 大端 - + Number 数值 - - + + CheckSum 校验和 - - + + DeleteBookMark 删除书签 - - + + ClearBookMark 清空书签 - - - - + + + + BookMark 书签 - - + + DecodeText 解码字符串 - + ScriptConsole 脚本控制台 - - + + DVList 可视化列表 - - + + DVTree 可视化树数据 - - + + DVTable 可视化表格 - - + + DVText 可视化文本 - - + + Basic 基础 - + New 新建 - + OpenF 打开文件 - + OpenWorkSpace 打开工作区 - + RecentFiles 最近打开 - + Reload 重新加载 - - + + Save 保存 - + SaveAs 另存为 - + ConvertWS 转为工作区 - + Export 导出 - + SaveSel 保存选区字节 - - - - + + + + General 基本 - + Undo 撤销 - + Redo 恢复 - + Cut 剪切 - + Paste 粘贴 - + Delete 删除 - + Clone 克隆 - + Lookup 查询 - + Find 查找 - + Goto 跳转 - - + + Encoding 编码 - + FileInfo 文件信息 - - + + Hex 十六进制 - + CutHex 剪切(十六进制) - + CopyHex 复制(十六进制) - + PasteHex 粘贴(十六进制) - - + + Fill 填充 - + FillZero 填充零 - - - - - + + + + + MetaData 标注 - + DeleteMetadata 删除标注 - + ClearMetadata 清空标注 - + MetaDataEdit 编辑标注 - + DeleteMetaData 删除标注 - + ClearMetaData 清空标注 - + Display 显示 - + ViewText 文本预览 - + Scale 缩放 @@ -1272,797 +1272,812 @@ 加载插件中: - + SetupConsole 启动脚本控制台 - + SetupScriptManager 启动脚本管理器 - + SetupScriptService 启动脚本服务 - + SetupScriptEditor 构建脚本编辑器 - + SetupSetDialog 构建设置窗体 - + SetupPlgWidgets 启动插件组件 - + SetupDockingLayout 恢复 Dock 布局 - + SetupWaiting 启动即将完成 - + SetupFinished 启动完毕 - + NoExtension 无扩展 - - - - - - + + + + + + ExportResult 导出结果 - - - + + + NothingToSave 没有保存的数据 - - - - + + + + ClearResult 清空结果 - + OpenExt 打开 - 拓展 - + ResetScale 重置缩放 - + ShowMetafg 标注前景色 - + ShowMetabg 标注背景色 - + ShowMetaComment 批注 - + MetaShowAll 显示所有标注 - + MetaHideAll 隐藏所有标注 - + FileStatus 文件状态 - + InfoSave 是否保存 - + ReadOnly 可读写 - + SetLocked 启用/禁用锁定编辑 - + ErrUnLock 锁定编辑失败 - + SetOver 启用/禁用改变大小 - + UnsignedHex 无符号 Hex - + + BgScriptOutput + 后台脚本输出 + + + ErrUnOver 锁定文件大小失败 - + Window 窗体 - + Editor 编辑器 - + Tools 工具 - + HexEditorLayout 编辑器布局 - + SetBaseAddr 设置基址 - + addressBase 基址 - + inputAddressBase 请输入基址 - + WarnBigBaseAddress 基址过大,你得到的地址将会不正确! - + ErrBaseAddress 非法基址输入 - + SetColInfo 显示/隐藏地址栏 - + SetHeaderInfo 显示/隐藏表头 - + SetAsciiString 显示/隐藏解码字符串 - + Layout 布局 - + Fullscreen 全屏 - + Default 默认 - - - + + + LayoutRestoring... 恢复布局中... - + RestoreLayout 恢复布局 - - + + SaveLayout 保存布局 - + ExportLog 导出日志 - + ClearLog 清空日志 - + InsepctQt 监视 Qt - + ScriptEditor 脚本编辑器 - + Scripts 脚本仓库 - + PluginFunctions 插件功能 - + ScriptSetting 脚本设置 - + PluginSettings 插件设置 - + Info 信息 - + Software 软件 - + Sponsor 赞助 - + CheckUpdate 检查更新 - + Wiki 网页 Wiki - + AboutQT 关于 QT - + SetPageIDEmptyTryUseName 设置页 ID 为空,尝试使用名称作为 ID - + SetPageDupNameIgnored 设置页重复的 ID 名称,已忽略加载 - + Plugin %1 contains a duplicate ID (%2) that is already registered by plugin %3 插件 %1 包含重复 ID (%2),该 ID 已被插件 %3 注册 - - + + ChooseFile 选择文件 - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + Error 错误 - - + + FileNotExist 文件不存在! - - - - - - - - + + + + + + + + FilePermission 因文件权限无法继续! - + ProjectFile (*.wingpro) 项目文件 (*.wingpro) - + ReloadSuccessfully 文件重新加载成功! - + ReloadUnSuccessfully 文件重新加载失败! - - - - - - - + + + + + + + ChooseSaveFile 请选择保存文件路径: - + NoMoreClone 克隆已到上限,无法继续操作! - + FindFininishBusy 查找任务繁忙,请勿重复查找! - + MayTooMuchFindResult 搜索数量已到达上限,结果可能不全,建议请按区段搜索。 - + SaveLayoutSuccess 保存布局成功 - + SaveLayoutError 保存布局失败 - + HasClonedView 该编辑页已被克隆编辑,如果关闭,相关联的页也会被关闭,你确认继续吗? - + SaveWorkSpace 保存工作区 - + WingHexWorkSpace (*.wingpro) 羽云十六进制工作区 (*.wingpro) - + ConfirmSave 正在关闭未保存的文件或工作区,你确定保存吗? - + + [Info] + 【信息】 + + + + [Warn] + 【警告】 + + + + [Error] + 【错误】 + + + Column %1 列 %1 - + ConfirmAPPSave 你尝试关闭程序,但仍存在未保存的文件或工作区,你确定保存这些更改吗? - - - - - - + + + + + + SaveSuccessfully 保存成功! - - + + SaveWSError 保存工作区错误! - - + + Warn 警告 - - ScriptObjShow - 脚本对象 - - - + Opening... 打开文件中... - + WorkSpaceOpening... 打开工作区中... - + Reloading... 重载文件中... - + Saving... 保存中... - + SaveNewFirst 请首先保存新建的文件 - + AlreadyWorkSpace 已经是工作区,无需转化 - + ConvWorkSpaceFailed 转化为工作区失败 - + ConvWorkSpaceSuccess 转化为工作区成功 - + SavingAs... 另存为中... - + SaveUnSuccessfully 保存失败! - + Exporting... 导出中... - + ChooseExportFile 请选择导出文件路径: - + ExportSuccessfully 导出成功! - + ExportUnSuccessfully 导出失败! - + SavingSel... 保存选中字节中... - + SaveSelSuccess 保存选区字节成功! - + SaveSelError 保存选区字节失败,因文件不具有可写权限! - - + + CutToClipBoard 数据已剪切到粘贴板! - - + + UnCutToClipBoard 由于保持大小限制,数据剪切到粘贴板失败! - - + + UnCopyToClipBoard 由于保持大小限制,数据剪切到复制板失败! - - + + Finding... 查找中... - + DeleteSuccess 删除成功 - + DeleteFailed 删除失败 - + FindFininish 查找结果完毕! - + PleaseInputFill 请输入填充字节值 - + FillInputTruncWarn 填充输入数值过大,将会被截断填充 - + FillInputError 填充字节输入错误 - - + + InputComment 请输入批注: - - + + BookmarkDelSuccess 删除书签成功 - + BookmarkDelNoItem 无书签可删除 - + BookmarkClearSuccess 书签清空完毕 - - - + + + NoSelection 没有选区,无法继续的操作! - + NoMetaData 无可编辑标记 - + PleaseClearSel 请清空选择 - + MetaDelSuccess 元数据删除成功 - + MetaDelNoItem 无元数据可删除 - + MetaClearSuccess 元数据清空完毕 - + FindResultExporting... 查找结果导出中... - - + + EmptyFindResult 没有可导出的搜索结果! - + SaveFindResult 导出搜索结果成功! - + SaveFindResultError 导出结果失败! - + TooManyBytesDecode 超出解码字节限制…… - + NoTextFileMayInvalid 该文件不是文本文件,以文本方式预览并不是一个好的方式,你确认继续吗? - + LayoutSaving... 布局保存中... - + PleaseInput 请输入 - + LogExporting... 日志导出中... - + ExportLogError 导出日志失败! - + ExportLogSuccess 导出日志成功,路径: - + ClearLogSuccess 清空日志成功! - + BadNetwork 无法与远程服务器的更新检查建立连接,请检查网络。 - + NewestVersion 当前软件为最新版本 - - + + OlderVersion 你使用的软件为老版本,建议到 Github 和 Gitee 的仓库发行版下载更新。 - + CheckingUpdate 检查更新中…… - + Too much opened files 打开的文件过多,无法继续操作! - + FilePermissionSure2Quit 因文件权限无法保存,你确认要退出吗? - + UnknownErrorSure2Quit 因未知错误无法保存,你确认要退出吗? - + WorkSpaceUnSavedSure2Quit 工作区文件无法保存,你确认要退出吗? - + CopyLimit 拷贝字节超出限制 - + ErrOpenFileBelow 打开文件出现错误(由于权限不足),如下为打开错误的文件: @@ -2293,200 +2308,200 @@ PluginSystem - + LoadingPlugin 加载插件中: - + InvalidPluginBrokenInfo 加载插件失败:损坏的插件数据 - + AppClosingCanceled: 程序关闭被取消: - + - PluginID: - 插件 ID: - + FoundDrvPluginCount 总计发现设备拓展插件数目: - + RegisterScriptFnUnSupportedTypes: 因脚本函数含有未支持的类型而注册失败: - - + + RegisterScriptFnInvalidSig: 因脚本函数签名非法而注册失败: - - + + RegisterScriptFnConflitSig: 因脚本函数签名冲突而注册失败: - + InvalidEnumName: 非法枚举名: - + InvalidEnumValue: 非法枚举值: - + InvalidMarcosRegister: 非法宏注册: - + ErrLoadPluginSDKVersion 插件加载失败:非法插件 SDK 版本! - + ErrLoadPluginNoName 插件加载失败:非法插件名称! - + ErrLoadInitPlugin 插件加载失败:初始化插件失败! - + PluginName : 插件名: - + PluginAuthor : 插件作者: - + PluginWidgetRegister 注册插件对象中…… - + ErrLoadExtPluginSDKVersion 设备拓展插件加载失败:非法插件 SDK 版本! - + ExtPluginAuthor : 设备拓展插件作者: - + ExtPluginWidgetRegister 设备拓展注册插件对象中…… - + ErrLoadInitExtPlugin 设备拓展插件加载失败:初始化插件失败! - + ChooseFile 选择文件 - - + + Error 错误 - + FileNotExist 文件不存在! - + FilePermission 因文件权限无法继续! - + EmptyNameDockWidget: 空的贴边组件名: - + InvalidNameDockWidget: 无效贴边组件名: - + InvalidNullDockWidget: 无效空贴边组件: - + Not allowed operation in non-UI thread 该操作在非 UI 线程非法 - + UnsafePluginDir 不安全的插件目录,请将插件目录设置为仅管理员账户可写 - + [EvilCall] 【非法调用】 - + InvalidPluginID 加载插件失败:非法插件标识符 - + InvalidDupPlugin 加载插件失败:重复的插件标识符 - + FoundPluginCount 总计发现插件数目: - + PluginLoadingFailedSummary 有依赖插件加载失败总结 - + - Dependencies: - 依赖: - + PUID: 插件唯一标志符: - + Version: 版本: - + PluginLoadingFinished 加载插件完毕! @@ -2798,1603 +2813,1575 @@ - - ScriptConsoleMachine - - - EmptyDecl - 空声明 - - - - Application functions: - 程序函数: - - - - User functions: - 用户函数: - - - - Application variables: - 程序变量: - - - - User variables: - 用户变量: - - ScriptMachine - + AngelScript callstack: AngelScript 调用堆栈: - + - Exception '%1' in '%2' — 在 ‘%2’ 中发生异常 ‘%1’ - + ExecNotAllowedInRoot 在管理员权限执行第三方命令为非法操作 - - - + + + Script failed to build 脚本编译失败 - - + + Cannot find 'int main()' or 'void main()' 无法找到程序入口点: "int main()" 或者 "void main()" - + Debugging, waiting for commands. 调试中,等待调试命令。 - + Failed while initializing global variables 初始化全局变量失败 - - + + The script failed with an exception 异常被抛出,脚本执行失败 - - + + The script was aborted 脚本被终止 - - + + The script terminated unexpectedly 脚本异常退出 - + The script exited with 脚本退出返回值: - + '%1' is already declared "%1" 已被声明 - + Abstract class '%1' cannot be instantiated 无法实例化抽象类 "%1" - + Accessing private property '%1' of parent class 非法访问父类的私有属性 "%1" - + Attribute '%1' informed multiple times 属性 "%1" 已被多次通知 - + Can't form arrays of subtype '%1' 无法创建子类型 "%1" 的数组 - + Can't inherit from class '%1' marked as final 无法从标记为 final 的类 "%1" 继承 - + Cannot access non-static member '%1' like this 无法和像使用 this 一样访问非静态成员 "%1" - + Can't construct handle '%1'. Use ref cast instead 无法构造句柄 "%1" 。请改用引用强制转换 - + Can't implicitly convert from '%1' to '%2'. 无法从 "%1' 隐式转换为 "%2"。 - + Compiling %1 正在编译 %1 - + Compiling auto generated %1 编译自动生成的 %1 - + Implemented property accessor '%1' does not expect index argument 已实现的属性访问器 "%1" 不需要索引参数 - + Implemented property accessor '%1' expects index argument 已实现的属性访问器 "%1" 需要索引参数 - + Data type can't be '%1' 数据类型不能为 "%1" - + All subsequent parameters after the first default value must have default values in function '%1' 在函数 "%1" 中,第一个默认值之后的所有后续参数都必须具有默认值 - + The method in the derived class must have the same return type as in the base class: '%1' 派生类中的方法必须具有与基类相同的返回类型:"%1" - + The name of the destructor '%1::~%2' must be the same as the class 析构函数 "%1::~%2" 的名称必须与类相同 - + Expected '%1' 应为 "%1" - + Expected '%1' or '%2' 应为 ”%1“ 或 ”%2“ - + Expression must be of boolean type, instead found '%1' 表达式必须是布尔类型,但实际使用的是 "%1" - + Expression '%1' is a data type 表达式 "%1" 是一种数据类型 - + External shared entity '%1' not found 未找到外部共享实体 "%1" - + External shared entity '%1' cannot redefine the original entity 外部共享实体 "%1" 无法重新定义原始实体 - + Failed while compiling default arg for parameter %1 in function '%2' 为函数 "%2" 中的参数 %1 编译默认参数时失败 - + Function '%1' not found 未找到函数 "%1" - + The property '%1' has mismatching types for the get and set accessors 属性 "%1" 的 get 和 set 访问器类型不匹配 - + Variable '%1' hides another variable of same name in outer scope 变量 "%1" 隐藏了外部作用域中另一个同名变量 - + Identifier '%1' is not a data type 标识符 "%1" 不是数据类型 - + Identifier '%1' is not a data type in global namespace 标识符 "%1" 不是全局命名空间中的数据类型 - + Identifier '%1' is not a data type in namespace '%2' or parent 标识符 "%1" 不是命名空间 "%2" 或其父级中的数据类型 - + Illegal operation on '%1' 对 "%1" 的非法操作 - + Illegal variable name '%1'. 非法变量名 "%1"。 - + Illegal access to inherited private property '%1' 非法访问继承的私有属性 "%1" - + Initialization lists cannot be used with '%1' 初始化列表不能与 "%1" 一起使用 - + Attempting to instantiate invalid template type '%1<%2>' 尝试实例化无效的模板类型 "%1<%2>" - + Instead found '%1' 而是找到了 "%1" - + Instead found identifier '%1' 而是找到标识符 "%1" - + Instead found reserved keyword '%1' 而是找到了保留关键字 "%1" - + Interface '%1' cannot be instantiated 无法实例化接口 "%1" - + Invalid unicode escape sequence, expected %1 hex digits 无效的 Unicode 转义序列,预期为 %1 个十六进制数字 - + Method '%1' declared as final and cannot be overridden 方法 "%1" 已声明为 final,因此无法被覆盖 - + Method '%1' marked as override but does not replace any base class or interface method 方法 "%1" 标记为覆盖,但并未替换任何基类或接口方法 - + Method '%1::%2' is missing the return type, nor is it the same name as object to be a constructor 方法 "%1::%2" 缺少返回类型,并且其名称与构造函数对象不同 - + Method '%1' is not part of object '%2' 方法 "%1" 不是对象 "%2" 的一部分 - + Missing implementation of '%1' 缺少 "%1" 的实现 - + Missing definition of '%1' 缺少 "%1" 的定义 - + Mixin class cannot be declared as '%1' Mixin 类不能声明为 "%1" - + Multiple matching signatures to '%1' "%1" 有多个匹配的签名 - + Found multiple get accessors for property '%1' 发现属性 "%1" 的多个 get 访问器 - + Found multiple set accessors for property '%1' 发现属性 "%1" 的多个集合访问器 - + Namespace '%1' doesn't exist. 命名空间 "%1" 不存在。 - - - - - - - - - - - - + + + + + + + + + + + + Name conflict. 名称冲突。 - + '%1' is an extended data type. "%1" 是扩展数据类型。 - + '%1' is a global property. "%1" 是全局属性。 - + '%1' is a named type. "%1" 是被命名的类型。 - + '%1' is a funcdef. "%1" 是一个函数签名定义。 - + '%1' is a global function. "%1" 是一个全局函数。 - + '%1' is a mixin class. "%1" 是一个 Mixin 类。 - + '%1' is a virtual property. "%1" 是虚拟属性。 - + '%1' is a class. "%1" 是一个类。 - + '%1' is an interface. "%1" 是一个接口。 - + '%1' is an object property. "%1" 是一个对象属性。 - + '%1' is a class method. "%1" 是一个类方法。 - + '%1' is already used. ”%1“ 已被使用。 - + No appropriate opHndlAssign method found in '%1' for handle assignment 在 "%1" 中未找到适当的 opHndlAssign 方法用于句柄分配 - + No conversion from '%1' to '%2' available. 无法进行从 "%1" 到 "%2" 的转换。 - + No conversion from '%1' to math type available. 无法将 "%1" 转换为数学类型。 - + No default constructor for object of type '%1'. "%1" 类型对象没有默认构造函数。 - + No appropriate opAssign method found in '%1' for value assignment 在 "%1" 中未找到适合赋值的 opAssign 方法 - + No copy constructor for object of type '%1'. 没有 "%1" 类型对象的复制构造函数。 - + No matching signatures to '%1' 没有与 "%1" 匹配的签名 - + No matching operator that takes the type '%1' found 未找到采用类型 "%1" 的匹配运算符 - + No matching operator that takes the types '%1' and '%2' found 未找到采用类型 "%1" 和 "%2" 的匹配运算符 - + No matching symbol '%1' 没有匹配的符号 "%1" - + Expression doesn't form a function call. '%1' evaluates to the non-function type '%2' 表达式不构成函数调用。"%1" 计算结果为非函数类型 "%2" - + '%1' is not declared "%1" 未被声明 - + '%1' is not initialized. ”%1“ 未初始化。 - + '%1' is not a member of '%2' ”%1“ 不是 ”%2“ 的成员 - + Type '%1' doesn't support the indexing operator 类型 "%1" 不支持索引运算符 - + Parameter type can't be '%1', because the type cannot be instantiated. 参数类型不能是 "%1",因为该类型无法实例化。 - + Previous error occurred while attempting to compile initialization list for type '%1' 尝试编译类型 "%1" 的初始化列表时发生先前的错误 - + Illegal call to private method '%1' 非法调用私有方法 "%1" - + Illegal access to private property '%1' 非法访问私有属性 "%1" - + Illegal call to protected method '%1' 非法调用受保护的方法 "%1" - + Illegal access to protected property '%1' 非法访问受保护的属性 "%1" - + Return type can't be '%1' 返回类型不能是 "%1" - + Shared code cannot access non-shared global variable '%1' 共享代码无法访问非共享全局变量 "%1" - + Shared code cannot call non-shared function '%1' 共享代码无法调用非共享函数 "%1" - + Shared type cannot implement non-shared interface '%1' 共享类型无法实现非共享接口 "%1" - + Shared class cannot inherit from non-shared class '%1' 共享类不能从非共享类 "%1" 继承 - + Shared code cannot use non-shared type '%1' 共享代码不能使用非共享类型 "%1" - + Shared type '%1' doesn't match the original declaration in other module 共享类型 "%1" 与其他模块中的原始声明不匹配 - + Template '%1' expects %2 sub type(s) 模板 "%1" 需要 %2 个子类型 - + Type '%1' cannot be a reference 类型 "%1" 不能是引用 - + Type '%1' is not available for this module 类型 "%1" 不适用于此模块 - + Type '%1' is not a template type 类型 "%1" 不是模板类型 - + Unexpected token '%1' 意外标记 "%1" - + Use of uninitialized global variable '%1'. 使用未初始化的全局变量 "%1"。 - + Unknown scope '%1' 未知作用域 "%1" - + Where '%1' is '%2' 其中 "%1" 是 "%2" - + Failed to initialize global variable '%1' 无法初始化全局变量 "%1" - + Exception '%1' in '%2' "%2" 中的异常 "%1" - + Type '%1' is missing behaviours 类型 "%1" 缺少的行为 - + Can't pass type '%1' by value unless the application type is informed in the registration 除非在注册时告知应用程序类型,否则无法按值传递类型 "%1" - + Can't return type '%1' by value unless the application type is informed in the registration 除非在注册时告知应用程序类型,否则无法按值返回类型 "%1" - + Don't support passing type '%1' by value to application in native calling convention on this platform 不支持在此平台上按照本机调用约定将类型 "%1" 按值传递给应用程序 - + Don't support returning type '%1' by value from application in native calling convention on this platform 不支持在此平台上按照本机调用约定从应用程序返回类型 "%1" 的值 - + Object {%1}. GC cannot destroy an object of type '%2' as it doesn't know how many references to there are. 对象 {%1}。GC 无法销毁类型为 "%2" 的对象,因为它不知道有多少个引用。 - + Object {%1}. GC cannot destroy an object of type '%2' as it can't see all references. Current ref count is %3. 对象 {%1}。GC 无法销毁类型为 "%2" 的对象,因为它无法看到所有引用。当前引用计数为 %3。 - + Object type '%1' doesn't exist 对象类型 "%1" 不存在 - + Cannot register. The template type instance '%1' has already been generated. 无法注册。模板类型实例 "%1" 已生成。 - + Template type '%1' doesn't exist 模板类型 "%1" 不存在 - + Template subtype '%1' doesn't exist 模板子类型 "%1" 不存在 - + Failed to read subtype of template type '%1' 无法读取模板类型 "%1" 的子类型 - + Failed in call to function '%1' (Code: %2, %3) 调用函数 "%1" 失败(代码:%2,%3) - + Failed in call to function '%1' with '%2' (Code: %3, %4) 使用 "%2" 调用函数 "%1" 失败(代码:%3,%4) - + Failed in call to function '%1' with '%2' and '%3' (Code: %4, %5) 使用 "%2" 和 "%3" 调用函数 "%1" 失败(代码:%4,%5) - + Type '%1' is still used by function '%2' 类型 "%1" 仍被函数 "%2" 使用 - + The builtin type in previous message is named '%1' 上一条消息中的内置类型名为 "%1" - + The function in previous message is named '%1'. The func type is %2 上一条消息中的函数名为 "%1"。函数类型为 %2 - + The script object of type '%1' is being resurrected illegally during destruction 类型为 "%1" 的脚本对象在销毁过程中被非法复活 - + LoadByteCode failed. The bytecode is invalid. Number of bytes read from stream: %1 LoadByteCode 失败。字节码无效。从流中读取的字节数:%1 - + Function '%1' appears to have been compiled without JIT entry points 函数 "%1" 似乎已在无 JIT 入口点的情况下进行编译 - + There is an external reference to an object in module '%1', preventing it from being deleted 存在对模块 "%1" 中对象的外部引用,导致无法删除该对象 - + Output argument expression is not assignable 输出参数表达式不可分配 - + Auto is not allowed here 这里禁止使用 auto 关键字 - + Can't find unambiguous implicit conversion to make both expressions have the same type 无法找到明确的隐式转换来使两个表达式具有相同的类型 - + Both conditions must call constructor 两个条件都必须调用构造函数 - + Base class doesn't have default constructor. Make explicit call to base constructor 基类没有默认构造函数。明确调用基类构造函数 - + Base class doesn't have copy constructor or default constructor and assign operator. Make explicit call to base constructor 基类没有复制构造函数或默认构造函数和赋值运算符。明确调用基类构造函数 - + Candidates are: 候选包括: - + Can't call a constructor in loops 无法在循环中调用构造函数 - + Can't call a constructor in switch 无法在 switch 中调用构造函数 - + Can't call a constructor multiple times 无法多次调用构造函数 - + Can't create delegate 无法创建委托 - + Can't create delegate for types that do not support handles 无法为不支持句柄的类型创建委托 - + Cannot flag function that will not be auto generated as deleted 无法将不会自动生成的函数标记为已删除 - + Conflict with explicit declaration of function and deleted function 与函数的显式声明和已删除函数冲突 - + Can't implement itself, or another interface that implements this interface 无法实现自身,也无法实现此接口的其他接口 - + Can't inherit from multiple classes 不能从多个类继承 - + Can't inherit from itself, or another class that inherits from this class 不能从其自身或从该类继承的其他类继承 - + Can't pass class method as arg directly. Use a delegate object instead 无法直接将类方法作为参数传递。请改用委托对象 - + Unable to resolve auto type 无法解析自动类型 - + Can't return reference to local value. 无法返回对本地值的引用。 - + Can't return value when return type is 'void' 返回类型为 "void" 时无法返回值 - + Implicit conversion changed sign of value 隐式转换改变了值的符号 - + A class cannot be both abstract and final 一个类不能同时是 abstract 和 final - + Compound assignments with property accessors on value types are not supported 不支持对值类型使用属性访问器的复合赋值 - + Compound assignments with indexed property accessors are not supported 不支持使用索引属性访问器的复合赋值 - + Compound assignments with property accessors require both get and set accessors 具有属性访问器的复合赋值需要 get 和 set 访问器 - + Variables cannot be declared in switch cases, except inside statement blocks 变量不能在 switch 语句中声明,除非在语句块内 - + The default case must be the last one default 情况必须是最后一个 - + The type of the default argument expression doesn't match the function parameter type 默认参数表达式的类型与函数参数类型不匹配 - + Deleted functions cannot have implementation 已删除的函数不能有实现 - + The destructor must not have any parameters 析构函数不能有任何参数 - + Value assignment on reference types is not allowed. Did you mean to do a handle assignment? 不允许对引用类型进行值分配。是要进行句柄分配吗? - + Compound assignment on reference types is not allowed 不允许对引用类型进行复合赋值 - + Duplicate named argument 重复命名参数 - + Duplicate switch case 重复的 switch case - + Else with empty statement else 中使用空语句 - + Empty list element is not allowed 不允许空列表元素 - + Empty switch statement 空的 switch 语句 - + Expected constant 应为常量 - + Expected data type 应为数据类型 - + Expected expression value 应为表达值 - + Expected identifier 应为标识符 - + Expected a list enclosed by { } to match pattern 应为用 { } 括起来的列表与模式匹配 - + Expected method or property 应为方法或属性 - + Expected one of: 应为为以下之一: - + Expected operator 应为操作符 - + Expected post operator 应为右操作符 - + Expected pre operator 应为左操作符 - + Expected string 应为字符串 - + Expression doesn't evaluate to a function 表达式无法计算函数值 - + Previous error occurred while attempting to create a temporary copy of object 尝试创建对象的临时副本时发生上一个错误 - + Float value truncated in implicit conversion to integer 浮点值在隐式转换为整数时被截断 - + Found multiple matching enum values 找到多个匹配的枚举值 - + A function with the same name and parameters already exists 具有相同名称和参数的函数已存在 - + Global variables have been disabled by the application 全局变量已被应用程序禁用 - + It is not allowed to perform a handle assignment on a non-handle property 不允许对非句柄属性执行句柄分配 - + The operand is implicitly converted to handle in order to compare them 操作数被隐式转换为句柄,以便进行比较 - + Handle to handle is not allowed 不允许使用句柄 - + If with empty statement 如果带有空语句 - + Illegal member type 非法成员类型 - + Illegal operation on this datatype 对该数据类型的非法操作 - + Illegal target type for reference cast 非法引用转换的目标类型 - + Interfaces can only implement other interfaces 接口只能实现其他接口 - + Invalid 'break' 无效的 break 关键字 - + Invalid character literal 无效的字符 - + Invalid 'continue' 无效的 continue 关键字 - + Invalid escape sequence 无效的转义序列 - + Invalid expression: ambiguous name 无效表达式:二义性名称 - + Invalid expression: stand-alone anonymous function 无效表达式:独立匿名函数 - + Invalid operation on method 方法操作无效 - + Invalid reference. Property accessors cannot be used in combined read/write operations 引用无效。属性访问器不能用于组合读/写操作。 - + Invalid scope resolution 范围解析无效 - + Invalid signature for virtual property 虚拟属性签名无效 - + Invalid type 类型无效 - + Invalid unicode code point 无效的 Unicode 代码点 - + Invalid unicode sequence in source 源代码中的 Unicode 序列无效 - + Invalid use of named arguments 命名参数的使用无效 - + The method cannot be named with the class name 该方法不能以类名命名 - + Mixin classes cannot have constructors or destructors Mixin 类不能有构造函数或析构函数 - + Mixin class cannot inherit from classes Mixin 类不能从类继承 - + Mixin classes cannot have child types Mixin 类不能有子类型 - + Found more than one matching operator 找到多个匹配的运算符 - + Multiline strings are not allowed in this application 此应用程序不允许使用多行字符串 - + Only objects have constructors 只有对象才有构造函数 - + Must return a value 必须返回一个值 - + Detected named argument with old syntax 检测到具有旧语法的命名参数 - + No appropriate indexing operator found 未找到合适的索引运算符 - + No appropriate opEquals method found 未找到合适的 opEquals 方法 - + The application doesn't support the default array type. 该应用程序不支持默认数组类型。 - + Non-const method call on read-only object reference 只读对象引用上的非常量方法调用 - + Non-terminated string literal 未终止的字符串 - + Not all paths return a value 并非所有路径都会返回值 - + Not enough values to match pattern 没有足够的值来模式匹配 - + Implicit conversion of value is not exact 值的隐式转换并不准确 - + Expression is not an l-value 表达式不是左值 - + Not a valid reference 无效引用 - + Not a valid lvalue 不是有效的左值 - + Nothing was built in the module 模块中没有构建任何内容 - + Object handle is not supported for this type 此类型不支持对象句柄 - + Only object types that support object handles can use &inout. Use &in or &out instead 只有支持对象句柄的对象类型才能使用 &inout。请改用 &in 或 &out - + A cast operator has one argument 强制类型转换运算符有一个参数 - + The code must contain one and only one function 代码必须包含一个且只能包含一个函数 - + The code must contain one and only one global variable 代码必须包含一个且只能有一个全局变量 - + Both operands must be handles when comparing identity 比较时,两个操作数都必须是句柄 - + The overloaded functions are identical on initial parameters without default arguments 重载函数在初始参数上相同,没有默认参数 - + Parameter already declared 参数已声明 - + Positional arguments cannot be passed after named arguments 位置参数不能在命名参数之后传递 - + Potentially matching non-const method is hidden on read-only object reference 可能匹配的非 const 方法隐藏在只读对象引用中 - + Property accessor with index must have 1 and only 1 index argument 带索引的属性访问器必须有 1 个且只能有 1 个索引参数 - + Property accessors have been disabled by the application 应用程序已禁用属性访问器 - + Property accessor must be implemented 必须实现属性访问器 - + Class properties cannot be declared as const 类属性不能声明为 const - + The property has no get accessor 该属性没有 get 访问器 - + The property has no set accessor 该属性没有设置访问器 - + Virtual property must have at least one get or set accessor 虚拟属性必须至少有一个 get 或 set 访问器 - + Resulting reference cannot be returned. Returned references must not refer to local variables. 无法返回结果引用。返回的引用不得引用局部变量。 - + Resulting reference cannot be returned. There are deferred arguments that may invalidate it. 无法返回结果引用。存在可能使其无效的延迟参数。 - + Resulting reference cannot be returned. The expression uses objects that during cleanup may invalidate it. 无法返回结果引用。表达式使用的对象在清理过程中可能会使其失效。 - + Reference is read-only 引用是只读的 - + Reference is temporary 参考是临时的 - + Reference types cannot be passed by value in function parameters 引用类型不能在函数参数中按值传递 - + Reference types cannot be returned by value from functions 引用类型不能通过函数返回值 - + The script section is empty 脚本节区为空 - + Signed/Unsigned mismatch 有符号/无符号不匹配 - + Strings are not recognized by the application 应用程序无法识别字符串 - + Case expressions must be literal constants case 表达式必须是文字常量 - + Switch expressions must be integral numbers switch 表达式必须是整数 - + The function has too many jump labels to handle. Split the function into smaller ones. 该函数的跳转标签过多,无法处理。请将函数拆分为较小的函数。 - + Too many values to match pattern 与模式匹配的值过多 - + Unexpected end of file 意外的文件结束 - + Unexpected variable declaration 意外的变量声明 - + Unreachable code 无法访问的代码 - + Virtual property contains unrecognized aspect 虚拟属性包含未被认可的部分 - + Unused script node 未使用的脚本节点 - + Value is too large for data type 对于数据类型来说,值太大 - + Void cannot be an operand in expressions void 不能作为表达式中的操作数 - + Warnings are treated as errors by the application 应用程序将警告视为错误 - + While parsing argument list 解析参数列表时 - + While parsing expression 解析表达式时 - + While parsing initialization list 解析初始化列表时 - + While parsing namespace 解析命名空间时 - + While parsing statement block 解析语句块时 - + Previous error occurred while including mixin 包含 mixin 时发生先前错误 - + Autohandles cannot be used with types that have been registered with NOCOUNT 自动句柄不能与已使用 NOCOUNT 注册的类型一起使用 - + First parameter to template factory must be a reference. This will be used to pass the object type of the template 模板工厂的第一个参数必须是引用。这将用于传递模板的对象类型 - + Invalid configuration. Verify the registered application interface. 配置无效。请验证已注册的应用程序接口。 - + A value type must be registered with a non-zero size 值类型必须注册为非零大小 - + The behaviour is not compatible with the type 行为与类型不兼容 - + A garbage collected ref type must have the addref, release, and all gc behaviours 垃圾收集引用类型必须具有 addref、release 和所有 gc 行为 - + A garbage collected value type must have the gc enum references behaviour 垃圾收集值类型必须具有 gc 枚举引用行为 - + A scoped reference type must have the release behaviour 作用域引用类型必须具有释放行为 - + A reference type must have the addref and release behaviours 引用类型必须具有 addref 和 release 行为 - + A non-pod value type must have at least one constructor and the destructor behaviours 非 pod 值类型必须至少有一个构造函数和析构函数行为 - + Template list factory expects two reference parameters. The last is the pointer to the initialization buffer 模板列表工厂需要两个引用参数。最后一个是指向初始化缓冲区的指针 - + List factory expects only one reference parameter. The pointer to the initialization buffer will be passed in this parameter 列表工厂仅需要一个引用参数。指向初始化缓冲区的指针将在此参数中传递 - + AddScriptObjectToGC called with null pointer 使用空指针调用 AddScriptObjectToGC - + An exception occurred in a nested call 嵌套调用中发生异常 - + Uh oh! The engine's reference count is increasing while it is being destroyed. Make sure references needed for clean-up are immediately released 哎呀!引擎的引用计数在被销毁时不断增加。确保立即释放清理所需的引用 - + The module is still in use and cannot be rebuilt. Discard it and request another module 该模块仍在使用中,无法重建。丢弃它并请求另一个模块 - + Property 属性 - + System function 系统函数 - + Variable declaration 变量声明 - + Stack overflow 栈溢出 - + Null pointer access 空指针访问 - + Divide by zero 除以零 - + Overflow in integer division 整数除法溢出 - + Overflow in exponent operation 指数运算溢出 - + Unrecognized byte code 无法识别的字节码 - + Invalid calling convention 无效调用约定 - + Unbound function called 未绑定的函数被调用 - + Out of range 越界 - + Caught an exception from the application 捕获应用程序异常 - + Mismatching types in value assignment 值分配中的类型不匹配 - + Too many nested calls 嵌套调用过多 - - + + Assert failed 断言失败 @@ -4402,38 +4389,15 @@ ScriptManager - + RunScript 执行脚本 - + CanNotRunUsrScriptForPolicy 由于限制策略,无法在 Root 模式下运行用户脚本! - - - Excuting: - 执行脚本: - - - - ScriptObjModel - - - Name - 名称 - - - - Type - 类型 - - - - Value - - ScriptSettingDialog @@ -4501,37 +4465,37 @@ ScriptingConsole - + [Info] 【信息】 - + [Warn] 【警告】 - + [Error] 【错误】 - + [Console] 【控制台】 - + Copy 复制 - + Cut 剪切 - + Paste 粘贴 @@ -4552,425 +4516,425 @@ ScriptingDialog - + ScriptEditor 脚本编辑器 - + ScriptPermissionDenied 因权限无法打开脚本 - + File 文件 - + Edit 编辑 - + Debugger 调试器 - + Setting 设置 - + About 关于 - + InvalidSourceFile 非法代码文件 - + Basic 基础 - + New 新建 - + OpenF 打开文件 - + RecentFiles 最近打开 - + Reload 重新加载 - - + + Save 保存 - + SaveAs 另存为 - + General 基本 - + Undo 撤销 - + Redo 恢复 - + Cut 剪切 - + Copy 复制 - + Paste 粘贴 - + Delete 删除 - + Lookup 查询 - + Find 查找 - + Replace 替换 - + Goto 跳转 - + Format 代码样式 - + CodeFormat 代码格式化 - + Window 窗体 - - + + Editor 编辑器 - + Tools 工具 - + Layout 布局 - + Fullscreen 全屏 - + RestoreLayout 恢复默认布局 - + BreakPoint 断点 - + ToggleBreakPoint 切换断点 - + AddBreakPoint 添加断点 - + Settings 设置 - + ClangFormat Clang Format - + Console 控制台 - + Local 本地 - + Global 全局 - + Variables 变量 - + ConsoleOutput 输出 - + StackTrace 栈跟踪 - + Symbol 符号 - - - - - - + + + + + + Error 错误 - + Too much opened files 打开的文件过多,无法继续操作! - + ConfirmSave 正在关闭未保存的脚本文件,你确定保存吗? - + ScriptSaveFailedClose 脚本保存失败,你仍确认关闭吗? - + Debuging... 调试中... - + Running... 运行中... - + Line %1, Col %2 行 %1, 列 %2 - + (Selected: %1) (选中: %1) - - + + ChooseFile 选择文件 - - - + + + FilePermission 因文件权限无法继续! - + ReloadSuccessfully 文件重新加载成功! - + ReloadUnSuccessfully 文件重新加载失败! - + ChooseSaveFile 请选择保存文件路径: - - + + SaveSuccessfully 保存成功! - + SaveUnSuccessfully 保存失败! - + FormatCodeFailed 代码格式化失败 - - + + CannotSave2RunScript 无法保存,故无法继续运行脚本。 - - + + ScriptStillRunning 脚本仍在运行,你确定要退出吗? - + ConfirmScriptSave 你尝试关闭程序,但仍存在未保存的脚本文件,你确定保存这些更改吗? - + View 视图 - + Debug 调试 - + Run 运行 - + RunWithDbg 调试运行 - + Pause 暂停 - + Continue 继续 - + Stop 停止 - + Restart 重启 - + StepInto 单步步入 - + StepOver 单步步过 - + StepOut 单步跳出 - + RemoveBreakPoint 删除断点 - + Info 信息 - + Software 软件 - + Sponsor 赞助 - + Wiki 网页 Wiki - + AboutQT 关于 QT @@ -5191,28 +5155,28 @@ WingAngelAPI - + AngelScriptService AngelScript 服务 - + A internal plugin that provides AngelScript scripts with the ability to call the host API. 为 AngelScript 脚本提供调用主机 API 能力的内部插件。 - + NotSupportedQMetaType: 不支持的 QT 数据元类型: - - + + Get Exception While ScriptCall: (%1) %2 脚本调用发生异常:(%1)%2 - + InvalidRetType: need 无效返回值:需要 @@ -5445,7 +5409,7 @@ asDebugger - + {no engine} {无引擎} diff --git a/lang/zh_TW/winghex_zh_TW.ts b/lang/zh_TW/winghex_zh_TW.ts index 12c02d7..a79ca77 100644 --- a/lang/zh_TW/winghex_zh_TW.ts +++ b/lang/zh_TW/winghex_zh_TW.ts @@ -865,18 +865,18 @@ MainWindow - + File - - + + View 視圖 - + About 關於 @@ -897,347 +897,347 @@ 選長: - + Edit 編輯 - + Script 腳本 - - - + + + Plugin 插件 - + Setting 設置 - - + + Log 日誌 - + ExportFindResult 導出搜索結果 - + ClearFindResult 清空記錄 - - + + FindResult 搜索結果 - - - - - - - + + + + + + + Copy 複製 - - - - - - - - + + + + + + + + CopyToClipBoard 數據已拷貝到粘貼板 - + LittleEndian 小端 - + BigEndian 大端 - + Number 數值 - - + + CheckSum 校驗和 - - + + DeleteBookMark 刪除書簽 - - + + ClearBookMark 清空書簽 - - - - + + + + BookMark 書簽 - - + + DecodeText 解碼字串 - + ScriptConsole 腳本控制臺 - - + + DVList 可視化列表 - - + + DVTree 可視化樹數據 - - + + DVTable 可視化表格 - - + + DVText 可視化文本 - - + + Basic 基礎 - + New 新建 - + OpenF 打開檔 - + OpenWorkSpace 打開工作區 - + RecentFiles 最近打開 - + Reload 重新加載 - - + + Save 保存 - + SaveAs 另存為 - + ConvertWS 轉為工作區 - + Export 導出 - + SaveSel 保存選區位元組 - - - - + + + + General 基本 - + Undo 撤銷 - + Redo 恢復 - + Cut 剪切 - + Paste 粘貼 - + Delete 刪除 - + Clone 克隆 - + Lookup 查詢 - + Find 查找 - + Goto 跳轉 - - + + Encoding 編碼 - + FileInfo 檔資訊 - - + + Hex 十六進制 - + CutHex 剪切(十六進制) - + CopyHex 複製(十六進制) - + PasteHex 粘貼(十六進制) - - + + Fill 填充 - + FillZero 填充零 - - - - - + + + + + MetaData 標注 - + DeleteMetadata 刪除標注 - + ClearMetadata 清空標注 - + MetaDataEdit 編輯標注 - + DeleteMetaData 刪除標注 - + ClearMetaData 清空標注 - + Display 顯示 - + ViewText 文本預覽 - + Scale 縮放 @@ -1272,797 +1272,812 @@ 加載插件中: - + SetupConsole 啟動腳本控制臺 - + SetupScriptManager 啟動腳本管理器 - + SetupScriptService 啟動腳本服務 - + SetupScriptEditor 構建腳本編輯器 - + SetupSetDialog 構建設置窗體 - + SetupPlgWidgets 啟動插件組件 - + SetupDockingLayout 恢復 Dock 佈局 - + SetupWaiting 啟動即將完成 - + SetupFinished 啟動完畢 - + NoExtension 無擴展 - - - - - - + + + + + + ExportResult 導出結果 - - - + + + NothingToSave 沒有保存的數據 - - - - + + + + ClearResult 清空結果 - + OpenExt 打開 - 拓展 - + ResetScale 重置縮放 - + ShowMetafg 標注前景色 - + ShowMetabg 標注背景色 - + ShowMetaComment 批註 - + MetaShowAll 顯示所有標注 - + MetaHideAll 隱藏所有標注 - + FileStatus 檔狀態 - + InfoSave 是否保存 - + ReadOnly 可讀寫 - + SetLocked 啟用/禁用鎖定編輯 - + ErrUnLock 鎖定編輯失敗 - + SetOver 啟用/禁用改變大小 - + UnsignedHex 無符號 Hex - + + BgScriptOutput + 後臺腳本輸出 + + + ErrUnOver 鎖定檔大小失敗 - + Window 窗體 - + Editor 編輯器 - + Tools 工具 - + HexEditorLayout 編輯器佈局 - + SetBaseAddr 設置基址 - + addressBase 基址 - + inputAddressBase 請輸入基址 - + WarnBigBaseAddress 基址過大,你得到的地址將會不正確! - + ErrBaseAddress 非法基址輸入 - + SetColInfo 顯示/隱藏地址欄 - + SetHeaderInfo 顯示/隱藏表頭 - + SetAsciiString 顯示/隱藏解碼字串 - + Layout 佈局 - + Fullscreen 全屏 - + Default 默認 - - - + + + LayoutRestoring... 恢復佈局中... - + RestoreLayout 恢復佈局 - - + + SaveLayout 保存佈局 - + ExportLog 導出日誌 - + ClearLog 清空日誌 - + InsepctQt 監視 Qt - + ScriptEditor 腳本編輯器 - + Scripts 腳本倉庫 - + PluginFunctions 插件功能 - + ScriptSetting 腳本設置 - + PluginSettings 插件設置 - + Info 資訊 - + Software 軟體 - + Sponsor 贊助 - + CheckUpdate 檢查更新 - + Wiki 網頁 Wiki - + AboutQT 關於 QT - + SetPageIDEmptyTryUseName 設置頁 ID 為空,嘗試使用名稱作為 ID - + SetPageDupNameIgnored 設置頁重複的 ID 名稱,已忽略加載 - + Plugin %1 contains a duplicate ID (%2) that is already registered by plugin %3 插件 %1 包含重複 ID (%2),該 ID 已被插件 %3 註冊 - - + + ChooseFile 選擇檔 - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + Error 錯誤 - - + + FileNotExist 檔不存在! - - - - - - - - + + + + + + + + FilePermission 因檔許可權無法繼續! - + ProjectFile (*.wingpro) 專案檔 (*.wingpro) - + ReloadSuccessfully 檔重新加載成功! - + ReloadUnSuccessfully 檔重新加載失敗! - - - - - - - + + + + + + + ChooseSaveFile 請選擇保存檔路徑: - + NoMoreClone 克隆已到上限,無法繼續操作! - + FindFininishBusy 查找任務繁忙,請勿重複查找! - + MayTooMuchFindResult 搜索數量已到達上限,結果可能不全,建議請按區段搜索。 - + SaveLayoutSuccess 保存佈局成功 - + SaveLayoutError 保存佈局失敗 - + HasClonedView 該編輯頁已被克隆編輯,如果關閉,相關聯的頁也會被關閉,你確認繼續嗎? - + SaveWorkSpace 保存工作區 - + WingHexWorkSpace (*.wingpro) 羽雲十六進制工作區 (*.wingpro) - + ConfirmSave 正在關閉未保存的檔或工作區,你確定保存嗎? - + + [Info] + 【資訊】 + + + + [Warn] + 【警告】 + + + + [Error] + 【錯誤】 + + + Column %1 列 %1 - + ConfirmAPPSave 你嘗試關閉程式,但仍存在未保存的檔或工作區,你確定保存這些更改嗎? - - - - - - + + + + + + SaveSuccessfully 保存成功! - - + + SaveWSError 保存工作區錯誤! - - + + Warn 警告 - - ScriptObjShow - 腳本對象 - - - + Opening... 打開檔中... - + WorkSpaceOpening... 打開工作區中... - + Reloading... 重載檔中... - + Saving... 保存中... - + SaveNewFirst 請首先保存新建的檔 - + AlreadyWorkSpace 已經是工作區,無需轉化 - + ConvWorkSpaceFailed 轉化為工作區失敗 - + ConvWorkSpaceSuccess 轉化為工作區成功 - + SavingAs... 另存為中... - + SaveUnSuccessfully 保存失敗! - + Exporting... 導出中... - + ChooseExportFile 請選擇導出檔路徑: - + ExportSuccessfully 導出成功! - + ExportUnSuccessfully 導出失敗! - + SavingSel... 保存選中位元組中... - + SaveSelSuccess 保存選區位元組成功! - + SaveSelError 保存選區位元組失敗,因檔不具有可寫許可權! - - + + CutToClipBoard 數據已剪切到粘貼板! - - + + UnCutToClipBoard 由於保持大小限制,數據剪切到粘貼板失敗! - - + + UnCopyToClipBoard 由於保持大小限制,數據剪切到複製板失敗! - - + + Finding... 查找中... - + DeleteSuccess 刪除成功 - + DeleteFailed 刪除失敗 - + FindFininish 查找結果完畢! - + PleaseInputFill 請輸入填充位元組值 - + FillInputTruncWarn 填充輸入數值過大,將會被截斷填充 - + FillInputError 填充位元組輸入錯誤 - - + + InputComment 請輸入批註: - - + + BookmarkDelSuccess 刪除書簽成功 - + BookmarkDelNoItem 無書簽可刪除 - + BookmarkClearSuccess 書簽清空完畢 - - - + + + NoSelection 沒有選區,無法繼續的操作! - + NoMetaData 無可編輯標記 - + PleaseClearSel 請清空選擇 - + MetaDelSuccess 元數據刪除成功 - + MetaDelNoItem 無元數據可刪除 - + MetaClearSuccess 元數據清空完畢 - + FindResultExporting... 查找結果導出中... - - + + EmptyFindResult 沒有可導出的搜索結果! - + SaveFindResult 導出搜索結果成功! - + SaveFindResultError 導出結果失敗! - + TooManyBytesDecode 超出解碼位元組限制…… - + NoTextFileMayInvalid 該檔不是文本檔,以文本方式預覽並不是一個好的方式,你確認繼續嗎? - + LayoutSaving... 佈局保存中... - + PleaseInput 請輸入 - + LogExporting... 日誌導出中... - + ExportLogError 導出日誌失敗! - + ExportLogSuccess 導出日誌成功,路徑: - + ClearLogSuccess 清空日誌成功! - + BadNetwork 無法與遠程伺服器的更新檢查建立連接,請檢查網路。 - + NewestVersion 當前軟體為最新版本 - - + + OlderVersion 你使用的軟體為老版本,建議到 Github 和 Gitee 的倉庫發行版下載更新。 - + CheckingUpdate 檢查更新中…… - + Too much opened files 打開的檔過多,無法繼續操作! - + FilePermissionSure2Quit 因檔許可權無法保存,你確認要退出嗎? - + UnknownErrorSure2Quit 因未知錯誤無法保存,你確認要退出嗎? - + WorkSpaceUnSavedSure2Quit 工作區檔無法保存,你確認要退出嗎? - + CopyLimit 拷貝位元組超出限制 - + ErrOpenFileBelow 打開檔出現錯誤(由於許可權不足),如下為打開錯誤的檔: @@ -2293,200 +2308,200 @@ PluginSystem - + LoadingPlugin 加載插件中: - + InvalidPluginBrokenInfo 加載插件失敗:損壞的插件數據 - + AppClosingCanceled: 程式關閉被取消: - + - PluginID: - 插件 ID: - + FoundDrvPluginCount 總計發現設備拓展插件數目: - + RegisterScriptFnUnSupportedTypes: 因腳本函數含有未支持的類型而註冊失敗: - - + + RegisterScriptFnInvalidSig: 因腳本函數簽名非法而註冊失敗: - - + + RegisterScriptFnConflitSig: 因腳本函數簽名衝突而註冊失敗: - + InvalidEnumName: 非法枚舉名: - + InvalidEnumValue: 非法枚舉值: - + InvalidMarcosRegister: 非法宏註冊: - + ErrLoadPluginSDKVersion 插件加載失敗:非法插件 SDK 版本! - + ErrLoadPluginNoName 插件加載失敗:非法插件名稱! - + ErrLoadInitPlugin 插件加載失敗:初始化插件失敗! - + PluginName : 插件名: - + PluginAuthor : 插件作者: - + PluginWidgetRegister 註冊插件對象中…… - + ErrLoadExtPluginSDKVersion 設備拓展插件加載失敗:非法插件 SDK 版本! - + ExtPluginAuthor : 設備拓展插件作者: - + ExtPluginWidgetRegister 設備拓展註冊插件對象中…… - + ErrLoadInitExtPlugin 設備拓展插件加載失敗:初始化插件失敗! - + ChooseFile 選擇檔 - - + + Error 錯誤 - + FileNotExist 檔不存在! - + FilePermission 因檔許可權無法繼續! - + EmptyNameDockWidget: 空的貼邊組件名: - + InvalidNameDockWidget: 無效貼邊組件名: - + InvalidNullDockWidget: 無效空貼邊組件: - + Not allowed operation in non-UI thread 該操作在非 UI 線程非法 - + UnsafePluginDir 不安全的插件目錄,請將插件目錄設置為僅管理員帳戶可寫 - + [EvilCall] 【非法調用】 - + InvalidPluginID 加載插件失敗:非法插件識別字 - + InvalidDupPlugin 加載插件失敗:重複的插件識別字 - + FoundPluginCount 總計發現插件數目: - + PluginLoadingFailedSummary 有依賴插件加載失敗總結 - + - Dependencies: - 依賴: - + PUID: 插件唯一標誌符: - + Version: 版本: - + PluginLoadingFinished 加載插件完畢! @@ -2798,1603 +2813,1575 @@ - - ScriptConsoleMachine - - - EmptyDecl - 空聲明 - - - - Application functions: - 程式函數: - - - - User functions: - 用戶函數: - - - - Application variables: - 程式變數: - - - - User variables: - 用戶變數: - - ScriptMachine - + AngelScript callstack: AngelScript 調用堆疊: - + - Exception '%1' in '%2' — 在 ‘%2’ 中發生異常 ‘%1’ - + ExecNotAllowedInRoot 在管理員許可權執行第三方命令為非法操作 - - - + + + Script failed to build 腳本編譯失敗 - - + + Cannot find 'int main()' or 'void main()' 無法找到程式入口點: "int main()" 或者 "void main()" - + Debugging, waiting for commands. 調試中,等待調試命令。 - + Failed while initializing global variables 初始化全局變數失敗 - - + + The script failed with an exception 異常被拋出,腳本執行失敗 - - + + The script was aborted 腳本被終止 - - + + The script terminated unexpectedly 腳本異常退出 - + The script exited with 腳本退出返回值: - + '%1' is already declared "%1" 已被聲明 - + Abstract class '%1' cannot be instantiated 無法實例化抽象類 "%1" - + Accessing private property '%1' of parent class 非法訪問父類的私有屬性 "%1" - + Attribute '%1' informed multiple times 屬性 "%1" 已被多次通知 - + Can't form arrays of subtype '%1' 無法創建子類型 "%1" 的數組 - + Can't inherit from class '%1' marked as final 無法從標記為 final 的類 "%1" 繼承 - + Cannot access non-static member '%1' like this 無法和像使用 this 一樣訪問非靜態成員 "%1" - + Can't construct handle '%1'. Use ref cast instead 無法構造句柄 "%1" 。請改用引用強制轉換 - + Can't implicitly convert from '%1' to '%2'. 無法從 "%1' 隱式轉換為 "%2"。 - + Compiling %1 正在編譯 %1 - + Compiling auto generated %1 編譯自動生成的 %1 - + Implemented property accessor '%1' does not expect index argument 已實現的屬性訪問器 "%1" 不需要索引參數 - + Implemented property accessor '%1' expects index argument 已實現的屬性訪問器 "%1" 需要索引參數 - + Data type can't be '%1' 數據類型不能為 "%1" - + All subsequent parameters after the first default value must have default values in function '%1' 在函數 "%1" 中,第一個默認值之後的所有後續參數都必須具有默認值 - + The method in the derived class must have the same return type as in the base class: '%1' 派生類中的方法必須具有與基類相同的返回類型:"%1" - + The name of the destructor '%1::~%2' must be the same as the class 析構函數 "%1::~%2" 的名稱必須與類相同 - + Expected '%1' 應為 "%1" - + Expected '%1' or '%2' 應為 ”%1“ 或 ”%2“ - + Expression must be of boolean type, instead found '%1' 運算式必須是布爾類型,但實際使用的是 "%1" - + Expression '%1' is a data type 運算式 "%1" 是一種數據類型 - + External shared entity '%1' not found 未找到外部共用實體 "%1" - + External shared entity '%1' cannot redefine the original entity 外部共用實體 "%1" 無法重新定義原始實體 - + Failed while compiling default arg for parameter %1 in function '%2' 為函數 "%2" 中的參數 %1 編譯默認參數時失敗 - + Function '%1' not found 未找到函數 "%1" - + The property '%1' has mismatching types for the get and set accessors 屬性 "%1" 的 get 和 set 訪問器類型不匹配 - + Variable '%1' hides another variable of same name in outer scope 變數 "%1" 隱藏了外部作用域中另一個同名變數 - + Identifier '%1' is not a data type 識別字 "%1" 不是數據類型 - + Identifier '%1' is not a data type in global namespace 識別字 "%1" 不是全局命名空間中的數據類型 - + Identifier '%1' is not a data type in namespace '%2' or parent 識別字 "%1" 不是命名空間 "%2" 或其父級中的數據類型 - + Illegal operation on '%1' 對 "%1" 的非法操作 - + Illegal variable name '%1'. 非法變數名 "%1"。 - + Illegal access to inherited private property '%1' 非法訪問繼承的私有屬性 "%1" - + Initialization lists cannot be used with '%1' 初始化列表不能與 "%1" 一起使用 - + Attempting to instantiate invalid template type '%1<%2>' 嘗試實例化無效的範本類型 "%1<%2>" - + Instead found '%1' 而是找到了 "%1" - + Instead found identifier '%1' 而是找到識別字 "%1" - + Instead found reserved keyword '%1' 而是找到了保留關鍵字 "%1" - + Interface '%1' cannot be instantiated 無法實例化介面 "%1" - + Invalid unicode escape sequence, expected %1 hex digits 無效的 Unicode 轉義序列,預期為 %1 個十六進制數字 - + Method '%1' declared as final and cannot be overridden 方法 "%1" 已聲明為 final,因此無法被覆蓋 - + Method '%1' marked as override but does not replace any base class or interface method 方法 "%1" 標記為覆蓋,但並未替換任何基類或介面方法 - + Method '%1::%2' is missing the return type, nor is it the same name as object to be a constructor 方法 "%1::%2" 缺少返回類型,並且其名稱與構造函數對象不同 - + Method '%1' is not part of object '%2' 方法 "%1" 不是對象 "%2" 的一部分 - + Missing implementation of '%1' 缺少 "%1" 的實現 - + Missing definition of '%1' 缺少 "%1" 的定義 - + Mixin class cannot be declared as '%1' Mixin 類不能聲明為 "%1" - + Multiple matching signatures to '%1' "%1" 有多個匹配的簽名 - + Found multiple get accessors for property '%1' 發現屬性 "%1" 的多個 get 訪問器 - + Found multiple set accessors for property '%1' 發現屬性 "%1" 的多個集合訪問器 - + Namespace '%1' doesn't exist. 命名空間 "%1" 不存在。 - - - - - - - - - - - - + + + + + + + + + + + + Name conflict. 名稱衝突。 - + '%1' is an extended data type. "%1" 是擴展數據類型。 - + '%1' is a global property. "%1" 是全局屬性。 - + '%1' is a named type. "%1" 是被命名的類型。 - + '%1' is a funcdef. "%1" 是一個函數簽名定義。 - + '%1' is a global function. "%1" 是一個全局函數。 - + '%1' is a mixin class. "%1" 是一個 Mixin 類。 - + '%1' is a virtual property. "%1" 是虛擬屬性。 - + '%1' is a class. "%1" 是一個類。 - + '%1' is an interface. "%1" 是一個介面。 - + '%1' is an object property. "%1" 是一個對象屬性。 - + '%1' is a class method. "%1" 是一個類方法。 - + '%1' is already used. ”%1“ 已被使用。 - + No appropriate opHndlAssign method found in '%1' for handle assignment 在 "%1" 中未找到適當的 opHndlAssign 方法用於句柄分配 - + No conversion from '%1' to '%2' available. 無法進行從 "%1" 到 "%2" 的轉換。 - + No conversion from '%1' to math type available. 無法將 "%1" 轉換為數學類型。 - + No default constructor for object of type '%1'. "%1" 類型對象沒有默認構造函數。 - + No appropriate opAssign method found in '%1' for value assignment 在 "%1" 中未找到適合賦值的 opAssign 方法 - + No copy constructor for object of type '%1'. 沒有 "%1" 類型對象的複製構造函數。 - + No matching signatures to '%1' 沒有與 "%1" 匹配的簽名 - + No matching operator that takes the type '%1' found 未找到採用類型 "%1" 的匹配運算符 - + No matching operator that takes the types '%1' and '%2' found 未找到採用類型 "%1" 和 "%2" 的匹配運算符 - + No matching symbol '%1' 沒有匹配的符號 "%1" - + Expression doesn't form a function call. '%1' evaluates to the non-function type '%2' 運算式不構成函數調用。"%1" 計算結果為非函數類型 "%2" - + '%1' is not declared "%1" 未被聲明 - + '%1' is not initialized. ”%1“ 未初始化。 - + '%1' is not a member of '%2' ”%1“ 不是 ”%2“ 的成員 - + Type '%1' doesn't support the indexing operator 類型 "%1" 不支持索引運算符 - + Parameter type can't be '%1', because the type cannot be instantiated. 參數類型不能是 "%1",因為該類型無法實例化。 - + Previous error occurred while attempting to compile initialization list for type '%1' 嘗試編譯類型 "%1" 的初始化列表時發生先前的錯誤 - + Illegal call to private method '%1' 非法調用私有方法 "%1" - + Illegal access to private property '%1' 非法訪問私有屬性 "%1" - + Illegal call to protected method '%1' 非法調用受保護的方法 "%1" - + Illegal access to protected property '%1' 非法訪問受保護的屬性 "%1" - + Return type can't be '%1' 返回類型不能是 "%1" - + Shared code cannot access non-shared global variable '%1' 共用代碼無法訪問非共用全局變數 "%1" - + Shared code cannot call non-shared function '%1' 共用代碼無法調用非共用函數 "%1" - + Shared type cannot implement non-shared interface '%1' 共用類型無法實現非共用介面 "%1" - + Shared class cannot inherit from non-shared class '%1' 共用類不能從非共用類 "%1" 繼承 - + Shared code cannot use non-shared type '%1' 共用代碼不能使用非共用類型 "%1" - + Shared type '%1' doesn't match the original declaration in other module 共用類型 "%1" 與其他模組中的原始聲明不匹配 - + Template '%1' expects %2 sub type(s) 範本 "%1" 需要 %2 個子類型 - + Type '%1' cannot be a reference 類型 "%1" 不能是引用 - + Type '%1' is not available for this module 類型 "%1" 不適用於此模組 - + Type '%1' is not a template type 類型 "%1" 不是範本類型 - + Unexpected token '%1' 意外標記 "%1" - + Use of uninitialized global variable '%1'. 使用未初始化的全局變數 "%1"。 - + Unknown scope '%1' 未知作用域 "%1" - + Where '%1' is '%2' 其中 "%1" 是 "%2" - + Failed to initialize global variable '%1' 無法初始化全局變數 "%1" - + Exception '%1' in '%2' "%2" 中的異常 "%1" - + Type '%1' is missing behaviours 類型 "%1" 缺少的行為 - + Can't pass type '%1' by value unless the application type is informed in the registration 除非在註冊時告知應用程式類型,否則無法按值傳遞類型 "%1" - + Can't return type '%1' by value unless the application type is informed in the registration 除非在註冊時告知應用程式類型,否則無法按值返回類型 "%1" - + Don't support passing type '%1' by value to application in native calling convention on this platform 不支持在此平臺上按照本機調用約定將類型 "%1" 按值傳遞給應用程式 - + Don't support returning type '%1' by value from application in native calling convention on this platform 不支持在此平臺上按照本機調用約定從應用程式返回類型 "%1" 的值 - + Object {%1}. GC cannot destroy an object of type '%2' as it doesn't know how many references to there are. 對象 {%1}。GC 無法銷毀類型為 "%2" 的對象,因為它不知道有多少個引用。 - + Object {%1}. GC cannot destroy an object of type '%2' as it can't see all references. Current ref count is %3. 對象 {%1}。GC 無法銷毀類型為 "%2" 的對象,因為它無法看到所有引用。當前引用計數為 %3。 - + Object type '%1' doesn't exist 對象類型 "%1" 不存在 - + Cannot register. The template type instance '%1' has already been generated. 無法註冊。範本類型實例 "%1" 已生成。 - + Template type '%1' doesn't exist 範本類型 "%1" 不存在 - + Template subtype '%1' doesn't exist 範本子類型 "%1" 不存在 - + Failed to read subtype of template type '%1' 無法讀取範本類型 "%1" 的子類型 - + Failed in call to function '%1' (Code: %2, %3) 調用函數 "%1" 失敗(代碼:%2,%3) - + Failed in call to function '%1' with '%2' (Code: %3, %4) 使用 "%2" 調用函數 "%1" 失敗(代碼:%3,%4) - + Failed in call to function '%1' with '%2' and '%3' (Code: %4, %5) 使用 "%2" 和 "%3" 調用函數 "%1" 失敗(代碼:%4,%5) - + Type '%1' is still used by function '%2' 類型 "%1" 仍被函數 "%2" 使用 - + The builtin type in previous message is named '%1' 上一條消息中的內置類型名為 "%1" - + The function in previous message is named '%1'. The func type is %2 上一條消息中的函數名為 "%1"。函數類型為 %2 - + The script object of type '%1' is being resurrected illegally during destruction 類型為 "%1" 的腳本對象在銷毀過程中被非法復活 - + LoadByteCode failed. The bytecode is invalid. Number of bytes read from stream: %1 LoadByteCode 失敗。位元組碼無效。從流中讀取的位元組數:%1 - + Function '%1' appears to have been compiled without JIT entry points 函數 "%1" 似乎已在無 JIT 入口點的情況下進行編譯 - + There is an external reference to an object in module '%1', preventing it from being deleted 存在對模組 "%1" 中對象的外部引用,導致無法刪除該對象 - + Output argument expression is not assignable 輸出參數運算式不可分配 - + Auto is not allowed here 這裏禁止使用 auto 關鍵字 - + Can't find unambiguous implicit conversion to make both expressions have the same type 無法找到明確的隱式轉換來使兩個運算式具有相同的類型 - + Both conditions must call constructor 兩個條件都必須調用構造函數 - + Base class doesn't have default constructor. Make explicit call to base constructor 基類沒有默認構造函數。明確調用基類構造函數 - + Base class doesn't have copy constructor or default constructor and assign operator. Make explicit call to base constructor 基類沒有複製構造函數或默認構造函數和賦值運算符。明確調用基類構造函數 - + Candidates are: 候選包括: - + Can't call a constructor in loops 無法在迴圈中調用構造函數 - + Can't call a constructor in switch 無法在 switch 中調用構造函數 - + Can't call a constructor multiple times 無法多次調用構造函數 - + Can't create delegate 無法創建委託 - + Can't create delegate for types that do not support handles 無法為不支持句柄的類型創建委託 - + Cannot flag function that will not be auto generated as deleted 無法將不會自動生成的函數標記為已刪除 - + Conflict with explicit declaration of function and deleted function 與函數的顯式聲明和已刪除函數衝突 - + Can't implement itself, or another interface that implements this interface 無法實現自身,也無法實現此介面的其他介面 - + Can't inherit from multiple classes 不能從多個類繼承 - + Can't inherit from itself, or another class that inherits from this class 不能從其自身或從該類繼承的其他類繼承 - + Can't pass class method as arg directly. Use a delegate object instead 無法直接將類方法作為參數傳遞。請改用委託對象 - + Unable to resolve auto type 無法解析自動類型 - + Can't return reference to local value. 無法返回對本地值的引用。 - + Can't return value when return type is 'void' 返回類型為 "void" 時無法返回值 - + Implicit conversion changed sign of value 隱式轉換改變了值的符號 - + A class cannot be both abstract and final 一個類不能同時是 abstract 和 final - + Compound assignments with property accessors on value types are not supported 不支持對值類型使用屬性訪問器的複合賦值 - + Compound assignments with indexed property accessors are not supported 不支持使用索引屬性訪問器的複合賦值 - + Compound assignments with property accessors require both get and set accessors 具有屬性訪問器的複合賦值需要 get 和 set 訪問器 - + Variables cannot be declared in switch cases, except inside statement blocks 變數不能在 switch 語句中聲明,除非在語句塊內 - + The default case must be the last one default 情況必須是最後一個 - + The type of the default argument expression doesn't match the function parameter type 默認參數運算式的類型與函數參數類型不匹配 - + Deleted functions cannot have implementation 已刪除的函數不能有實現 - + The destructor must not have any parameters 析構函數不能有任何參數 - + Value assignment on reference types is not allowed. Did you mean to do a handle assignment? 不允許對引用類型進行值分配。是要進行句柄分配嗎? - + Compound assignment on reference types is not allowed 不允許對引用類型進行複合賦值 - + Duplicate named argument 重複命名參數 - + Duplicate switch case 重複的 switch case - + Else with empty statement else 中使用空語句 - + Empty list element is not allowed 不允許空列表元素 - + Empty switch statement 空的 switch 語句 - + Expected constant 應為常量 - + Expected data type 應為數據類型 - + Expected expression value 應為表達值 - + Expected identifier 應為識別字 - + Expected a list enclosed by { } to match pattern 應為用 { } 括起來的列表與模式匹配 - + Expected method or property 應為方法或屬性 - + Expected one of: 應為為以下之一: - + Expected operator 應為操作符 - + Expected post operator 應為右操作符 - + Expected pre operator 應為左操作符 - + Expected string 應為字串 - + Expression doesn't evaluate to a function 運算式無法計算函數值 - + Previous error occurred while attempting to create a temporary copy of object 嘗試創建對象的臨時副本時發生上一個錯誤 - + Float value truncated in implicit conversion to integer 浮點值在隱式轉換為整數時被截斷 - + Found multiple matching enum values 找到多個匹配的枚舉值 - + A function with the same name and parameters already exists 具有相同名稱和參數的函數已存在 - + Global variables have been disabled by the application 全局變數已被應用程式禁用 - + It is not allowed to perform a handle assignment on a non-handle property 不允許對非句柄屬性執行句柄分配 - + The operand is implicitly converted to handle in order to compare them 運算元被隱式轉換為句柄,以便進行比較 - + Handle to handle is not allowed 不允許使用句柄 - + If with empty statement 如果帶有空語句 - + Illegal member type 非法成員類型 - + Illegal operation on this datatype 對該數據類型的非法操作 - + Illegal target type for reference cast 非法引用轉換的目標類型 - + Interfaces can only implement other interfaces 介面只能實現其他介面 - + Invalid 'break' 無效的 break 關鍵字 - + Invalid character literal 無效的字元 - + Invalid 'continue' 無效的 continue 關鍵字 - + Invalid escape sequence 無效的轉義序列 - + Invalid expression: ambiguous name 無效運算式:二義性名稱 - + Invalid expression: stand-alone anonymous function 無效運算式:獨立匿名函數 - + Invalid operation on method 方法操作無效 - + Invalid reference. Property accessors cannot be used in combined read/write operations 引用無效。屬性訪問器不能用於組合讀/寫操作。 - + Invalid scope resolution 範圍解析無效 - + Invalid signature for virtual property 虛擬屬性簽名無效 - + Invalid type 類型無效 - + Invalid unicode code point 無效的 Unicode 代碼點 - + Invalid unicode sequence in source 源代碼中的 Unicode 序列無效 - + Invalid use of named arguments 命名參數的使用無效 - + The method cannot be named with the class name 該方法不能以類名命名 - + Mixin classes cannot have constructors or destructors Mixin 類不能有構造函數或析構函數 - + Mixin class cannot inherit from classes Mixin 類不能從類繼承 - + Mixin classes cannot have child types Mixin 類不能有子類型 - + Found more than one matching operator 找到多個匹配的運算符 - + Multiline strings are not allowed in this application 此應用程式不允許使用多行字串 - + Only objects have constructors 只有對象才有構造函數 - + Must return a value 必須返回一個值 - + Detected named argument with old syntax 檢測到具有舊語法的命名參數 - + No appropriate indexing operator found 未找到合適的索引運算符 - + No appropriate opEquals method found 未找到合適的 opEquals 方法 - + The application doesn't support the default array type. 該應用程式不支持默認數組類型。 - + Non-const method call on read-only object reference 只讀對象引用上的非常量方法調用 - + Non-terminated string literal 未終止的字串 - + Not all paths return a value 並非所有路徑都會返回值 - + Not enough values to match pattern 沒有足夠的值來模式匹配 - + Implicit conversion of value is not exact 值的隱式轉換並不準確 - + Expression is not an l-value 運算式不是左值 - + Not a valid reference 無效引用 - + Not a valid lvalue 不是有效的左值 - + Nothing was built in the module 模組中沒有構建任何內容 - + Object handle is not supported for this type 此類型不支持對象句柄 - + Only object types that support object handles can use &inout. Use &in or &out instead 只有支持對象句柄的對象類型才能使用 &inout。請改用 &in 或 &out - + A cast operator has one argument 強制類型轉換運算符有一個參數 - + The code must contain one and only one function 代碼必須包含一個且只能包含一個函數 - + The code must contain one and only one global variable 代碼必須包含一個且只能有一個全局變數 - + Both operands must be handles when comparing identity 比較時,兩個運算元都必須是句柄 - + The overloaded functions are identical on initial parameters without default arguments 重載函數在初始參數上相同,沒有默認參數 - + Parameter already declared 參數已聲明 - + Positional arguments cannot be passed after named arguments 位置參數不能在命名參數之後傳遞 - + Potentially matching non-const method is hidden on read-only object reference 可能匹配的非 const 方法隱藏在只讀對象引用中 - + Property accessor with index must have 1 and only 1 index argument 帶索引的屬性訪問器必須有 1 個且只能有 1 個索引參數 - + Property accessors have been disabled by the application 應用程式已禁用屬性訪問器 - + Property accessor must be implemented 必須實現屬性訪問器 - + Class properties cannot be declared as const 類屬性不能聲明為 const - + The property has no get accessor 該屬性沒有 get 訪問器 - + The property has no set accessor 該屬性沒有設置訪問器 - + Virtual property must have at least one get or set accessor 虛擬屬性必須至少有一個 get 或 set 訪問器 - + Resulting reference cannot be returned. Returned references must not refer to local variables. 無法返回結果引用。返回的引用不得引用局部變數。 - + Resulting reference cannot be returned. There are deferred arguments that may invalidate it. 無法返回結果引用。存在可能使其無效的延遲參數。 - + Resulting reference cannot be returned. The expression uses objects that during cleanup may invalidate it. 無法返回結果引用。運算式使用的對象在清理過程中可能會使其失效。 - + Reference is read-only 引用是只讀的 - + Reference is temporary 參考是臨時的 - + Reference types cannot be passed by value in function parameters 引用類型不能在函數參數中按值傳遞 - + Reference types cannot be returned by value from functions 引用類型不能通過函數返回值 - + The script section is empty 腳本節區為空 - + Signed/Unsigned mismatch 有符號/無符號不匹配 - + Strings are not recognized by the application 應用程式無法識別字串 - + Case expressions must be literal constants case 運算式必須是文字常量 - + Switch expressions must be integral numbers switch 運算式必須是整數 - + The function has too many jump labels to handle. Split the function into smaller ones. 該函數的跳轉標籤過多,無法處理。請將函數拆分為較小的函數。 - + Too many values to match pattern 與模式匹配的值過多 - + Unexpected end of file 意外的檔結束 - + Unexpected variable declaration 意外的變數聲明 - + Unreachable code 無法訪問的代碼 - + Virtual property contains unrecognized aspect 虛擬屬性包含未被認可的部分 - + Unused script node 未使用的腳本節點 - + Value is too large for data type 對於數據類型來說,值太大 - + Void cannot be an operand in expressions void 不能作為運算式中的運算元 - + Warnings are treated as errors by the application 應用程式將警告視為錯誤 - + While parsing argument list 解析參數列表時 - + While parsing expression 解析運算式時 - + While parsing initialization list 解析初始化列表時 - + While parsing namespace 解析命名空間時 - + While parsing statement block 解析語句塊時 - + Previous error occurred while including mixin 包含 mixin 時發生先前錯誤 - + Autohandles cannot be used with types that have been registered with NOCOUNT 自動句柄不能與已使用 NOCOUNT 註冊的類型一起使用 - + First parameter to template factory must be a reference. This will be used to pass the object type of the template 範本工廠的第一個參數必須是引用。這將用於傳遞範本的對象類型 - + Invalid configuration. Verify the registered application interface. 配置無效。請驗證已註冊的應用程式介面。 - + A value type must be registered with a non-zero size 值類型必須註冊為非零大小 - + The behaviour is not compatible with the type 行為與類型不相容 - + A garbage collected ref type must have the addref, release, and all gc behaviours 垃圾收集引用類型必須具有 addref、release 和所有 gc 行為 - + A garbage collected value type must have the gc enum references behaviour 垃圾收集值類型必須具有 gc 枚舉引用行為 - + A scoped reference type must have the release behaviour 作用域引用類型必須具有釋放行為 - + A reference type must have the addref and release behaviours 引用類型必須具有 addref 和 release 行為 - + A non-pod value type must have at least one constructor and the destructor behaviours 非 pod 值類型必須至少有一個構造函數和析構函數行為 - + Template list factory expects two reference parameters. The last is the pointer to the initialization buffer 範本列表工廠需要兩個引用參數。最後一個是指向初始化緩衝區的指針 - + List factory expects only one reference parameter. The pointer to the initialization buffer will be passed in this parameter 列表工廠僅需要一個引用參數。指向初始化緩衝區的指針將在此參數中傳遞 - + AddScriptObjectToGC called with null pointer 使用空指針調用 AddScriptObjectToGC - + An exception occurred in a nested call 嵌套調用中發生異常 - + Uh oh! The engine's reference count is increasing while it is being destroyed. Make sure references needed for clean-up are immediately released 哎呀!引擎的引用計數在被銷毀時不斷增加。確保立即釋放清理所需的引用 - + The module is still in use and cannot be rebuilt. Discard it and request another module 該模組仍在使用中,無法重建。丟棄它並請求另一個模組 - + Property 屬性 - + System function 系統函數 - + Variable declaration 變數聲明 - + Stack overflow 棧溢出 - + Null pointer access 空指針訪問 - + Divide by zero 除以零 - + Overflow in integer division 整數除法溢出 - + Overflow in exponent operation 指數運算溢出 - + Unrecognized byte code 無法識別的位元組碼 - + Invalid calling convention 無效調用約定 - + Unbound function called 未綁定的函數被調用 - + Out of range 越界 - + Caught an exception from the application 捕獲應用程式異常 - + Mismatching types in value assignment 值分配中的類型不匹配 - + Too many nested calls 嵌套調用過多 - - + + Assert failed 斷言失敗 @@ -4402,38 +4389,15 @@ ScriptManager - + RunScript 執行腳本 - + CanNotRunUsrScriptForPolicy 由於限制策略,無法在 Root 模式下運行用戶腳本! - - - Excuting: - 執行腳本: - - - - ScriptObjModel - - - Name - 名稱 - - - - Type - 類型 - - - - Value - - ScriptSettingDialog @@ -4501,37 +4465,37 @@ ScriptingConsole - + [Info] 【資訊】 - + [Warn] 【警告】 - + [Error] 【錯誤】 - + [Console] 【控制臺】 - + Copy 複製 - + Cut 剪切 - + Paste 粘貼 @@ -4552,425 +4516,425 @@ ScriptingDialog - + ScriptEditor 腳本編輯器 - + ScriptPermissionDenied 因許可權無法打開腳本 - + File - + Edit 編輯 - + Debugger 調試器 - + Setting 設置 - + About 關於 - + InvalidSourceFile 非法代碼檔 - + Basic 基礎 - + New 新建 - + OpenF 打開檔 - + RecentFiles 最近打開 - + Reload 重新加載 - - + + Save 保存 - + SaveAs 另存為 - + General 基本 - + Undo 撤銷 - + Redo 恢復 - + Cut 剪切 - + Copy 複製 - + Paste 粘貼 - + Delete 刪除 - + Lookup 查詢 - + Find 查找 - + Replace 替換 - + Goto 跳轉 - + Format 代碼樣式 - + CodeFormat 代碼格式化 - + Window 窗體 - - + + Editor 編輯器 - + Tools 工具 - + Layout 佈局 - + Fullscreen 全屏 - + RestoreLayout 恢復默認佈局 - + BreakPoint 中斷點 - + ToggleBreakPoint 切換中斷點 - + AddBreakPoint 添加中斷點 - + Settings 設置 - + ClangFormat Clang Format - + Console 控制台 - + Local 本地 - + Global 全局 - + Variables 變數 - + ConsoleOutput 輸出 - + StackTrace 棧跟蹤 - + Symbol 符號 - - - - - - + + + + + + Error 錯誤 - + Too much opened files 打開的檔過多,無法繼續操作! - + ConfirmSave 正在關閉未保存的腳本檔,你確定保存嗎? - + ScriptSaveFailedClose 腳本保存失敗,你仍確認關閉嗎? - + Debuging... 調試中... - + Running... 運行中... - + Line %1, Col %2 行 %1, 列 %2 - + (Selected: %1) (選中: %1) - - + + ChooseFile 選擇檔 - - - + + + FilePermission 因檔許可權無法繼續! - + ReloadSuccessfully 檔重新加載成功! - + ReloadUnSuccessfully 檔重新加載失敗! - + ChooseSaveFile 請選擇保存檔路徑: - - + + SaveSuccessfully 保存成功! - + SaveUnSuccessfully 保存失敗! - + FormatCodeFailed 代碼格式化失敗 - - + + CannotSave2RunScript 無法保存,故無法繼續運行腳本。 - - + + ScriptStillRunning 腳本仍在運行,你確定要退出嗎? - + ConfirmScriptSave 你嘗試關閉程式,但仍存在未保存的腳本檔,你確定保存這些更改嗎? - + View 視圖 - + Debug 調試 - + Run 運行 - + RunWithDbg 調試運行 - + Pause 暫停 - + Continue 繼續 - + Stop 停止 - + Restart 重啟 - + StepInto 單步步入 - + StepOver 單步步過 - + StepOut 單步跳出 - + RemoveBreakPoint 刪除中斷點 - + Info 資訊 - + Software 軟體 - + Sponsor 贊助 - + Wiki 網頁 Wiki - + AboutQT 關於 QT @@ -5191,28 +5155,28 @@ WingAngelAPI - + AngelScriptService AngelScript 服務 - + A internal plugin that provides AngelScript scripts with the ability to call the host API. 為 AngelScript 腳本提供調用主機 API 能力的內部插件。 - + NotSupportedQMetaType: 不支持的 QT 數據元類型: - - + + Get Exception While ScriptCall: (%1) %2 腳本調用發生異常:(%1)%2 - + InvalidRetType: need 無效返回值:需要 @@ -5445,7 +5409,7 @@ asDebugger - + {no engine} {無引擎} diff --git a/src/class/asbuilder.cpp b/src/class/asbuilder.cpp index e5cceee..a8f8fb6 100644 --- a/src/class/asbuilder.cpp +++ b/src/class/asbuilder.cpp @@ -24,33 +24,14 @@ asBuilder::asBuilder(asIScriptEngine *engine) : AsPreprocesser(engine) {} -asBuilder::~asBuilder() { - if (module) { - module->Discard(); - } -} - -int asBuilder::StartNewModule(const char *moduleName) { - if (module) { - module->Discard(); - } - - module = engine->GetModule(moduleName, asGM_ALWAYS_CREATE); - if (module == nullptr) - return -1; - - clearAll(); - return 0; -} - -asIScriptModule *asBuilder::GetModule() { return module; } - -int asBuilder::Build() { +int asBuilder::build(asIScriptModule *module) { Q_ASSERT(module); if (module == nullptr) { return -1; } + module->ResetGlobalVars(); + for (auto &mod : modifiedScripts) { module->AddScriptSection(mod.section.toUtf8(), mod.script.data(), mod.script.size()); diff --git a/src/class/asbuilder.h b/src/class/asbuilder.h index 801e47c..a418f58 100644 --- a/src/class/asbuilder.h +++ b/src/class/asbuilder.h @@ -27,19 +27,10 @@ class asBuilder : public AsPreprocesser { public: explicit asBuilder(asIScriptEngine *engine); - virtual ~asBuilder(); - // Start a new module - virtual int StartNewModule(const char *moduleName); - - // Build the added script sections - virtual int Build(); - - // Returns the current module - asIScriptModule *GetModule(); - -protected: - asIScriptModule *module = nullptr; +public: + // build the added script sections + int build(asIScriptModule *module); }; #endif // ASBUILDER_H diff --git a/src/class/ascompletion.cpp b/src/class/ascompletion.cpp index 9463b59..277ed98 100644 --- a/src/class/ascompletion.cpp +++ b/src/class/ascompletion.cpp @@ -20,6 +20,7 @@ #include "asdatabase.h" #include "class/aspreprocesser.h" #include "class/qascodeparser.h" +#include "class/scriptmachine.h" #include "model/codecompletionmodel.h" #include "wingcodeedit.h" @@ -39,10 +40,9 @@ Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, DBL_COLON_TRIGGER, ("::")) Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, LEFT_PARE_TRIGGER, ("(")) Q_GLOBAL_STATIC_WITH_ARGS(QByteArray, SEMI_COLON_TRIGGER, (";")) -AsCompletion::AsCompletion(asIScriptEngine *engine, WingCodeEdit *p) - : WingCompleter(p), parser(engine), _engine(engine), m_parseDocument(true) { - Q_ASSERT(engine); - +AsCompletion::AsCompletion(WingCodeEdit *p) + : WingCompleter(p), parser(ScriptMachine::instance().engine()), + m_parseDocument(true) { setTriggerList({*DOT_TRIGGER, *DBL_COLON_TRIGGER, // unleash the power of call tips *LEFT_PARE_TRIGGER, @@ -157,7 +157,8 @@ void AsCompletion::processTrigger(const QString &trigger, qsizetype pos = 0; for (; p < end;) { asUINT tokenLen = 0; - auto tt = _engine->ParseToken(p, len, &tokenLen); + auto tt = + ScriptMachine::instance().engine()->ParseToken(p, len, &tokenLen); if (tt == asTC_WHITESPACE) { p += tokenLen; pos += tokenLen; @@ -292,7 +293,7 @@ QList AsCompletion::parseDocument() { auto code = editor->toPlainText(); // first preprocess the code - AsPreprocesser prepc(_engine); + AsPreprocesser prepc(ScriptMachine::instance().engine()); // TODO: set include callback // prepc.setIncludeCallback(); @@ -306,7 +307,7 @@ QList AsCompletion::parseDocument() { QList ret; for (auto &d : data) { - QAsCodeParser parser(_engine); + QAsCodeParser parser(ScriptMachine::instance().engine()); auto syms = parser.parseAndIntell(editor->textCursor().position(), d.script); diff --git a/src/class/ascompletion.h b/src/class/ascompletion.h index 4efc03f..4879de7 100644 --- a/src/class/ascompletion.h +++ b/src/class/ascompletion.h @@ -24,7 +24,7 @@ class AsCompletion : public WingCompleter { Q_OBJECT public: - explicit AsCompletion(asIScriptEngine *engine, WingCodeEdit *p); + explicit AsCompletion(WingCodeEdit *p); virtual ~AsCompletion(); @@ -56,7 +56,6 @@ private: private: ASDataBase parser; - asIScriptEngine *_engine; bool m_parseDocument; }; diff --git a/src/class/asconsolecompletion.cpp b/src/class/asconsolecompletion.cpp index a5386e8..e2e1b03 100644 --- a/src/class/asconsolecompletion.cpp +++ b/src/class/asconsolecompletion.cpp @@ -19,8 +19,7 @@ #include "control/scriptingconsole.h" -AsConsoleCompletion::AsConsoleCompletion(asIScriptEngine *engine, - ScriptingConsole *p) - : AsCompletion(engine, p), _console(p) { +AsConsoleCompletion::AsConsoleCompletion(ScriptingConsole *p) + : AsCompletion(p), _console(p) { setParseDocument(false); } diff --git a/src/class/asconsolecompletion.h b/src/class/asconsolecompletion.h index 7f7caf5..f0f6132 100644 --- a/src/class/asconsolecompletion.h +++ b/src/class/asconsolecompletion.h @@ -25,7 +25,7 @@ class ScriptingConsole; class AsConsoleCompletion : public AsCompletion { Q_OBJECT public: - explicit AsConsoleCompletion(asIScriptEngine *engine, ScriptingConsole *p); + explicit AsConsoleCompletion(ScriptingConsole *p); virtual ~AsConsoleCompletion() = default; private: diff --git a/src/class/ascontextmgr.cpp b/src/class/ascontextmgr.cpp index a9b2db8..7499de3 100644 --- a/src/class/ascontextmgr.cpp +++ b/src/class/ascontextmgr.cpp @@ -17,6 +17,25 @@ #include "ascontextmgr.h" +// copy from base class +struct SContextInfo { + asUINT sleepUntil; + std::vector coRoutines; + asUINT currentCoRoutine; + asIScriptContext *keepCtxAfterExecution; +}; + asContextMgr::asContextMgr() : CContextMgr() {} -bool asContextMgr::isRunning() const { return !m_threads.empty(); } +bool asContextMgr::findThreadWithUserData(asPWORD index, void *data) const { + for (auto &th : m_threads) { + auto ctx = th->keepCtxAfterExecution; + if (ctx) { + auto user = ctx->GetUserData(index); + if (user == data) { + return true; + } + } + } + return false; +} diff --git a/src/class/ascontextmgr.h b/src/class/ascontextmgr.h index 813bbe2..d798321 100644 --- a/src/class/ascontextmgr.h +++ b/src/class/ascontextmgr.h @@ -24,7 +24,7 @@ class asContextMgr : public CContextMgr { public: asContextMgr(); - bool isRunning() const; + bool findThreadWithUserData(asPWORD index, void *data) const; }; #endif // ASCONTEXTMGR_H diff --git a/src/class/asdebugger.cpp b/src/class/asdebugger.cpp index 56b77b8..24b32f7 100644 --- a/src/class/asdebugger.cpp +++ b/src/class/asdebugger.cpp @@ -75,6 +75,12 @@ void asDebugger::lineCallback(asIScriptContext *ctx) { if (ctx == nullptr) return; + auto isDbg = reinterpret_cast( + ctx->GetUserData(AsUserDataType::UserData_isDbg)); + if (!isDbg) { + return; + } + const char *file = 0; int col = 0; int lineNbr = ctx->GetLineNumber(0, &col, &file); @@ -500,6 +506,8 @@ asDebugger::GCStatistic asDebugger::gcStatistics() { void asDebugger::runDebugAction(DebugAction action) { m_action = action; } +void asDebugger::resetState() { m_action = CONTINUE; } + void asDebugger::deleteDbgContextInfo(void *info) { if (info) { delete reinterpret_cast(info); diff --git a/src/class/asdebugger.h b/src/class/asdebugger.h index 05e1b89..f43dff6 100644 --- a/src/class/asdebugger.h +++ b/src/class/asdebugger.h @@ -116,6 +116,7 @@ public: void runDebugAction(DebugAction action); DebugAction currentState() const; + void resetState(); static void deleteDbgContextInfo(void *info); diff --git a/src/class/clangformatmanager.cpp b/src/class/clangformatmanager.cpp index f261752..ccb68ac 100644 --- a/src/class/clangformatmanager.cpp +++ b/src/class/clangformatmanager.cpp @@ -133,7 +133,7 @@ QString ClangFormatManager::formatCode(const QString &codes, bool &ok) { .arg(m_clangStyle) .arg(m_identWidth); auto ret = runClangFormat( - {style, QStringLiteral("--assume-filename=wing.cpp")}, codes, ok); + {style, QStringLiteral("--assume-filename=wing.cs")}, codes, ok); return ret; } else { return runClangFormat({}, codes, ok); diff --git a/src/class/pluginsystem.cpp b/src/class/pluginsystem.cpp index 939fbbf..bca36f2 100644 --- a/src/class/pluginsystem.cpp +++ b/src/class/pluginsystem.cpp @@ -21,6 +21,7 @@ #include "Qt-Advanced-Docking-System/src/DockAreaWidget.h" #include "class/languagemanager.h" #include "class/logger.h" +#include "class/scriptmachine.h" #include "class/settingmanager.h" #include "class/skinmanager.h" #include "class/wingcstruct.h" @@ -3886,6 +3887,8 @@ void PluginSystem::loadAllPlugin() { } } + Logger::newLine(); + // loading finished, delete the checking engine finalizeCheckingEngine(); } diff --git a/src/class/scriptconsolemachine.cpp b/src/class/scriptconsolemachine.cpp deleted file mode 100644 index 1cd7ce0..0000000 --- a/src/class/scriptconsolemachine.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/*============================================================================== -** Copyright (C) 2024-2027 WingSummer -** -** This program is free software: you can redistribute it and/or modify it under -** the terms of the GNU Affero General Public License as published by the Free -** Software Foundation, version 3. -** -** This program is distributed in the hope that it will be useful, but WITHOUT -** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -** details. -** -** You should have received a copy of the GNU Affero General Public License -** along with this program. If not, see . -** ============================================================================= -*/ - -#include "scriptconsolemachine.h" - -#include -#include - -ScriptConsoleMachine::ScriptConsoleMachine( - std::function &getInputFn, QObject *parent) - : ScriptMachine(getInputFn, parent) { - if (!ScriptConsoleMachine::configureEngine(engine())) { - destoryMachine(); - } - if (engine()) { - _model = new ScriptObjModel(engine(), debugger(), this); - } -} - -ScriptConsoleMachine::~ScriptConsoleMachine() {} - -bool ScriptConsoleMachine::executeCode(const QString &code) { - return execString(engine(), code); -} - -ScriptObjModel *ScriptConsoleMachine::model() const { return _model; } - -bool ScriptConsoleMachine::configureEngine(asIScriptEngine *engine) { - _clsfn = std::bind(&ScriptConsoleMachine::onClearConsole, this); - auto r = engine->RegisterGlobalFunction( - "void clear()", asMETHOD(decltype(_clsfn), operator()), - asCALL_THISCALL_ASGLOBAL, &_clsfn); - Q_ASSERT(r >= 0); - return r >= 0; -} - -bool ScriptConsoleMachine::execString(asIScriptEngine *engine, - const QString &code) { - auto mod = engine->GetModule("Console", asGM_CREATE_IF_NOT_EXISTS); - if (code.startsWith(QStringLiteral("addvar "))) { - auto varcmd = code.mid(7) + QStringLiteral(";"); - if (varcmd.length() == 1) { - MessageInfo info; - info.message = tr("EmptyDecl"); - emit onOutput(MessageType::Error, info); - return false; - } - auto ret = mod->CompileGlobalVar("addvar", varcmd.toUtf8(), 0) >= 0; - _model->updateData(); - return ret; - } else if (code.startsWith(QStringLiteral("rmvar "))) { - if (mod == nullptr || mod->GetGlobalVarCount() == 0) { - return false; - } - - // remove the tailing semi-colons - static QRegularExpression re(QStringLiteral(";+$")); - - auto varcmd = code.mid(6).remove(re); - for (auto &var : varcmd.split(' ', Qt::SkipEmptyParts)) { - int index = mod->GetGlobalVarIndexByName(var.toUtf8()); - if (index >= 0) { - mod->RemoveGlobalVar(index); - } - } - _model->updateData(); - return true; - } else if (code.startsWith(QStringLiteral("lsfn"))) { - if (code.trimmed().length() != 4) { - return false; - } - - QString str; - QTextStream s(&str); - asUINT n; - - // List the application registered functions - s << tr("Application functions:") << Qt::endl; - for (n = 0; n < engine->GetGlobalFunctionCount(); n++) { - asIScriptFunction *func = engine->GetGlobalFunctionByIndex(n); - - // Skip the functions that start with _ as these are not meant to be - // called explicitly by the user - if (func->GetName()[0] != '_') - s << QStringLiteral(" ") << func->GetDeclaration() << Qt::endl; - } - - // List the user functions in the module - if (mod) { - s << Qt::endl; - s << tr("User functions:") << Qt::endl; - for (n = 0; n < mod->GetFunctionCount(); n++) { - asIScriptFunction *func = mod->GetFunctionByIndex(n); - s << QStringLiteral(" ") << func->GetDeclaration() << Qt::endl; - } - } - - MessageInfo info; - info.message = str; - emit onOutput(MessageType::Info, info); - return true; - } else if (code.startsWith(QStringLiteral("lsvar"))) { - if (code.trimmed().length() != 5) { - return false; - } - - QString str; - QTextStream s(&str); - asUINT n; - - // List the application registered variables - s << tr("Application variables:") << Qt::endl; - for (n = 0; n < engine->GetGlobalPropertyCount(); n++) { - const char *name; - int typeId; - bool isConst; - engine->GetGlobalPropertyByIndex(n, &name, 0, &typeId, &isConst); - auto decl = - isConst ? QStringLiteral(" const ") : QStringLiteral(" "); - decl += engine->GetTypeDeclaration(typeId); - decl += QStringLiteral(" "); - decl += name; - s << decl << Qt::endl; - } - - // List the user variables in the module - if (mod) { - s << Qt::endl; - s << tr("User variables:") << Qt::endl; - for (n = 0; n < (asUINT)mod->GetGlobalVarCount(); n++) { - s << QStringLiteral(" ") << mod->GetGlobalVarDeclaration(n) - << Qt::endl; - } - } - - MessageInfo info; - info.message = str; - emit onOutput(MessageType::Info, info); - return true; - } else { - return ScriptMachine::executeCode(code); - } -} diff --git a/src/class/scriptconsolemachine.h b/src/class/scriptconsolemachine.h deleted file mode 100644 index 0f29c72..0000000 --- a/src/class/scriptconsolemachine.h +++ /dev/null @@ -1,50 +0,0 @@ -/*============================================================================== -** Copyright (C) 2024-2027 WingSummer -** -** This program is free software: you can redistribute it and/or modify it under -** the terms of the GNU Affero General Public License as published by the Free -** Software Foundation, version 3. -** -** This program is distributed in the hope that it will be useful, but WITHOUT -** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -** details. -** -** You should have received a copy of the GNU Affero General Public License -** along with this program. If not, see . -** ============================================================================= -*/ - -#ifndef SCRIPTCONSOLEMACHINE_H -#define SCRIPTCONSOLEMACHINE_H - -#include "model/scriptobjmodel.h" -#include "scriptmachine.h" - -class ScriptConsoleMachine : public ScriptMachine { - Q_OBJECT -public: - explicit ScriptConsoleMachine(std::function &getInputFn, - QObject *parent = nullptr); - virtual ~ScriptConsoleMachine(); - - virtual bool executeCode(const QString &code) override; - - ScriptObjModel *model() const; - -signals: - void onClearConsole(); - -protected: - virtual bool configureEngine(asIScriptEngine *engine) override; - -private: - bool execString(asIScriptEngine *engine, const QString &code); - -private: - ScriptObjModel *_model = nullptr; - - std::function _clsfn; -}; - -#endif // SCRIPTCONSOLEMACHINE_H diff --git a/src/class/scriptmachine.cpp b/src/class/scriptmachine.cpp index 665cf8f..27ef928 100644 --- a/src/class/scriptmachine.cpp +++ b/src/class/scriptmachine.cpp @@ -40,6 +40,7 @@ #include "scriptaddon/scriptregex.h" #include +#include ScriptMachine::~ScriptMachine() { if (_ctxMgr) { @@ -49,94 +50,119 @@ ScriptMachine::~ScriptMachine() { destoryMachine(); } -bool ScriptMachine::inited() { return _engine != nullptr; } +bool ScriptMachine::init() { + if (isInited()) { + return true; + } -bool ScriptMachine::isRunning() const { - return _debugger->getEngine() || _ctxMgr->isRunning(); + qRegisterMetaType(); + + _engine = asCreateScriptEngine(); + if (!ScriptMachine::configureEngine()) { + _engine->ShutDownAndRelease(); + _engine = nullptr; + return false; + } + + // Let the debugger hold an engine pointer that can be used by the + // callbacks + _debugger->setEngine(_engine); + + return true; } -bool ScriptMachine::configureEngine(asIScriptEngine *engine) { - if (engine == nullptr) { +bool ScriptMachine::isInited() const { return _engine != nullptr; } + +bool ScriptMachine::isRunning(ConsoleMode mode) const { + return _ctxMgr->findThreadWithUserData( + AsUserDataType::UserData_ContextMode, + reinterpret_cast(asPWORD(mode))); +} + +bool ScriptMachine::configureEngine() { + if (_engine == nullptr) { return false; } // we need utf8, the default is what we want - engine->SetEngineProperty(asEP_EXPAND_DEF_ARRAY_TO_TMPL, true); - engine->SetEngineProperty(asEP_DISALLOW_EMPTY_LIST_ELEMENTS, true); - engine->SetEngineProperty(asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE, false); - engine->SetEngineProperty(asEP_ALLOW_MULTILINE_STRINGS, false); - engine->SetEngineProperty(asEP_USE_CHARACTER_LITERALS, false); - engine->SetEngineProperty(asEP_DISABLE_INTEGER_DIVISION, false); - engine->SetEngineProperty(asEP_PRIVATE_PROP_AS_PROTECTED, false); - engine->SetEngineProperty(asEP_ALTER_SYNTAX_NAMED_ARGS, 0); - engine->SetEngineProperty(asEP_ALLOW_UNICODE_IDENTIFIERS, true); - engine->SetEngineProperty(asEP_REQUIRE_ENUM_SCOPE, true); // enum class like - setDebugMode(false); + _engine->SetEngineProperty(asEP_EXPAND_DEF_ARRAY_TO_TMPL, true); + _engine->SetEngineProperty(asEP_DISALLOW_EMPTY_LIST_ELEMENTS, true); + _engine->SetEngineProperty(asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE, false); + _engine->SetEngineProperty(asEP_ALLOW_MULTILINE_STRINGS, false); + _engine->SetEngineProperty(asEP_USE_CHARACTER_LITERALS, false); + _engine->SetEngineProperty(asEP_DISABLE_INTEGER_DIVISION, false); + _engine->SetEngineProperty(asEP_PRIVATE_PROP_AS_PROTECTED, false); + _engine->SetEngineProperty(asEP_ALTER_SYNTAX_NAMED_ARGS, 0); + _engine->SetEngineProperty(asEP_ALLOW_UNICODE_IDENTIFIERS, true); + _engine->SetEngineProperty(asEP_REQUIRE_ENUM_SCOPE, + true); // enum class like + + // We will only initialize the global variables once we're + // ready to execute, so disable the automatic initialization + _engine->SetEngineProperty(asEP_INIT_GLOBAL_VARS_AFTER_BUILD, false); // The script compiler will send any compiler messages to the callback - auto r = engine->SetMessageCallback(asFUNCTION(messageCallback), this, - asCALL_CDECL); + auto r = _engine->SetMessageCallback(asFUNCTION(messageCallback), this, + asCALL_CDECL); Q_ASSERT(r >= 0); if (r < 0) { return false; } - engine->SetContextUserDataCleanupCallback( + _engine->SetContextUserDataCleanupCallback( &ScriptMachine::cleanUpDbgContext, AsUserDataType::UserData_ContextDbgInfo); - engine->SetFunctionUserDataCleanupCallback( + _engine->SetFunctionUserDataCleanupCallback( &ScriptMachine::cleanUpPluginSysIDFunction, AsUserDataType::UserData_PluginFn); - registerEngineAddon(engine); + registerEngineAddon(_engine); _rtypes.resize(RegisteredType::tMAXCOUNT); _rtypes[RegisteredType::tString] = - q_check_ptr(engine->GetTypeInfoByName("string")); + q_check_ptr(_engine->GetTypeInfoByName("string")); _rtypes[RegisteredType::tChar] = - q_check_ptr(engine->GetTypeInfoByName("char")); + q_check_ptr(_engine->GetTypeInfoByName("char")); _rtypes[RegisteredType::tArray] = - q_check_ptr(engine->GetTypeInfoByName("array")); + q_check_ptr(_engine->GetTypeInfoByName("array")); _rtypes[RegisteredType::tComplex] = - q_check_ptr(engine->GetTypeInfoByName("complex")); + q_check_ptr(_engine->GetTypeInfoByName("complex")); _rtypes[RegisteredType::tWeakref] = - q_check_ptr(engine->GetTypeInfoByName("weakref")); + q_check_ptr(_engine->GetTypeInfoByName("weakref")); _rtypes[RegisteredType::tConstWeakref] = - q_check_ptr(engine->GetTypeInfoByName("const_weakref")); + q_check_ptr(_engine->GetTypeInfoByName("const_weakref")); _rtypes[RegisteredType::tAny] = - q_check_ptr(engine->GetTypeInfoByName("any")); + q_check_ptr(_engine->GetTypeInfoByName("any")); _rtypes[RegisteredType::tDictionary] = - q_check_ptr(engine->GetTypeInfoByName("dictionary")); + q_check_ptr(_engine->GetTypeInfoByName("dictionary")); _rtypes[RegisteredType::tDictionaryValue] = - q_check_ptr(engine->GetTypeInfoByName("dictionaryValue")); + q_check_ptr(_engine->GetTypeInfoByName("dictionaryValue")); _rtypes[RegisteredType::tGrid] = - q_check_ptr(engine->GetTypeInfoByName("grid")); + q_check_ptr(_engine->GetTypeInfoByName("grid")); _rtypes[RegisteredType::tRef] = - q_check_ptr(engine->GetTypeInfoByName("ref")); + q_check_ptr(_engine->GetTypeInfoByName("ref")); _rtypes[RegisteredType::tColor] = - q_check_ptr(engine->GetTypeInfoByName("color")); + q_check_ptr(_engine->GetTypeInfoByName("color")); // Register a couple of extra functions for the scripts - _printFn = std::bind(&ScriptMachine::print, this, std::placeholders::_1, - std::placeholders::_2); - r = engine->RegisterGlobalFunction("void print(? &in obj)", - asMETHOD(decltype(_printFn), operator()), - asCALL_THISCALL_ASGLOBAL, &_printFn); + r = _engine->RegisterGlobalFunction("void print(? &in obj)", + asMETHOD(ScriptMachine, print), + asCALL_THISCALL_ASGLOBAL, this); Q_ASSERT(r >= 0); if (r < 0) { return false; } - r = engine->RegisterGlobalFunction( - "string getInput()", asMETHOD(decltype(_getInputFn), operator()), - asCALL_THISCALL_ASGLOBAL, &_getInputFn); - assert(r >= 0); + r = _engine->RegisterGlobalFunction("string getInput()", + asMETHOD(ScriptMachine, getInput), + asCALL_THISCALL_ASGLOBAL, this); + Q_ASSERT(r >= 0); if (r < 0) { return false; } - r = engine->RegisterGlobalFunction( + r = _engine->RegisterGlobalFunction( "int exec(string &out output, const string &in exe, " "const string &in params = \"\", int timeout = 3000)", asFUNCTION(execSystemCmd), asCALL_CDECL); @@ -147,12 +173,12 @@ bool ScriptMachine::configureEngine(asIScriptEngine *engine) { // Setup the context manager and register the support for co-routines _ctxMgr = new asContextMgr(); - _ctxMgr->RegisterCoRoutineSupport(engine); + _ctxMgr->RegisterCoRoutineSupport(_engine); // Tell the engine to use our context pool. This will also // allow us to debug internal script calls made by the engine - r = engine->SetContextCallbacks(requestContextCallback, - returnContextCallback, this); + r = _engine->SetContextCallbacks(requestContextCallback, + returnContextCallback, this); Q_ASSERT(r >= 0); if (r < 0) { return false; @@ -160,8 +186,8 @@ bool ScriptMachine::configureEngine(asIScriptEngine *engine) { _debugger = new asDebugger(this); - // Register the to-string callbacks so the user can see the contents of - // strings + // Register the to-string callbacks so the user can see + // the contents of strings _debugger->registerToStringCallback(_rtypes[RegisteredType::tString], &AngelObjString::stringToString); _debugger->registerToStringCallback(_rtypes[RegisteredType::tChar], @@ -175,6 +201,9 @@ bool ScriptMachine::configureEngine(asIScriptEngine *engine) { PluginSystem::instance().angelApi()->installAPI(this); + // create module for Console + _engine->GetModule("WINGCONSOLE", asGM_ALWAYS_CREATE); + return true; } @@ -198,34 +227,64 @@ QString ScriptMachine::getCallStack(asIScriptContext *context) { } void ScriptMachine::destoryMachine() { + _debugger->setEngine(nullptr); _engine->ShutDownAndRelease(); _engine = nullptr; } void ScriptMachine::exceptionCallback(asIScriptContext *context) { - QString message = - tr("- Exception '%1' in '%2'\n") - .arg(context->GetExceptionString(), - context->GetExceptionFunction()->GetDeclaration()) + - QStringLiteral("\n") + getCallStack(context); + if (context) { + ConsoleMode mode = ConsoleMode(reinterpret_cast( + context->GetUserData(AsUserDataType::UserData_ContextMode))); + QString message = + tr("- Exception '%1' in '%2'\n") + .arg(context->GetExceptionString(), + context->GetExceptionFunction()->GetDeclaration()) + + QStringLiteral("\n") + getCallStack(context); - const char *section; - MessageInfo msg; - msg.row = context->GetExceptionLineNumber(&msg.col, §ion); - msg.type = asMSGTYPE_ERROR; - msg.message = message; - emit onOutput(MessageType::Error, msg); + const char *section; + MessageInfo msg; + msg.row = context->GetExceptionLineNumber(&msg.col, §ion); + msg.type = MessageType::Error; + msg.message = message; + + outputMessage(mode, msg); + } } void ScriptMachine::print(void *ref, int typeId) { - MessageInfo info; - info.message = _debugger->toString(ref, typeId, _engine); - emit onOutput(MessageType::Print, info); + auto context = asGetActiveContext(); + if (context) { + ConsoleMode mode = ConsoleMode(reinterpret_cast( + context->GetUserData(AsUserDataType::UserData_ContextMode))); + + MessageInfo info; + info.type = MessageType::Print; + info.message = _debugger->toString(ref, typeId, _engine); + + outputMessage(mode, info); + } } QString ScriptMachine::getInput() { - Q_ASSERT(_getInputFn); - return _getInputFn(); + auto context = asGetActiveContext(); + if (context) { + ConsoleMode mode = ConsoleMode(reinterpret_cast( + context->GetUserData(AsUserDataType::UserData_ContextMode))); + + auto cbs = _regcalls.value(mode); + if (cbs.getInputFn) { + return cbs.getInputFn(); + } + } + return {}; +} + +void ScriptMachine::outputMessage(ConsoleMode mode, const MessageInfo &info) { + auto cbs = _regcalls.value(mode); + if (cbs.printMsgFn) { + cbs.printMsgFn(info); + } } bool ScriptMachine::isType(asITypeInfo *tinfo, RegisteredType type) { @@ -257,11 +316,32 @@ int ScriptMachine::execSystemCmd(QString &out, const QString &exe, } } -bool ScriptMachine::executeScript(const QString &script, bool isInDebug) { - // We will only initialize the global variables once we're - // ready to execute, so disable the automatic initialization - _engine->SetEngineProperty(asEP_INIT_GLOBAL_VARS_AFTER_BUILD, false); - setDebugMode(isInDebug); +bool ScriptMachine::executeScript(ConsoleMode mode, const QString &script, + bool isInDebug) { + // Compile the script + auto mod = createModule(mode); + // script-running is not allowed in interactive mode + if (mod == nullptr) { + return false; + } + + QScopeGuard guard([mod, mode]() { + if (mode != ConsoleMode::Interactive) { + // Before leaving, allow the engine to clean up remaining objects by + // discarding the module and doing a full garbage collection so that + // this can also be debugged if desired + mod->Discard(); + } + }); + + asPWORD isDbg = 0; + if (mode == Scripting) { + if (isInDebug) { + isDbg = 1; + _debugger->resetState(); + } + } + _engine->SetEngineProperty(asEP_BUILD_WITHOUT_LINE_CUES, isDbg == 0); asBuilder builder(_engine); for (auto &m : PluginSystem::instance().scriptMarcos()) { @@ -272,27 +352,17 @@ bool ScriptMachine::executeScript(const QString &script, bool isInDebug) { builder.setPragmaCallback(&ScriptMachine::pragmaCallback, this); builder.setIncludeCallback(&ScriptMachine::includeCallback, this); - // Compile the script - auto r = builder.StartNewModule("script"); + auto r = builder.loadSectionFromFile(script.toUtf8()); if (r < 0) { return false; } - r = builder.loadSectionFromFile(script.toUtf8()); - if (r < 0) { - return false; - } - - r = builder.Build(); + r = builder.build(mod); if (r < 0) { MessageInfo info; info.message = tr("Script failed to build"); - emit onOutput(MessageType::Error, info); - return false; - } - - asIScriptModule *mod = builder.GetModule(); - if (!mod) { + info.type = MessageType::Error; + outputMessage(mode, info); return false; } @@ -306,19 +376,17 @@ bool ScriptMachine::executeScript(const QString &script, bool isInDebug) { if (func == nullptr) { MessageInfo info; info.message = tr("Cannot find 'int main()' or 'void main()'"); - emit onOutput(MessageType::Error, info); + info.type = MessageType::Error; + outputMessage(mode, info); return false; } - // Let the debugger hold an engine pointer that can be used by the - // callbacks - _debugger->setEngine(_engine); - if (isInDebug) { // Allow the user to initialize the debugging before moving on MessageInfo info; info.message = tr("Debugging, waiting for commands."); - emit onOutput(MessageType::Info, info); + info.type = MessageType::Info; + outputMessage(mode, info); } // Once we have the main function, we first need to initialize the global @@ -328,7 +396,8 @@ bool ScriptMachine::executeScript(const QString &script, bool isInDebug) { if (r < 0) { MessageInfo info; info.message = tr("Failed while initializing global variables"); - emit onOutput(MessageType::Error, info); + info.type = MessageType::Error; + outputMessage(mode, info); return false; } @@ -336,6 +405,16 @@ bool ScriptMachine::executeScript(const QString &script, bool isInDebug) { // The context manager will request the context from the // pool, which will automatically attach the debugger asIScriptContext *ctx = _ctxMgr->AddContext(_engine, func, true); + + ctx->SetUserData(reinterpret_cast(isDbg), + AsUserDataType::UserData_isDbg); + mod->SetUserData(reinterpret_cast(isDbg), + AsUserDataType::UserData_isDbg); + + asPWORD umode = asPWORD(mode); + ctx->SetUserData(reinterpret_cast(umode), + AsUserDataType::UserData_ContextMode); + ctx->SetExceptionCallback(asMETHOD(ScriptMachine, exceptionCallback), this, asCALL_THISCALL); @@ -353,12 +432,14 @@ bool ScriptMachine::executeScript(const QString &script, bool isInDebug) { info.message = tr("The script failed with an exception") + QStringLiteral("\n") + QString::fromStdString(GetExceptionInfo(ctx, true)); - emit onOutput(MessageType::Error, info); + info.type = MessageType::Error; + outputMessage(mode, info); r = -1; } else if (r == asEXECUTION_ABORTED) { MessageInfo info; info.message = tr("The script was aborted"); - emit onOutput(MessageType::Error, info); + info.type = MessageType::Error; + outputMessage(mode, info); r = -1; } else { auto e = QMetaEnum::fromType(); @@ -366,7 +447,8 @@ bool ScriptMachine::executeScript(const QString &script, bool isInDebug) { info.message = tr("The script terminated unexpectedly") + QStringLiteral(" (") + e.valueToKey(r) + QStringLiteral(")"); - emit onOutput(MessageType::Error, info); + info.type = MessageType::Error; + outputMessage(mode, info); r = -1; } } else { @@ -379,7 +461,8 @@ bool ScriptMachine::executeScript(const QString &script, bool isInDebug) { MessageInfo info; info.message = tr("The script exited with ") + QString::number(r); - emit onOutput(MessageType::Info, info); + info.type = MessageType::Info; + outputMessage(mode, info); // Return the context after retrieving the return value _ctxMgr->DoneWithContext(ctx); @@ -389,31 +472,21 @@ bool ScriptMachine::executeScript(const QString &script, bool isInDebug) { // this can also be debugged if desired _engine->GarbageCollect(); - // Release all contexts that have been allocated - for (auto &ctx : _ctxPool) { - ctx->Release(); - } - - _ctxPool.clear(); - - // Detach debugger - Q_ASSERT(_debugger); - _debugger->setEngine(nullptr); - - if (isInDebug) { + if (isDbg) { _debugger->clearBreakPoint(); - setDebugMode(false); emit onDebugFinished(); } return r >= 0; } -void ScriptMachine::abortScript() { +void ScriptMachine::abortDbgScript(ConsoleMode mode) { if (_debugger->getEngine()) { _debugger->runDebugAction(asDebugger::ABORT); } } +void ScriptMachine::abortScript() { _ctxMgr->AbortAll(); } + void ScriptMachine::messageCallback(const asSMessageInfo *msg, void *param) { MessageType t = MessageType::Print; switch (msg->type) { @@ -438,7 +511,8 @@ void ScriptMachine::messageCallback(const asSMessageInfo *msg, void *param) { info.col = msg->col; info.section = msg->section; info.message = m; - emit ins->onOutput(t, info); + info.type = t; + ins->outputMessage(ins->_curMode, info); } void ScriptMachine::cleanUpDbgContext(asIScriptContext *context) { @@ -460,17 +534,56 @@ asITypeInfo *ScriptMachine::typeInfo(RegisteredType type) const { return nullptr; } -ScriptMachine::ScriptMachine(const std::function &getInputFn, - QObject *parent) - : QObject(parent), _getInputFn(getInputFn) { - Q_ASSERT(getInputFn); - qRegisterMetaType(); +ScriptMachine &ScriptMachine::instance() { + static ScriptMachine ins; + return ins; +} - _engine = asCreateScriptEngine(); - if (!ScriptMachine::configureEngine(_engine)) { - _engine->ShutDownAndRelease(); - _engine = nullptr; +ScriptMachine::ScriptMachine() : QObject() {} + +asIScriptModule *ScriptMachine::createModule(ConsoleMode mode) { + if (isModuleExists(mode)) { + return nullptr; } + switch (mode) { + case Interactive: + return nullptr; + case Scripting: + return _engine->GetModule("WINGSCRIPT", asGM_ALWAYS_CREATE); + case Background: + return _engine->GetModule("WINGSRV", asGM_ALWAYS_CREATE); + } + // should not go there + return nullptr; +} + +asIScriptModule *ScriptMachine::createModuleIfNotExist(ConsoleMode mode) { + switch (mode) { + case Interactive: + return _engine->GetModule("WINGCONSOLE", asGM_ONLY_IF_EXISTS); + case Scripting: + return _engine->GetModule("WINGSCRIPT", asGM_CREATE_IF_NOT_EXISTS); + case Background: + return _engine->GetModule("WINGSRV", asGM_CREATE_IF_NOT_EXISTS); + } + // should not go there + return nullptr; +} + +asIScriptModule *ScriptMachine::module(ConsoleMode mode) { + switch (mode) { + case Interactive: + return _engine->GetModule("WINGCONSOLE", asGM_ONLY_IF_EXISTS); + case Scripting: + return _engine->GetModule("WINGSCRIPT", asGM_ONLY_IF_EXISTS); + case Background: + return _engine->GetModule("WINGSRV", asGM_ONLY_IF_EXISTS); + } + return nullptr; +} + +bool ScriptMachine::isModuleExists(ConsoleMode mode) { + return module(mode) != nullptr; } asIScriptContext *ScriptMachine::requestContextCallback(asIScriptEngine *engine, @@ -808,8 +921,6 @@ QString ScriptMachine::processTranslation(const char *content, }}, {QRegularExpression(QStringLiteral("^Instead found '(.*?)'")), [machine](const QStringList &contents) -> QString { - if (machine->m_insteadFoundDisabled) - return {}; return tr("Instead found '%1'").arg(contents.at(1)); }}, {QRegularExpression( @@ -1588,14 +1699,6 @@ void ScriptMachine::translation() { tr("Too many nested calls"); } -bool ScriptMachine::insteadFoundDisabled() const { - return m_insteadFoundDisabled; -} - -void ScriptMachine::setInsteadFoundDisabled(bool newInsteadFoundDisabled) { - m_insteadFoundDisabled = newInsteadFoundDisabled; -} - void ScriptMachine::registerEngineAddon(asIScriptEngine *engine) { RegisterScriptArray(engine, true); RegisterQString(engine); @@ -1649,6 +1752,11 @@ void ScriptMachine::registerEngineAssert(asIScriptEngine *engine) { } } +void ScriptMachine::registerCallBack(ConsoleMode mode, + const RegCallBacks &callbacks) { + _regcalls.insert(mode, callbacks); +} + void ScriptMachine::scriptAssert(bool b) { auto ctx = asGetActiveContext(); if (ctx) { @@ -1679,28 +1787,35 @@ void ScriptMachine::scriptThrow(const QString &msg) { } } -bool ScriptMachine::isDebugMode() const { - return !_engine->GetEngineProperty(asEP_BUILD_WITHOUT_LINE_CUES); -} +bool ScriptMachine::isDebugMode(ConsoleMode mode) { + if (mode == Scripting) { + auto mod = module(mode); + if (mod) { + return reinterpret_cast( + mod->GetUserData(AsUserDataType::UserData_isDbg)); + } + } -void ScriptMachine::setDebugMode(bool isDbg) { - _engine->SetEngineProperty(asEP_BUILD_WITHOUT_LINE_CUES, !isDbg); + return false; } asIScriptEngine *ScriptMachine::engine() const { return _engine; } asDebugger *ScriptMachine::debugger() const { return _debugger; } -bool ScriptMachine::executeCode(const QString &code) { - // We will only initialize the global variables once we're - // ready to execute, so disable the automatic initialization - _engine->SetEngineProperty(asEP_INIT_GLOBAL_VARS_AFTER_BUILD, false); - setDebugMode(false); +bool ScriptMachine::executeCode(ConsoleMode mode, const QString &code) { + asIScriptModule *mod = createModuleIfNotExist(mode); - asIScriptModule *mod = _engine->GetModule("Console", asGM_ONLY_IF_EXISTS); - if (!mod) { - return false; - } + QScopeGuard guard([mod, mode]() { + if (mode != ConsoleMode::Interactive) { + // Before leaving, allow the engine to clean up remaining objects by + // discarding the module and doing a full garbage collection so that + // this can also be debugged if desired + mod->Discard(); + } + }); + + _engine->SetEngineProperty(asEP_BUILD_WITHOUT_LINE_CUES, false); // first, preparse the code QAsCodeParser parser(_engine); @@ -1717,9 +1832,10 @@ bool ScriptMachine::executeCode(const QString &code) { auto r = mod->CompileFunction(nullptr, ccode, -1, 0, &func); if (r < 0) { MessageInfo info; + info.mode = mode; info.message = tr("Script failed to build"); - emit onOutput(MessageType::Error, info); - mod->Discard(); + info.type = MessageType::Error; + outputMessage(mode, info); return false; } } else { @@ -1728,9 +1844,10 @@ bool ScriptMachine::executeCode(const QString &code) { auto r = mod->Build(); if (r < 0) { MessageInfo info; + info.mode = mode; info.message = tr("Script failed to build"); - emit onOutput(MessageType::Error, info); - mod->Discard(); + info.type = MessageType::Error; + outputMessage(mode, info); return false; } @@ -1743,21 +1860,29 @@ bool ScriptMachine::executeCode(const QString &code) { if (func == nullptr) { MessageInfo info; + info.mode = mode; info.message = tr("Cannot find 'int main()' or 'void main()'"); - emit onOutput(MessageType::Error, info); - mod->Discard(); + info.type = MessageType::Error; + outputMessage(mode, info); return false; } } - // Let the debugger hold an engine pointer that can be used by the - // callbacks - _debugger->setEngine(_engine); - // Set up a context to execute the script // The context manager will request the context from the // pool, which will automatically attach the debugger asIScriptContext *ctx = _ctxMgr->AddContext(_engine, func, true); + + asPWORD isDbg = 0; + ctx->SetUserData(reinterpret_cast(isDbg), + AsUserDataType::UserData_isDbg); + mod->SetUserData(reinterpret_cast(isDbg), + AsUserDataType::UserData_isDbg); + + asPWORD umode = asPWORD(mode); + ctx->SetUserData(reinterpret_cast(umode), + AsUserDataType::UserData_ContextMode); + ctx->SetExceptionCallback(asMETHOD(ScriptMachine, exceptionCallback), this, asCALL_THISCALL); @@ -1772,15 +1897,19 @@ bool ScriptMachine::executeCode(const QString &code) { if (r != asEXECUTION_FINISHED) { if (r == asEXECUTION_EXCEPTION) { MessageInfo info; + info.mode = mode; info.message = tr("The script failed with an exception") + QStringLiteral("\n") + QString::fromStdString(GetExceptionInfo(ctx, true)); - emit onOutput(MessageType::Error, info); + info.type = MessageType::Error; + outputMessage(mode, info); r = -1; } else if (r == asEXECUTION_ABORTED) { MessageInfo info; + info.mode = mode; info.message = tr("The script was aborted"); - emit onOutput(MessageType::Error, info); + info.type = MessageType::Error; + outputMessage(mode, info); r = -1; } else { auto e = QMetaEnum::fromType(); @@ -1788,7 +1917,8 @@ bool ScriptMachine::executeCode(const QString &code) { info.message = tr("The script terminated unexpectedly") + QStringLiteral(" (") + e.valueToKey(r) + QStringLiteral(")"); - emit onOutput(MessageType::Error, info); + info.type = MessageType::Error; + outputMessage(mode, info); r = -1; } } else { @@ -1797,24 +1927,8 @@ bool ScriptMachine::executeCode(const QString &code) { // Return the context after retrieving the return value _ctxMgr->DoneWithContext(ctx); - - // Before leaving, allow the engine to clean up remaining objects by - // discarding the module and doing a full garbage collection so that - // this can also be debugged if desired - mod->Discard(); _engine->GarbageCollect(); - // Release all contexts that have been allocated - for (auto ctx : std::as_const(_ctxPool)) { - ctx->Release(); - } - - _ctxPool.clear(); - - // Detach debugger - Q_ASSERT(_debugger); - _debugger->setEngine(nullptr); - return r >= 0; } diff --git a/src/class/scriptmachine.h b/src/class/scriptmachine.h index 0186153..4fd0f11 100644 --- a/src/class/scriptmachine.h +++ b/src/class/scriptmachine.h @@ -31,14 +31,23 @@ class ScriptMachine : public QObject { private: using TranslateFunc = std::function; +public: + // we have three console modes + enum ConsoleMode { + Interactive, // in a shell + Scripting, // in scripting dialog + Background // run codes from other way + }; + public: enum class MessageType { Info, Warn, Error, Print }; struct MessageInfo { + ConsoleMode mode = ConsoleMode::Background; QString section; int row = -1; int col = -1; - asEMsgType type = asEMsgType::asMSGTYPE_INFORMATION; + MessageType type = MessageType::Info; QString message; }; @@ -78,25 +87,42 @@ public: Q_ENUM(asEContextState) public: - explicit ScriptMachine(const std::function &getInputFn, - QObject *parent = nullptr); + struct RegCallBacks { + std::function getInputFn; + std::function clearFn; + std::function printMsgFn; + }; + +private: + explicit ScriptMachine(); + Q_DISABLE_COPY_MOVE(ScriptMachine) + +public: + asIScriptModule *createModule(ConsoleMode mode); + asIScriptModule *createModuleIfNotExist(ConsoleMode mode); + asIScriptModule *module(ConsoleMode mode); + bool isModuleExists(ConsoleMode mode); + +public: + static ScriptMachine &instance(); virtual ~ScriptMachine(); - bool inited(); - - bool isRunning() const; - - asDebugger *debugger() const; - - asIScriptEngine *engine() const; - - bool insteadFoundDisabled() const; - void setInsteadFoundDisabled(bool newInsteadFoundDisabled); +public: + bool init(); + bool isInited() const; + bool isRunning(ConsoleMode mode = Scripting) const; static void registerEngineAddon(asIScriptEngine *engine); static void registerEngineAssert(asIScriptEngine *engine); + void registerCallBack(ConsoleMode mode, const RegCallBacks &callbacks); + +public: + asDebugger *debugger() const; + + asIScriptEngine *engine() const; + public: static void scriptAssert(bool b); static void scriptAssert_X(bool b, const QString &msg); @@ -109,20 +135,19 @@ public: public: // debug or release? - bool isDebugMode() const; - void setDebugMode(bool isDbg); + bool isDebugMode(ConsoleMode mode = Scripting); public slots: - virtual bool executeCode(const QString &code); - virtual bool executeScript(const QString &script, bool isInDebug = false); + bool executeCode(ConsoleMode mode, const QString &code); + // only scripting mode can be debugged + bool executeScript(ConsoleMode mode, const QString &script, + bool isInDebug = false); + void abortDbgScript(ConsoleMode mode); void abortScript(); -private: - bool execute(const QString &code, bool isInDebug = false); - protected: - virtual bool configureEngine(asIScriptEngine *engine); + bool configureEngine(); QString getCallStack(asIScriptContext *context); @@ -130,8 +155,8 @@ protected: private: void print(void *ref, int typeId); - QString getInput(); + void outputMessage(ConsoleMode mode, const MessageInfo &info); bool isType(asITypeInfo *tinfo, RegisteredType type); @@ -166,8 +191,6 @@ private: Q_DECL_UNUSED void translation(); signals: - void onOutput(MessageType type, const MessageInfo &message); - void onDebugFinished(); private: @@ -175,12 +198,10 @@ private: asDebugger *_debugger = nullptr; asContextMgr *_ctxMgr = nullptr; QVector _ctxPool; - std::function _printFn; QVector _rtypes; - std::function _getInputFn; - - bool m_insteadFoundDisabled = false; + QMap _regcalls; + ConsoleMode _curMode = ConsoleMode::Background; }; Q_DECLARE_METATYPE(ScriptMachine::MessageInfo) diff --git a/src/class/scriptmanager.cpp b/src/class/scriptmanager.cpp index 0e9bf4b..e706b3b 100644 --- a/src/class/scriptmanager.cpp +++ b/src/class/scriptmanager.cpp @@ -25,6 +25,7 @@ #include #include +#include "scriptmachine.h" #include "settingmanager.h" #include "utilities.h" #include "wingmessagebox.h" @@ -50,7 +51,7 @@ ScriptManager::ScriptManager() : QObject() { refresh(); } -ScriptManager::~ScriptManager() { detach(); } +ScriptManager::~ScriptManager() {} QStringList ScriptManager::getScriptFileNames(const QDir &dir) const { if (!dir.exists()) { @@ -206,14 +207,6 @@ ScriptManager::ensureDirMeta(const QFileInfo &info) { return meta; } -void ScriptManager::attach(ScriptingConsole *console) { - if (console) { - _console = console; - } -} - -void ScriptManager::detach() { _console = nullptr; } - ScriptManager::ScriptDirMeta ScriptManager::usrDirMeta(const QString &cat) const { return _usrDirMetas.value(cat); @@ -257,13 +250,16 @@ ScriptManager::buildUpRibbonScriptRunner(RibbonButtonGroup *group) { } void ScriptManager::runScript(const QString &filename) { - Q_ASSERT(_console); - _console->setMode(ScriptingConsole::Output); - _console->stdWarn(tr("Excuting:") + filename); - _console->newLine(); - _console->machine()->executeScript(filename); - _console->appendCommandPrompt(); - _console->setMode(ScriptingConsole::Input); + // ScriptMachine::instance().executeScript(filename); + + // Q_ASSERT(_console); + // _console->setMode(ScriptingConsole::Output); + // _console->stdWarn(tr("Excuting:") + filename); + // _console->newLine(); + // // TODO + // // _console->machine()->executeScript(filename); + // _console->appendCommandPrompt(); + // _console->setMode(ScriptingConsole::Input); } QStringList ScriptManager::usrScriptsDbCats() const { diff --git a/src/class/scriptmanager.h b/src/class/scriptmanager.h index 32dd0b0..7726946 100644 --- a/src/class/scriptmanager.h +++ b/src/class/scriptmanager.h @@ -65,9 +65,6 @@ public: void refreshUsrScriptsDbCats(); void refreshSysScriptsDbCats(); - void attach(ScriptingConsole *console); - void detach(); - ScriptDirMeta usrDirMeta(const QString &cat) const; ScriptDirMeta sysDirMeta(const QString &cat) const; @@ -133,8 +130,6 @@ private: QHash _usrDirMetas; QHash _sysDirMetas; - - ScriptingConsole *_console = nullptr; }; Q_DECLARE_METATYPE(ScriptManager::ScriptDirMeta) diff --git a/src/class/wingangelapi.cpp b/src/class/wingangelapi.cpp index ea2fc62..bb500ed 100644 --- a/src/class/wingangelapi.cpp +++ b/src/class/wingangelapi.cpp @@ -24,7 +24,6 @@ #include "class/scriptmachine.h" #include "class/wingfiledialog.h" #include "class/winginputdialog.h" -#include "control/scriptingconsole.h" #include "define.h" #include "scriptaddon/scriptqdictionary.h" @@ -2084,44 +2083,35 @@ bool WingAngelAPI::execScriptCode(const WingHex::SenderInfo &sender, return true; } - if (_console) { - QTemporaryFile f; - if (f.open()) { - f.write(code.toUtf8()); - f.close(); - } - - _console->setMode(ScriptingConsole::Output); - _console->stdOut(getSenderHeader(sender)); - auto handles = _handles; - _console->machine()->executeScript(f.fileName()); - cleanUpHandles(handles); - _console->appendCommandPrompt(); - _console->setMode(ScriptingConsole::Input); + QTemporaryFile f; + if (f.open()) { + f.write(code.toUtf8()); + f.close(); } + auto handles = _handles; + ScriptMachine::instance().executeScript(ScriptMachine::Background, + f.fileName()); + cleanUpHandles(handles); + return false; } bool WingAngelAPI::execScript(const WingHex::SenderInfo &sender, const QString &fileName) { - _console->setMode(ScriptingConsole::Output); - _console->stdOut(getSenderHeader(sender)); auto handles = _handles; - auto ret = _console->machine()->executeScript(fileName); + auto ret = ScriptMachine::instance().executeScript( + ScriptMachine::Background, fileName); cleanUpHandles(handles); - _console->appendCommandPrompt(); - _console->setMode(ScriptingConsole::Input); return ret; } bool WingAngelAPI::execCode(const WingHex::SenderInfo &sender, const QString &code) { - _console->setMode(ScriptingConsole::Output); - _console->stdOut(getSenderHeader(sender)); - auto ret = _console->machine()->executeCode(code); - _console->appendCommandPrompt(); - _console->setMode(ScriptingConsole::Input); + auto handles = _handles; + auto ret = + ScriptMachine::instance().executeCode(ScriptMachine::Background, code); + cleanUpHandles(handles); return ret; } @@ -2175,7 +2165,7 @@ void *WingAngelAPI::vector2AsArray(const WingHex::SenderInfo &sender, return nullptr; } - auto engine = _console->machine()->engine(); + auto engine = ScriptMachine::instance().engine(); auto info = engine->GetTypeInfoByDecl(typeStr.toUtf8()); if (info) { auto len = content.length(); @@ -2197,7 +2187,7 @@ void *WingAngelAPI::list2AsArray(const WingHex::SenderInfo &sender, return nullptr; } - auto engine = _console->machine()->engine(); + auto engine = ScriptMachine::instance().engine(); auto info = engine->GetTypeInfoByDecl(typeStr.toUtf8()); if (info) { auto len = content.length(); @@ -2222,7 +2212,7 @@ void *WingAngelAPI::newAsDictionary( const WingHex::SenderInfo &sender, const QHash> &content) { Q_UNUSED(sender); - auto engine = _console->machine()->engine(); + auto engine = ScriptMachine::instance().engine(); auto dic = CScriptDictionary::Create(engine); for (auto p = content.constKeyValueBegin(); p != content.constKeyValueEnd(); @@ -2248,11 +2238,6 @@ void WingAngelAPI::deleteAsDictionary(const WingHex::SenderInfo &sender, } } -QString WingAngelAPI::getSenderHeader(const WingHex::SenderInfo &sender) { - return QStringLiteral("(") + sender.puid + QStringLiteral("::") + - sender.plgcls + QStringLiteral(") "); -} - void WingAngelAPI::cleanUpHandles(const QVector &handles) { for (auto &h : _handles) { if (!handles.contains(h)) { @@ -2510,7 +2495,3 @@ bool WingAngelAPI::_DataVisual_updateTextTable(const QString &json, } return false; } - -void WingAngelAPI::setBindingConsole(ScriptingConsole *console) { - _console = console; -} diff --git a/src/class/wingangelapi.h b/src/class/wingangelapi.h index 8dc562e..2a55fb0 100644 --- a/src/class/wingangelapi.h +++ b/src/class/wingangelapi.h @@ -73,9 +73,6 @@ public: void installAPI(ScriptMachine *machine); void installBasicTypes(asIScriptEngine *engine); - void setBindingConsole(ScriptingConsole *console); - void unBindConsole(); - static QString qvariantCastASString(const QMetaType::Type &id); static int qvariantCastASID(asIScriptEngine *engine, @@ -203,8 +200,6 @@ private: // ========================================================= - QString getSenderHeader(const WingHex::SenderInfo &sender); - void cleanUpHandles(const QVector &handles); private: @@ -261,8 +256,6 @@ private: QVector _usfns; QHash> _urfns; - ScriptingConsole *_console = nullptr; - QHash>>> _objs; QVector _handles; diff --git a/src/control/scripteditor.cpp b/src/control/scripteditor.cpp index 71f667b..4c01a7c 100644 --- a/src/control/scripteditor.cpp +++ b/src/control/scripteditor.cpp @@ -35,7 +35,7 @@ #include "class/ascompletion.h" #include "class/clangformatmanager.h" -ScriptEditor::ScriptEditor(asIScriptEngine *engine, QWidget *parent) +ScriptEditor::ScriptEditor(QWidget *parent) : ads::CDockWidget(nullptr, QString(), parent) { this->setFeatures( CDockWidget::DockWidgetFocusable | CDockWidget::DockWidgetMovable | @@ -48,7 +48,7 @@ ScriptEditor::ScriptEditor(asIScriptEngine *engine, QWidget *parent) m_editor->setSyntax( m_editor->syntaxRepo().definitionForName("AngelScript")); - auto cm = new AsCompletion(engine, m_editor); + auto cm = new AsCompletion(m_editor); connect(cm, &AsCompletion::onFunctionTip, this, &ScriptEditor::onFunctionTip); diff --git a/src/control/scripteditor.h b/src/control/scripteditor.h index 4804461..16226fd 100644 --- a/src/control/scripteditor.h +++ b/src/control/scripteditor.h @@ -27,7 +27,7 @@ class ScriptEditor : public ads::CDockWidget { Q_OBJECT public: - explicit ScriptEditor(asIScriptEngine *engine, QWidget *parent = nullptr); + explicit ScriptEditor(QWidget *parent = nullptr); virtual ~ScriptEditor(); QString fileName() const; diff --git a/src/control/scriptingconsole.cpp b/src/control/scriptingconsole.cpp index 675e03b..2ebbfa5 100644 --- a/src/control/scriptingconsole.cpp +++ b/src/control/scriptingconsole.cpp @@ -18,7 +18,7 @@ #include "scriptingconsole.h" #include "QConsoleWidget/QConsoleIODevice.h" #include "class/logger.h" -#include "class/scriptconsolemachine.h" +#include "class/scriptmachine.h" #include "class/scriptsettings.h" #include "class/skinmanager.h" #include "model/codecompletionmodel.h" @@ -91,103 +91,16 @@ void ScriptingConsole::handleReturnKey() { void ScriptingConsole::init() { _getInputFn = std::bind(&ScriptingConsole::getInput, this); - _sp = new ScriptConsoleMachine(_getInputFn, this); - connect(_sp, &ScriptConsoleMachine::onClearConsole, this, - &ScriptingConsole::clear); - connect(this, &ScriptingConsole::abortEvaluation, _sp, - &ScriptConsoleMachine::abortScript); - - connect( - _sp, &ScriptConsoleMachine::onOutput, this, - [=](ScriptConsoleMachine::MessageType type, - const ScriptConsoleMachine::MessageInfo &message) { - // > - static QPair> - lastInfo{ScriptConsoleMachine::MessageType::Print, {-1, -1}}; - - auto doc = this->document(); - auto lastLine = doc->lastBlock(); - auto isNotBlockStart = !lastLine.text().isEmpty(); - - auto fmtMsg = [](const ScriptConsoleMachine::MessageInfo &message) - -> QString { - if (message.row <= 0 || message.col <= 0) { - return message.message; - } else { - return QStringLiteral("(") + QString::number(message.row) + - QStringLiteral(", ") + QString::number(message.col) + - QStringLiteral(") ") + message.message; - } - }; - - auto isMatchLast = - [](ScriptConsoleMachine::MessageType type, - const ScriptConsoleMachine::MessageInfo &message) -> bool { - if (message.row < 0 || message.col < 0) { - return false; - } - return lastInfo.first == type && - lastInfo.second.first == message.row && - lastInfo.second.second == message.col; - }; - - switch (type) { - case ScriptMachine::MessageType::Info: - if (isMatchLast(type, message)) { - stdOut(message.message); - } else { - if (isNotBlockStart) { - newLine(); - } - stdOut(tr("[Info]") + fmtMsg(message)); - } - flush(); - break; - case ScriptMachine::MessageType::Warn: - if (isMatchLast(type, message)) { - stdWarn(message.message); - } else { - if (isNotBlockStart) { - newLine(); - } - stdWarn(tr("[Warn]") + fmtMsg(message)); - } - flush(); - break; - case ScriptMachine::MessageType::Error: - if (isMatchLast(type, message)) { - stdErr(message.message); - } else { - if (isNotBlockStart) { - newLine(); - } - stdErr(tr("[Error]") + fmtMsg(message)); - } - flush(); - break; - case ScriptMachine::MessageType::Print: - if (lastInfo.first != type) { - newLine(); - } - // If running ouput in the console, - // otherwise logging. - if (_sp->isRunning()) { - stdOut(message.message); - } else { - Logger::logPrint(Logger::packDebugStr( - packUpLoggingStr(message.message))); - } - break; - } - - lastInfo.first = type; - lastInfo.second = qMakePair(message.row, message.col); - }); + // _sp = new ScriptConsoleMachine(_getInputFn, this); + // connect(_sp, &ScriptConsoleMachine::onClearConsole, this, + // &ScriptingConsole::clear); + // connect(this, &ScriptingConsole::abortEvaluation, _sp, + // &ScriptConsoleMachine::abortScript); connect(this, &QConsoleWidget::consoleCommand, this, &ScriptingConsole::runConsoleCommand); - auto cm = new AsConsoleCompletion(_sp->engine(), this); + auto cm = new AsConsoleCompletion(this); connect(cm, &AsCompletion::onFunctionTip, this, &ScriptingConsole::onFunctionTip); } @@ -201,6 +114,80 @@ void ScriptingConsole::clearConsole() { void ScriptingConsole::processKeyEvent(QKeyEvent *e) { keyPressEvent(e); } +void ScriptingConsole::onOutput(const ScriptMachine::MessageInfo &message) { + // > + static QPair> lastInfo{ + ScriptMachine::MessageType::Print, {-1, -1}}; + + auto doc = this->document(); + auto lastLine = doc->lastBlock(); + auto isNotBlockStart = !lastLine.text().isEmpty(); + + auto fmtMsg = [](const ScriptMachine::MessageInfo &message) -> QString { + if (message.row <= 0 || message.col <= 0) { + return message.message; + } else { + return QStringLiteral("(") + QString::number(message.row) + + QStringLiteral(", ") + QString::number(message.col) + + QStringLiteral(")") + message.message; + } + }; + + auto isMatchLast = [](const ScriptMachine::MessageInfo &message) -> bool { + if (message.row < 0 || message.col < 0) { + return false; + } + return lastInfo.first == message.type && + lastInfo.second.first == message.row && + lastInfo.second.second == message.col; + }; + + switch (message.type) { + case ScriptMachine::MessageType::Info: + if (isMatchLast(message)) { + stdOut(message.message); + } else { + if (isNotBlockStart) { + newLine(); + } + stdOut(tr("[Info]") + fmtMsg(message)); + } + flush(); + break; + case ScriptMachine::MessageType::Warn: + if (isMatchLast(message)) { + stdWarn(message.message); + } else { + if (isNotBlockStart) { + newLine(); + } + stdWarn(tr("[Warn]") + fmtMsg(message)); + } + flush(); + break; + case ScriptMachine::MessageType::Error: + if (isMatchLast(message)) { + stdErr(message.message); + } else { + if (isNotBlockStart) { + newLine(); + } + stdErr(tr("[Error]") + fmtMsg(message)); + } + flush(); + break; + case ScriptMachine::MessageType::Print: + if (lastInfo.first != message.type) { + newLine(); + } + stdOut(message.message); + break; + } + + lastInfo.first = message.type; + lastInfo.second = qMakePair(message.row, message.col); +} + void ScriptingConsole::applyScriptSettings() { auto &set = ScriptSettings::instance(); auto dfont = QFont(set.consoleFontFamily()); @@ -241,7 +228,9 @@ void ScriptingConsole::runConsoleCommand(const QString &code) { } else { setMode(Output); _codes += exec; - if (!_sp->executeCode(_codes)) { + if (!ScriptMachine::instance().executeCode(ScriptMachine::Interactive, + _codes)) { + // WingMessageBox:: } _codes.clear(); appendCommandPrompt(); @@ -290,10 +279,6 @@ QString ScriptingConsole::currentCodes() const { return _codes + currentCommandLine(); } -ScriptMachine *ScriptingConsole::machine() const { return _sp; } - -ScriptConsoleMachine *ScriptingConsole::consoleMachine() const { return _sp; } - void ScriptingConsole::contextMenuEvent(QContextMenuEvent *event) { QMenu menu(this); diff --git a/src/control/scriptingconsole.h b/src/control/scriptingconsole.h index 5247571..013acc2 100644 --- a/src/control/scriptingconsole.h +++ b/src/control/scriptingconsole.h @@ -18,10 +18,9 @@ #ifndef ScriptingConsole_H #define ScriptingConsole_H -#include "scriptingconsolebase.h" - #include "class/asconsolecompletion.h" -#include "class/scriptconsolemachine.h" +#include "class/scriptmachine.h" +#include "scriptingconsolebase.h" #include @@ -33,14 +32,14 @@ public: virtual ~ScriptingConsole(); - ScriptMachine *machine() const; - ScriptConsoleMachine *consoleMachine() const; - QString currentCodes() const; signals: void onFunctionTip(const QString &tip); +public: + QString getInput(); + public slots: void init(); @@ -48,14 +47,14 @@ public slots: void processKeyEvent(QKeyEvent *e); + void onOutput(const ScriptMachine::MessageInfo &message); + private slots: void applyScriptSettings(); private: void runConsoleCommand(const QString &code); - QString getInput(); - QString packUpLoggingStr(const QString &message); protected: @@ -67,8 +66,6 @@ protected slots: virtual void onCompletion(const QModelIndex &index) override; private: - ScriptConsoleMachine *_sp = nullptr; - QString _codes; std::function _getInputFn; diff --git a/src/define.h b/src/define.h index b44749a..43b78ad 100644 --- a/src/define.h +++ b/src/define.h @@ -13,6 +13,8 @@ enum AsUserDataType { UserData_ContextDbgInfo, UserData_API, UserData_PluginFn, + UserData_isDbg, + UserData_ContextMode, }; } diff --git a/src/dialog/mainwindow.cpp b/src/dialog/mainwindow.cpp index a4dc62b..07950fc 100644 --- a/src/dialog/mainwindow.cpp +++ b/src/dialog/mainwindow.cpp @@ -33,7 +33,7 @@ #include "class/pluginsystem.h" #include "class/qkeysequences.h" #include "class/richtextitemdelegate.h" -#include "class/scriptconsolemachine.h" +#include "class/scriptmachine.h" #include "class/settingmanager.h" #include "class/wingfiledialog.h" #include "class/winginputdialog.h" @@ -230,6 +230,32 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() { // Don't setup it too early, because the plugin can register script // functions. Code completions of them will be not worked out. if (set.scriptEnabled()) { + auto &sm = ScriptMachine::instance(); + auto smr = sm.init(); + if (smr) { + ScriptMachine::RegCallBacks callbacks; + callbacks.getInputFn = [this]() -> QString { + return m_scriptConsole->getInput(); + }; + callbacks.clearFn = [this]() { m_scriptConsole->clearConsole(); }; + callbacks.printMsgFn = + [this](const ScriptMachine::MessageInfo &message) { + m_scriptConsole->onOutput(message); + }; + sm.registerCallBack(ScriptMachine::Interactive, callbacks); + + callbacks.getInputFn = [this]() -> QString { + return WingInputDialog::getText(this, tr(""), tr("")); + }; + callbacks.clearFn = [this]() { m_bgScriptOutput->clear(); }; + callbacks.printMsgFn = + std::bind(&MainWindow::onOutputBgScriptOutput, this, + std::placeholders::_1); + sm.registerCallBack(ScriptMachine::Background, callbacks); + } else { + // TODO + } + // At this time, AngelScript service plugin has started if (splash) splash->setInfoText(tr("SetupConsole")); @@ -237,25 +263,17 @@ MainWindow::MainWindow(SplashDialog *splash) : FramelessMainWindow() { m_scriptConsole->init(); if (splash) splash->setInfoText(tr("SetupScriptManager")); - ScriptManager::instance().attach(m_scriptConsole); - - plg.angelApi()->setBindingConsole(m_scriptConsole); if (splash) splash->setInfoText(tr("SetupScriptService")); m_scriptConsole->initOutput(); m_scriptConsole->setMode(QConsoleWidget::Input); - m_scriptConsole->machine()->setInsteadFoundDisabled(true); if (splash) splash->setInfoText(tr("SetupScriptEditor")); m_scriptDialog = new ScriptingDialog(this); m_scriptDialog->initConsole(); - - // load the model - Q_ASSERT(m_scriptConsole && m_scriptConsole->machine()); - m_varshowtable->setModel(m_scriptConsole->consoleMachine()->model()); } // connect settings signals @@ -535,8 +553,8 @@ void MainWindow::buildUpDockSystem(QWidget *container) { bottomRightArea = buildUpScriptConsoleDock( m_dock, ads::RightDockWidgetArea, bottomLeftArea); qApp->processEvents(); - buildUpScriptObjShowDock(m_dock, ads::CenterDockWidgetArea, - bottomRightArea); + buildUpScriptBgOutputDock(m_dock, ads::CenterDockWidgetArea, + bottomRightArea); qApp->processEvents(); buildUpHashResultDock(m_dock, ads::CenterDockWidgetArea, bottomRightArea); @@ -1000,17 +1018,14 @@ MainWindow::buildUpScriptConsoleDock(ads::CDockManager *dock, } ads::CDockAreaWidget * -MainWindow::buildUpScriptObjShowDock(ads::CDockManager *dock, - ads::DockWidgetArea area, - ads::CDockAreaWidget *areaw) { - m_varshowtable = new QTableViewExt(this); - m_varshowtable->setEditTriggers(QTableView::EditTrigger::DoubleClicked); - m_varshowtable->setSelectionBehavior( - QAbstractItemView::SelectionBehavior::SelectRows); - m_varshowtable->horizontalHeader()->setStretchLastSection(true); +MainWindow::buildUpScriptBgOutputDock(ads::CDockManager *dock, + ads::DockWidgetArea area, + ads::CDockAreaWidget *areaw) { + m_bgScriptOutput = new QPlainTextEdit(this); + m_bgScriptOutput->setReadOnly(true); - auto dw = buildDockWidget(dock, QStringLiteral("ScriptObjShow"), - tr("ScriptObjShow"), m_varshowtable); + auto dw = buildDockWidget(dock, QStringLiteral("BgScriptOutput"), + tr("BgScriptOutput"), m_bgScriptOutput); return dock->addDockWidget(area, dw, areaw); } @@ -1720,7 +1735,7 @@ RibbonTabContent *MainWindow::buildPluginPage(RibbonTabContent *tab) { auto pannel = tab->addGroup(tr("General")); addPannelAction( pannel, QStringLiteral("settingplugin"), tr("Plugin"), - &MainWindow::on_setting_plugin, + &MainWindow::on_settingPlugin, shortcuts.keySequence(QKeySequences::Key::SETTING_PLUGIN)); } @@ -1743,13 +1758,12 @@ RibbonTabContent *MainWindow::buildSettingPage(RibbonTabContent *tab) { auto pannel = tab->addGroup(tr("General")); addPannelAction( pannel, QStringLiteral("general"), tr("General"), - &MainWindow::on_setting_general, + &MainWindow::on_settingGeneral, shortcuts.keySequence(QKeySequences::Key::SETTING_GENERAL)); if (set.scriptEnabled()) { addPannelAction(pannel, QStringLiteral("scriptset"), - tr("ScriptSetting"), - &MainWindow::on_setting_script); + tr("ScriptSetting"), &MainWindow::on_settingScript); } } @@ -3097,13 +3111,13 @@ void MainWindow::on_scriptwindow() { m_scriptDialog->raise(); } -void MainWindow::on_setting_general() { m_setdialog->showConfig(0); } +void MainWindow::on_settingGeneral() { m_setdialog->showConfig(0); } -void MainWindow::on_setting_script() { +void MainWindow::on_settingScript() { m_scriptDialog->settingDialog()->showConfig(); } -void MainWindow::on_setting_plugin() { m_setdialog->showConfig(2); } +void MainWindow::on_settingPlugin() { m_setdialog->showConfig(2); } void MainWindow::on_about() { AboutSoftwareDialog().exec(); } @@ -3939,6 +3953,88 @@ ads::CDockAreaWidget *MainWindow::editorViewArea() const { return m_dock->centralWidget()->dockAreaWidget(); } +void MainWindow::onOutputBgScriptOutput( + const ScriptMachine::MessageInfo &message) { + static QPair> lastInfo{ + ScriptMachine::MessageType::Print, {-1, -1}}; + + auto doc = m_bgScriptOutput->document(); + auto lastLine = doc->lastBlock(); + auto isNotBlockStart = !lastLine.text().isEmpty(); + + auto cursor = m_bgScriptOutput->textCursor(); + cursor.movePosition(QTextCursor::End); + + auto fmtMsg = [](const ScriptMachine::MessageInfo &message) -> QString { + if (message.row <= 0 || message.col <= 0) { + return message.message; + } else { + return QStringLiteral("(") + QString::number(message.row) + + QStringLiteral(", ") + QString::number(message.col) + + QStringLiteral(")") + message.message; + } + }; + + auto isMatchLast = [](const ScriptMachine::MessageInfo &message) -> bool { + if (message.row < 0 || message.col < 0) { + return false; + } + return lastInfo.first == message.type && + lastInfo.second.first == message.row && + lastInfo.second.second == message.col; + }; + + switch (message.type) { + case ScriptMachine::MessageType::Info: + if (isMatchLast(message)) { + cursor.insertText(message.message); + } else { + if (isNotBlockStart) { + cursor.insertBlock(); + } + cursor.insertText(tr("[Info]") + fmtMsg(message)); + } + break; + case ScriptMachine::MessageType::Warn: + if (isMatchLast(message)) { + auto fmt = cursor.charFormat(); + fmt.setForeground(QColorConstants::Svg::gold); + cursor.insertText(message.message, fmt); + } else { + if (isNotBlockStart) { + m_bgScriptOutput->appendPlainText({}); + } + auto fmt = cursor.charFormat(); + fmt.setForeground(QColorConstants::Svg::gold); + cursor.insertText(tr("[Warn]") + fmtMsg(message), fmt); + } + break; + case ScriptMachine::MessageType::Error: + if (isMatchLast(message)) { + auto fmt = cursor.charFormat(); + fmt.setForeground(Qt::red); + cursor.insertText(message.message, fmt); + } else { + if (isNotBlockStart) { + cursor.insertBlock(); + } + auto fmt = cursor.charFormat(); + fmt.setForeground(Qt::red); + cursor.insertText(tr("[Error]") + fmtMsg(message), fmt); + } + break; + case ScriptMachine::MessageType::Print: + if (lastInfo.first != message.type) { + cursor.insertBlock(); + } + cursor.insertText(message.message); + break; + } + + lastInfo.first = message.type; + lastInfo.second = qMakePair(message.row, message.col); +} + QJsonObject MainWindow::extractModelData(const QAbstractItemModel *model, const QModelIndex &parent) { QJsonObject jsonObject; @@ -3981,11 +4077,8 @@ void MainWindow::closeEvent(QCloseEvent *event) { return; } - // then checking the scripting console - auto sm = m_scriptConsole->consoleMachine(); - if (sm->isRunning()) { - sm->abortScript(); - } + // then abort all script running + ScriptMachine::instance().abortScript(); // then checking itself if (!m_views.isEmpty()) { diff --git a/src/dialog/mainwindow.h b/src/dialog/mainwindow.h index 50a4317..04c5a64 100644 --- a/src/dialog/mainwindow.h +++ b/src/dialog/mainwindow.h @@ -123,8 +123,8 @@ private: buildUpScriptConsoleDock(ads::CDockManager *dock, ads::DockWidgetArea area, ads::CDockAreaWidget *areaw = nullptr); ads::CDockAreaWidget * - buildUpScriptObjShowDock(ads::CDockManager *dock, ads::DockWidgetArea area, - ads::CDockAreaWidget *areaw = nullptr); + buildUpScriptBgOutputDock(ads::CDockManager *dock, ads::DockWidgetArea area, + ads::CDockAreaWidget *areaw = nullptr); ads::CDockAreaWidget * buildUpVisualDataDock(ads::CDockManager *dock, ads::DockWidgetArea area, ads::CDockAreaWidget *areaw = nullptr); @@ -205,9 +205,9 @@ private slots: void on_inspectQt(); void on_scriptwindow(); - void on_setting_general(); - void on_setting_script(); - void on_setting_plugin(); + void on_settingGeneral(); + void on_settingScript(); + void on_settingPlugin(); void on_about(); void on_sponsor(); @@ -266,6 +266,8 @@ private: inline ads::CDockAreaWidget *editorViewArea() const; + void onOutputBgScriptOutput(const ScriptMachine::MessageInfo &message); + private: QJsonObject extractModelData(const QAbstractItemModel *model, const QModelIndex &parent = QModelIndex()); @@ -481,7 +483,7 @@ private: ScriptingDialog *m_scriptDialog = nullptr; ScriptingConsole *m_scriptConsole = nullptr; - QTableViewExt *m_varshowtable = nullptr; + QPlainTextEdit *m_bgScriptOutput = nullptr; bool m_isfinding = false; ads::CDockWidget *m_find = nullptr; diff --git a/src/dialog/scriptingdialog.cpp b/src/dialog/scriptingdialog.cpp index 6a9827b..e2db99b 100644 --- a/src/dialog/scriptingdialog.cpp +++ b/src/dialog/scriptingdialog.cpp @@ -24,6 +24,7 @@ #include "class/languagemanager.h" #include "class/pluginsystem.h" #include "class/qkeysequences.h" +#include "class/scriptmachine.h" #include "class/settingmanager.h" #include "class/wingfiledialog.h" #include "class/wingmessagebox.h" @@ -93,6 +94,17 @@ ScriptingDialog::ScriptingDialog(QWidget *parent) m_dock->restoreState(set.scriptDockLayout()); _savedLayout = set.scriptDockLayout(); + ScriptMachine::RegCallBacks callbacks; + callbacks.getInputFn = [this]() -> QString { + return m_consoleout->getInput(); + }; + callbacks.clearFn = [this]() { m_consoleout->clearConsole(); }; + callbacks.printMsgFn = [this](const ScriptMachine::MessageInfo &message) { + m_consoleout->onOutput(message); + }; + ScriptMachine::instance().registerCallBack(ScriptMachine::Scripting, + callbacks); + this->setUpdatesEnabled(true); } @@ -102,8 +114,8 @@ void ScriptingDialog::initConsole() { Q_ASSERT(m_consoleout); m_consoleout->init(); - auto machine = m_consoleout->machine(); - connect(machine, &ScriptMachine::onDebugFinished, this, [=] { + auto &machine = ScriptMachine::instance(); + connect(&machine, &ScriptMachine::onDebugFinished, this, [=] { this->updateRunDebugMode(); m_callstack->updateData({}); m_varshow->updateData({}); @@ -138,7 +150,7 @@ void ScriptingDialog::initConsole() { _DebugingEditor = nullptr; } }); - auto dbg = machine->debugger(); + auto dbg = machine.debugger(); Q_ASSERT(dbg); connect(dbg, &asDebugger::onAdjustBreakPointLine, this, [=](const asDebugger::BreakPoint &old, int newLineNr) { @@ -210,7 +222,7 @@ void ScriptingDialog::initConsole() { }); connect(dbg, &asDebugger::onDebugActionExec, this, [this]() { updateRunDebugMode(); }); - m_sym->setEngine(machine->engine()); + m_sym->setEngine(machine.engine()); } bool ScriptingDialog::about2Close() { @@ -489,16 +501,15 @@ RibbonTabContent *ScriptingDialog::buildDebugPage(RibbonTabContent *tab) { auto dbgShortCut = new QShortcut(dbgkey, this); connect(dbgShortCut, &QShortcut::activated, this, [this]() { - auto runner = m_consoleout->machine(); + auto &runner = ScriptMachine::instance(); bool isRun = false; bool isDbg = false; bool isPaused = false; - if (runner) { - isRun = runner->isRunning(); - isDbg = runner->isDebugMode(); - auto dbg = runner->debugger(); - isPaused = dbg->currentState() == asDebugger::PAUSE; - } + + isRun = runner.isRunning(); + isDbg = runner.isDebugMode(); + auto dbg = runner.debugger(); + isPaused = dbg->currentState() == asDebugger::PAUSE; if (isRun && isDbg && isPaused) { m_Tbtneditors[ToolButtonIndex::DBG_CONTINUE_ACTION]->animateClick(); @@ -728,8 +739,8 @@ void ScriptingDialog::registerEditorView(ScriptEditor *editor) { Q_ASSERT(editor); Q_ASSERT(m_views.contains(editor)); - auto m = m_consoleout->machine(); - if (m->isRunning() && _DebugingEditor == editor) { + auto &m = ScriptMachine::instance(); + if (m.isRunning() && _DebugingEditor == editor) { if (WingMessageBox::warning( this, this->windowTitle(), tr("ScriptStillRunning"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) { @@ -864,17 +875,17 @@ void ScriptingDialog::swapEditor(ScriptEditor *old, ScriptEditor *cur) { } void ScriptingDialog::updateRunDebugMode(bool disable) { - auto runner = m_consoleout->machine(); + auto &runner = ScriptMachine::instance(); auto enable = !disable; bool isRun = false; bool isDbg = false; bool isPaused = false; - if (runner) { - isRun = runner->isRunning(); - isDbg = runner->isDebugMode(); - auto dbg = runner->debugger(); - isPaused = dbg->currentState() == asDebugger::PAUSE; - } + + isRun = runner.isRunning(); + isDbg = runner.isDebugMode(); + auto dbg = runner.debugger(); + isPaused = dbg->currentState() == asDebugger::PAUSE; + m_Tbtneditors.value(ToolButtonIndex::DBG_RUN_ACTION)->setEnabled(!isRun); m_Tbtneditors.value(ToolButtonIndex::DBG_RUN_DBG_ACTION) ->setEnabled(!isRun); @@ -920,8 +931,8 @@ ScriptEditor *ScriptingDialog::findEditorView(const QString &filename) { } bool ScriptingDialog::isCurrentDebugging() const { - auto m = m_consoleout->machine(); - return m && m->isDebugMode(); + auto &m = ScriptMachine::instance(); + return m.isDebugMode(); } ScriptEditor *ScriptingDialog::openFile(const QString &filename) { @@ -932,8 +943,7 @@ ScriptEditor *ScriptingDialog::openFile(const QString &filename) { return e; } - auto editor = - new ScriptEditor(m_consoleout->consoleMachine()->engine(), this); + auto editor = new ScriptEditor(this); auto res = editor->openFile(filename); if (!res) { @@ -949,9 +959,9 @@ ScriptEditor *ScriptingDialog::openFile(const QString &filename) { void ScriptingDialog::runDbgCommand(asDebugger::DebugAction action) { updateRunDebugMode(true); - auto machine = m_consoleout->machine(); - if (machine->isDebugMode()) { - auto dbg = machine->debugger(); + auto &machine = ScriptMachine::instance(); + if (machine.isDebugMode()) { + auto dbg = machine.debugger(); dbg->runDebugAction(action); } } @@ -978,7 +988,7 @@ void ScriptingDialog::startDebugScript(ScriptEditor *editor) { m_consoleout->clear(); // add breakpoints - auto dbg = m_consoleout->machine()->debugger(); + auto dbg = ScriptMachine::instance().debugger(); auto fileName = editor->fileName(); auto e = editor->editor(); auto totalblk = e->blockCount(); @@ -992,7 +1002,8 @@ void ScriptingDialog::startDebugScript(ScriptEditor *editor) { PluginSystem::instance().scriptPragmaBegin(); editor->setReadOnly(true); - m_consoleout->machine()->executeScript(fileName, true); + ScriptMachine::instance().executeScript(ScriptMachine::Scripting, fileName, + true); editor->setReadOnly(false); updateRunDebugMode(); @@ -1006,8 +1017,9 @@ void ScriptingDialog::addBreakPoint(ScriptEditor *editor, int line) { const auto curSym = QStringLiteral("cur"); const auto hitCur = QStringLiteral("curbp"); - if (m_consoleout->machine()->isDebugMode()) { - auto dbg = m_consoleout->machine()->debugger(); + auto &m = ScriptMachine::instance(); + if (m.isDebugMode()) { + auto dbg = m.debugger(); auto symID = e->symbolMark(line); if (curSym == symID) { e->addSymbolMark(line, hitCur); @@ -1027,8 +1039,9 @@ void ScriptingDialog::removeBreakPoint(ScriptEditor *editor, int line) { Q_ASSERT(editor); auto e = editor->editor(); - if (m_consoleout->machine()->isDebugMode()) { - auto dbg = m_consoleout->machine()->debugger(); + auto &m = ScriptMachine::instance(); + if (m.isDebugMode()) { + auto dbg = m.debugger(); auto symID = e->symbolMark(line); const auto bpMark = QStringLiteral("bp"); @@ -1053,8 +1066,9 @@ void ScriptingDialog::toggleBreakPoint(ScriptEditor *editor, int line) { Q_ASSERT(editor); auto e = editor->editor(); - if (m_consoleout->machine()->isDebugMode()) { - auto dbg = m_consoleout->machine()->debugger(); + auto &m = ScriptMachine::instance(); + if (m.isDebugMode()) { + auto dbg = m.debugger(); auto symID = e->symbolMark(line); const auto bpMark = QStringLiteral("bp"); @@ -1134,8 +1148,7 @@ void ScriptingDialog::on_newfile() { return; } - auto editor = - new ScriptEditor(m_consoleout->consoleMachine()->engine(), this); + auto editor = new ScriptEditor(this); auto res = editor->openFile(filename); if (!res) { WingMessageBox::critical(this, tr("Error"), tr("FilePermission")); @@ -1355,7 +1368,7 @@ void ScriptingDialog::on_runscript() { PluginSystem::instance().scriptPragmaBegin(); editor->setReadOnly(true); - m_consoleout->machine()->executeScript(editor->fileName()); + // ScriptMachine::instance().executeScript(editor->fileName()); editor->setReadOnly(false); updateRunDebugMode(); } @@ -1423,8 +1436,8 @@ void ScriptingDialog::on_removebreakpoint() { } void ScriptingDialog::closeEvent(QCloseEvent *event) { - auto runner = m_consoleout->machine(); - if (runner->isRunning()) { + auto &runner = ScriptMachine::instance(); + if (runner.isRunning()) { if (WingMessageBox::warning( this, this->windowTitle(), tr("ScriptStillRunning"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) { diff --git a/src/model/scriptobjmodel.cpp b/src/model/scriptobjmodel.cpp deleted file mode 100644 index b94215e..0000000 --- a/src/model/scriptobjmodel.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/*============================================================================== -** Copyright (C) 2024-2027 WingSummer -** -** This program is free software: you can redistribute it and/or modify it under -** the terms of the GNU Affero General Public License as published by the Free -** Software Foundation, version 3. -** -** This program is distributed in the hope that it will be useful, but WITHOUT -** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -** details. -** -** You should have received a copy of the GNU Affero General Public License -** along with this program. If not, see . -** ============================================================================= -*/ - -#include "scriptobjmodel.h" - -ScriptObjModel::ScriptObjModel(asIScriptEngine *engine, asDebugger *debugger, - QObject *parent) - : QAbstractTableModel(parent), _engine(engine), _debugger(debugger) { - Q_ASSERT(engine && debugger); - _mod = engine->GetModule("Console", asGM_CREATE_IF_NOT_EXISTS); - Q_ASSERT(_mod); -} - -void ScriptObjModel::updateData() { - this->beginResetModel(); - _datas.reserve(_engine->GetGlobalPropertyCount() + - _mod->GetGlobalVarCount()); - _datas.clear(); - - for (asUINT n = 0; n < _engine->GetGlobalPropertyCount(); n++) { - const char *name; - int typeId; - bool isConst; - void *v; - - _engine->GetGlobalPropertyByIndex(n, &name, nullptr, &typeId, &isConst, - nullptr, &v); - - Data d; - d.name = name; - d.type = (isConst ? QStringLiteral(" const ") : QStringLiteral(" ")) + - _engine->GetTypeDeclaration(typeId); - d.value = _debugger->toString(v, typeId, _engine); - - _datas.append(d); - } - - for (asUINT n = 0; n < _mod->GetGlobalVarCount(); n++) { - const char *name; - int typeId; - bool isConst; - void *v; - - _mod->GetGlobalVar(n, &name, nullptr, &typeId, &isConst); - v = _mod->GetAddressOfGlobalVar(n); - - Data d; - d.name = name; - d.type = (isConst ? QStringLiteral(" const ") : QStringLiteral(" ")) + - _engine->GetTypeDeclaration(typeId); - d.value = _debugger->toString(v, typeId, _engine); - _datas.append(d); - } - this->endResetModel(); -} - -int ScriptObjModel::rowCount(const QModelIndex &parent) const { - Q_UNUSED(parent); - return _datas.size(); -} - -int ScriptObjModel::columnCount(const QModelIndex &parent) const { - Q_UNUSED(parent); - return 3; -} - -QVariant ScriptObjModel::data(const QModelIndex &index, int role) const { - switch (role) { - case Qt::DisplayRole: { - auto d = _datas.at(index.row()); - switch (index.column()) { - case 0: - return d.name; - case 1: - return d.type; - case 2: - return d.value; - default: - return QVariant(); - } - } - case Qt::TextAlignmentRole: - return int(Qt::AlignCenter); - } - return QVariant(); -} - -QVariant ScriptObjModel::headerData(int section, Qt::Orientation orientation, - int role) const { - if (role == Qt::DisplayRole) { - if (orientation == Qt::Horizontal) { - switch (section) { - case 0: - return tr("Name"); - case 1: - return tr("Type"); - case 2: - return tr("Value"); - } - } else { - return section + 1; - } - } - return QVariant(); -} diff --git a/src/model/scriptobjmodel.h b/src/model/scriptobjmodel.h deleted file mode 100644 index fcf5e38..0000000 --- a/src/model/scriptobjmodel.h +++ /dev/null @@ -1,56 +0,0 @@ -/*============================================================================== -** Copyright (C) 2024-2027 WingSummer -** -** This program is free software: you can redistribute it and/or modify it under -** the terms of the GNU Affero General Public License as published by the Free -** Software Foundation, version 3. -** -** This program is distributed in the hope that it will be useful, but WITHOUT -** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -** FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more -** details. -** -** You should have received a copy of the GNU Affero General Public License -** along with this program. If not, see . -** ============================================================================= -*/ - -#ifndef SCRIPTOBJMODEL_H -#define SCRIPTOBJMODEL_H - -#include "angelscript.h" -#include "class/asdebugger.h" -#include - -class ScriptObjModel : public QAbstractTableModel { - Q_OBJECT -public: - explicit ScriptObjModel(asIScriptEngine *engine, asDebugger *debugger, - QObject *parent = nullptr); - - void updateData(); - -private: - struct Data { - QString name; - QString type; - QString value; - }; - - QList _datas; - - // QAbstractItemModel interface -public: - virtual int rowCount(const QModelIndex &parent) const override; - virtual int columnCount(const QModelIndex &parent) const override; - virtual QVariant data(const QModelIndex &index, int role) const override; - virtual QVariant headerData(int section, Qt::Orientation orientation, - int role) const override; - -private: - asIScriptEngine *_engine = nullptr; - asDebugger *_debugger = nullptr; - asIScriptModule *_mod = nullptr; -}; - -#endif // SCRIPTOBJMODEL_H