双线程异步泵送、结果封送与线程安全规程
sequenceDiagram
participant GT as Game Thread (Actor/UI)
participant PL as Plugin Layer (Wrapper)
participant K as Worker Thread (Async Pump)
GT->>PL: 1. SendChatRequest()
PL->>K: 2. 封送 Lambda 闭包 (Marshalling)
activate K
K->>K: 3. 执行推理循环 (WaitUntilDone)
loop Token 产出
K->>PL: 4. Internal_OnChunk
PL-->>GT: 5. AsyncTask(GameThread) -> UI 更新
end
deactivate K
K-->>PL: 6. Internal_OnDone
PL-->>GT: 7. AsyncTask(GameThread) -> 业务结算
插件通过隔离计算线程与游戏线程,确保了大模型推理这种“重型物理动作”不会干扰游戏的帧率表现。
所有来自后台线程的回调,在进入插件封装层(Layer 2)时,都会被自动包裹在 ENamedThreads::GameThread 的 AsyncTask 中。业务层(Layer 3)接收到信号时,物理上已经回到了主线程。
SendChatRequest 本身是毫秒级的非阻塞调用。它只是将任务“投递”进管道队列。这种设计允许游戏在等待 AI 回复时,依然保持 60+ FPS 的物理模拟。
解析管道如何驱动业务渲染:
// 1. 业务层只需定义逻辑 (不用考虑线程)
FLiteRtLmChunkCallback MyOnChunk = ...Lambda([this](const FString& Chunk) {
// 物理安全性:此处已由插件保证处于 GameThread
UpdateUMG(Chunk);
});
// 2. 投递管道
Subsystem->SendChatRequest(..., MyOnChunk, ...);