mirror of
https://github.com/qingjian-team/qingjian.git
synced 2026-11-06 16:13:55 +00:00
* feat(linux): Server 接本地整句模型重排 - 照 Windows Server 的 dispatch/rescore 平移:后台加载、停键 80 ms 防抖、20 ms 收结果、2 s 兜底,只换整句候选 - 模型在后台接上时用户正在组句,补查一次攒下整句路径再起防抖,这一轮不错过重排 - 主循环改按 next_tick 的绝对到点时间等消息,防抖与轮询才到得了点;Poll 先 tick 再回帧 - 前文用本会话历史,不读应用光标前文;[model] 只在启动时读,Linux 没有配置热加载 * feat(linux): Poll 回帧内容没变时沿用展示身份 - 插件组句期间每 80 ms Poll 一次取重排结果;若每次都推进版本号,插件就得每拍重画、每拍回报曝光,面板闪且词汇统计被刷高 - 会话记下上次发出的帧,Poll 回的帧与之相同就当没有新展示:身份不变、不清曝光记录;重排换了顺序才推进 - KeyResult 的行为不变,每次按键仍是新的展示 * feat(linux): 插件组句期间轮询取本地整句模型的重排结果 - 插件是一问一答,Server 推不了;照 Windows DLL 挂一个 80 ms 定时器,组句期间发已有的 Poll 消息 - 只在 revision 推进时重画并回报;同版本什么都不做,面板不闪、曝光不重复记 - 帧为空、Reset、失焦、停用、断线时停表;定时器建一次反复用 - 回归:mock 全模式应答 Poll,rescore 模式第一条回换序帧,断言重画一次、回报一次 * build(linux): 安装清单加本地整句模型文件 - files.py 只装 data/generated,data-fetch.sh 取回的 data/model/model.qjm 没进清单,装完 Server 找不到模型 - 非样例安装把它按 data.lock 的校验值装到 resources/data/model/,缺文件提示先跑 data-fetch.sh - 用户文档:Linux 页去掉「暂不提供神经模型」,本地整句模型页补 Linux 的开关与自有模型路径 --------- Co-authored-by: Li <clwillsoncl@gmail.com>
50 lines
2.3 KiB
C++
50 lines
2.3 KiB
C++
//! 组句期间轮询:Server 回新版本的换序帧就重画一次并回报,同版本不重画也不重复回报。
|
|
#include "qingjian.h"
|
|
#include "support/context.h"
|
|
#include "support/mock.h"
|
|
#include <fcitx/inputcontextmanager.h>
|
|
#include <fcitx/inputpanel.h>
|
|
int main() {
|
|
qingjian::test::Mock mock("rescore");
|
|
char program[] = "qingjian-test"; char disable[] = "--disable=all";
|
|
char *arguments[] = {program, disable, nullptr};
|
|
fcitx::Instance instance(2, arguments);
|
|
instance.initialize();
|
|
fcitx::QingjianEngine engine(&instance.addonManager());
|
|
auto owned = std::make_unique<Context>(instance.inputContextManager());
|
|
auto &context = *owned;
|
|
context.setCapabilityFlags(fcitx::CapabilityFlag::Preedit);
|
|
context.focusIn();
|
|
assert(engine.process(&context, fcitx::Key(FcitxKey_n)));
|
|
auto candidates = context.inputPanel().candidateList();
|
|
assert(candidates && candidates->candidate(2).text().toString() == "你好");
|
|
// 事件循环只能 exec 一次:300 ms 时换序帧早到了(插件约每 80 ms Poll 一次,第一条就回换序帧),
|
|
// 断言后销毁上下文,再跑一拍让排队的 CloseSession 发出去。
|
|
int fired = 0;
|
|
// 精度给 1 ms:缺省的 250 ms 会让这一拍晚到,300 ms 内的 Poll 次数就数不准。
|
|
auto timer = instance.eventLoop().addTimeEvent(CLOCK_MONOTONIC, fcitx::now(CLOCK_MONOTONIC) + 300000, 1000,
|
|
[&](fcitx::EventSourceTime *source, uint64_t) {
|
|
if (++fired == 1) {
|
|
auto list = owned->inputPanel().candidateList();
|
|
assert(list && list->candidate(0).text().toString() == "你好");
|
|
owned.reset();
|
|
source->setNextInterval(30000);
|
|
source->setOneShot();
|
|
return true;
|
|
}
|
|
instance.eventLoop().exit();
|
|
return false;
|
|
});
|
|
instance.eventLoop().exec();
|
|
assert(fired == 2);
|
|
mock.join();
|
|
size_t polls = 0, acknowledged = 0;
|
|
for (const auto &message : mock.messages) {
|
|
if (message.contains("Poll")) ++polls;
|
|
if (message.contains("DisplayAcknowledged")) ++acknowledged;
|
|
}
|
|
assert(polls >= 2);
|
|
// 按键那帧回报一次、换序那帧回报一次;同版本的 Poll 不重画也不重复回报。
|
|
assert(acknowledged == 2);
|
|
}
|