问题说明
在一些场景中,librime-lua定义的组件需要像其他组件那样在初始化时定义部分组件实例私有的存储。
但目前的文档和示例似乎并没有考虑组件实例私有的存储,建议定义实例私有存储的范式。
场景示例
例如有一个filter,它在初始化过程中会随机生成一个int32的值randvar,并在运行时为Translation的各个Candidate的comment字符追加初始化的randvar。
由于文档和示例并未对此场景进行说明,因此有可能会进行以下不符场景要求的编程示例:
-- Filter
-- BUG: `randvar` is an static value for this filter. Different instance of this filter will got same value.
local randvar = nil
---@type fun(env: Env): nil
local function filter_init(env)
randvar = math.random(1<<30)
end
---@type fun(translation: Translation, env: Env): nil
local function do_filter(translation, env)
for cand in translation:iter() do
cand.comment = string.format("%s %X", cand.comment, randvar)
end
end
return {
init = filter_init,
func = do_filter,
fini = function (_)
end
}
预期方案
针对上述示例,一个可行的实践方案是定义接口时额外添加参数作为单独的实例存储。
-- Filter
-- InstPrivVar: user defined struct for filter's per-instance storage.
---@class InstPrivVar
---@field randvar integer
-- inst will be initialized as an empty table by librime-lua runtime
---@type fun(env: Env, inst: InstPrivVar): nil
local function filter_init(env, inst)
inst.randvar = math.random(1<<30)
end
---@type fun(translation: Translation, env: Env, inst: InstPrivVar): nil
local function do_filter(translation, env, inst)
for cand in translation:iter() do
cand.comment = string.format("%s %X", cand.comment, inst.randvar)
end
end
return {
init = filter_init,
func = do_filter,
fini = function (_)
end
}
目前实践
上述方案会造成接口变化。注意到参数env在现有代码中为librime-lua类中的成员变量[1][2],因此可以经由env实现这一目标。但这一方案似乎并未在文档中提及。
-- Filter
-- PrivType: user defined struct for filter's per-instance storage.
---@class PrivType
---@field randvar integer
-- inst will be initialized as an empty table by librime-lua runtime
---@type fun(env: Env): nil
local function filter_init(env)
---@type PrivType
env.priv = {}
env.priv.randvar = math.random(1<<30)
end
---@type fun(translation: Translation): nil
local function do_filter(translation, env)
for cand in translation:iter() do
cand.comment = string.format("%s %X", cand.comment, env.priv.randvar)
end
end
return {
init = filter_init,
func = do_filter,
fini = function (_)
end
}
1:
2:
|
*env = LuaObj::todata(L, -1); |
问题说明
在一些场景中,
librime-lua定义的组件需要像其他组件那样在初始化时定义部分组件实例私有的存储。但目前的文档和示例似乎并没有考虑组件实例私有的存储,建议定义实例私有存储的范式。
场景示例
例如有一个filter,它在初始化过程中会随机生成一个
int32的值randvar,并在运行时为Translation的各个Candidate的comment字符追加初始化的randvar。由于文档和示例并未对此场景进行说明,因此有可能会进行以下不符场景要求的编程示例:
预期方案
针对上述示例,一个可行的实践方案是定义接口时额外添加参数作为单独的实例存储。
目前实践
上述方案会造成接口变化。注意到参数
env在现有代码中为librime-lua类中的成员变量[1][2],因此可以经由env实现这一目标。但这一方案似乎并未在文档中提及。1:
librime-lua/src/lua_gears.h
Line 59 in e3912a4
2:
librime-lua/src/lua_gears.cc
Line 72 in e3912a4