mirror of
https://gitcode.com/JianFeeeee/LuaCangjia_api.git
synced 2026-09-21 09:28:17 +00:00
feat: 实现loadFunction预加载函数能力 + AI辅助编程标识
- 新增 loadFunction/callFunction/unloadFunction 预加载函数 API - 预加载语义:加载文件→顶层执行一次→返回函数存入Lua Registry→可多次调用 - 与管道模式(load/runScript)存储完全解耦:funcs[]+Registry vs pkgs[]+虚拟栈 - 新增错误码 5023/5024/5025 - 新增单元测试:仓颉侧 8 个 + C++ GTest 侧 11 个 - 本机以 Cangjie 1.1.0 实编译并通过功能运行验证 - README/doc 增加 AI 辅助编程标识及预加载函数模式说明
This commit is contained in:
@ -15,6 +15,12 @@ foreign func run(selfd: CPointer<Unit>, path: CString, arg: CString): Int32
|
||||
@C
|
||||
foreign func dostring(selfd: CPointer<Unit>,target: CString): Int32
|
||||
@C
|
||||
foreign func loadfunction(selfd: CPointer<Unit>,path: CString, name: CString): Int32
|
||||
@C
|
||||
foreign func unloadfunction(selfd: CPointer<Unit>,name: CString): Int32
|
||||
@C
|
||||
foreign func callfunction(selfd: CPointer<Unit>,name: CString, arg: CString): Int32
|
||||
@C
|
||||
foreign func cleanup(selfd: CPointer<Unit>): Int32
|
||||
@C
|
||||
foreign func get_errno(): Int32
|
||||
@ -94,6 +100,9 @@ public class LuaError <: Exception {
|
||||
case 5020 => "Error in callback functions"
|
||||
case 5021 => "change workdir error"
|
||||
case 5022 => "No callable chunk found"
|
||||
case 5023 => "Function not found"
|
||||
case 5024 => "Too many preloaded functions"
|
||||
case 5025 => "Preloaded file must return a function"
|
||||
case _ => "Unknown error"
|
||||
}
|
||||
}
|
||||
@ -230,6 +239,82 @@ public class LuaRunner {
|
||||
return this.cachedResult
|
||||
}
|
||||
|
||||
/// 加载函数到内存(预加载)
|
||||
///
|
||||
/// 加载 Lua 文件 → 编译成 chunk → 执行顶层代码(顶层代码只执行一次)→ 捕获返回的 Lua 函数 → 存入独立的 Registry 引用表。
|
||||
/// 与 load() 的块压栈不同:
|
||||
/// - load() 把 chunk 留在虚拟栈上(管道模式用),每次调用会重新执行
|
||||
/// - loadFunction() 执行一次顶层代码,保留返回的函数对象,后续 callFunction 多次调用不重复执行
|
||||
/// 注意:被加载的 Lua 文件必须在其顶层 return 一个函数。
|
||||
///
|
||||
/// @param path 函数所在文件路径
|
||||
/// @param name 函数名称(callFunction/unloadFunction 时使用)
|
||||
/// @return 当前实例
|
||||
/// @throws LuaError 当文件不存在/顶层未返回函数/已存在同名函数时抛出
|
||||
public func loadFunction(path: String, name: String): This {
|
||||
let pathPtr = toCStr(path)
|
||||
let namePtr = toCStr(name)
|
||||
let result = unsafe { loadfunction(this.handle, pathPtr, namePtr) }
|
||||
|
||||
unsafe {
|
||||
if (!pathPtr.isNull()) { LibC.free(pathPtr) }
|
||||
if (!namePtr.isNull()) { LibC.free(namePtr) }
|
||||
}
|
||||
|
||||
if (result != 0) {
|
||||
throw LuaError(unsafe { get_errno() })
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/// 卸载预加载的函数(释放 Registry 引用)
|
||||
///
|
||||
/// @param name loadFunction 时指定的函数名称
|
||||
/// @return 当前实例
|
||||
/// @throws LuaError 当函数未找到时抛出
|
||||
public func unloadFunction(name: String): This {
|
||||
let namePtr = toCStr(name)
|
||||
let result = unsafe { unloadfunction(this.handle, namePtr) }
|
||||
|
||||
unsafe {
|
||||
if (!namePtr.isNull()) { LibC.free(namePtr) }
|
||||
}
|
||||
|
||||
if (result != 0) {
|
||||
throw LuaError(unsafe { get_errno() })
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/// 调用已预加载的函数
|
||||
///
|
||||
/// 通过 name 在预加载函数表中查找,从 Lua Registry 取出函数对象后 pcall 调用。
|
||||
/// 不消耗该函数,因此可对同一函数重复调用(顶层代码只在 loadFunction 时执行一次)。
|
||||
/// 注意:与 runScript 管道模式完全独立,互不干扰。
|
||||
///
|
||||
/// @param name loadFunction 时指定的函数名称
|
||||
/// @param arg 传递给函数的单参数;传空字符串表示无参数(底层会转为 NULL)
|
||||
/// @return 函数执行的字符串结果
|
||||
/// @throws LuaError 当函数不存在或执行出错时抛出
|
||||
public func callFunction(name: String, arg: String): String {
|
||||
let namePtr = toCStr(name)
|
||||
// 空字符串会被 toCStr 转为 NULL,C 层据此识别“无参数”
|
||||
let argPtr = toCStr(arg)
|
||||
let code = unsafe { callfunction(this.handle, namePtr, argPtr) }
|
||||
|
||||
unsafe {
|
||||
if (!namePtr.isNull()) { LibC.free(namePtr) }
|
||||
if (!argPtr.isNull()) { LibC.free(argPtr) }
|
||||
}
|
||||
|
||||
this.cachedResult = toString(unsafe { getresult(this.handle) })
|
||||
|
||||
if (code != 0) {
|
||||
throw LuaError(unsafe { get_errno() }, this.cachedResult)
|
||||
}
|
||||
return this.cachedResult
|
||||
}
|
||||
|
||||
/// 获取缓存的结果
|
||||
public func result(): String { this.cachedResult }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user