Repository navigation
fix: Maimoller 手台在游戏加载阶段/卡顿不更新灯光阶段 手台回落到固件待机灯 - #155
Conversation
审查者指南引入后台 LED 输出保活机制,在静默 100 毫秒后重新发送当前状态,防止 Maimoller 设备在初始化或帧停滞期间恢复为固件待机灯效,同时使用非阻塞锁获取,避免增加游戏线程的延迟。 Maimoller LED 输出保活时序图sequenceDiagram
participant GameThread
participant MaimollerDeviceNative
participant KeepAliveThread
participant HIDDevice
GameThread->>MaimollerDeviceNative: Update()
MaimollerDeviceNative->>MaimollerDeviceNative: Monitor.TryEnter(_outputLock)
alt lock acquired
MaimollerDeviceNative->>HIDDevice: HidRawIO.Write(_reportBuffer)
else lock unavailable
MaimollerDeviceNative-->>GameThread: Skip output without blocking
end
loop every 25ms
KeepAliveThread->>MaimollerDeviceNative: KeepAliveThread()
alt silence exceeds 100ms
MaimollerDeviceNative->>MaimollerDeviceNative: WriteOutputReport(force: true)
MaimollerDeviceNative->>HIDDevice: HidRawIO.Write(_reportBuffer)
end
end
文件级变更
可能关联的问题
提示和命令与 Sourcery 交互
自定义你的使用体验访问你的控制面板以:
获取帮助Original review guide in EnglishReviewer's GuideIntroduces a background LED output keep-alive that resends the current state after 100 ms of silence, preventing Maimoller devices from reverting to firmware standby lighting during initialization or stalled frames, while using non-blocking lock acquisition to avoid adding latency to the game thread. Sequence diagram for Maimoller LED output keep-alivesequenceDiagram
participant GameThread
participant MaimollerDeviceNative
participant KeepAliveThread
participant HIDDevice
GameThread->>MaimollerDeviceNative: Update()
MaimollerDeviceNative->>MaimollerDeviceNative: Monitor.TryEnter(_outputLock)
alt lock acquired
MaimollerDeviceNative->>HIDDevice: HidRawIO.Write(_reportBuffer)
else lock unavailable
MaimollerDeviceNative-->>GameThread: Skip output without blocking
end
loop every 25ms
KeepAliveThread->>MaimollerDeviceNative: KeepAliveThread()
alt silence exceeds 100ms
MaimollerDeviceNative->>MaimollerDeviceNative: WriteOutputReport(force: true)
MaimollerDeviceNative->>HIDDevice: HidRawIO.Write(_reportBuffer)
end
end
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
您好——我发现了 1 个问题
给 AI 代理的提示
请处理此次代码审查中的评论:
## 单条评论
### 评论 1
<location path="AquaMai.Mods/GameSystem/MaimollerIO/Libs/MaimollerDeviceNative.cs" line_range="41" />
<code_context>
private readonly InputLatch _inputLatch = new();
private readonly MaimollerOutputReport _output = new();
private readonly MaimollerLedManager _ledManager;
+ private readonly object _outputLock = new();
</code_context>
<issue_to_address>
**发送了混合的 LED 状态**
当游戏线程中的 LED 更新与报告序列化重叠时,`MaimollerLedManager` 的 setter 会在未使用 `_outputLock` 的情况下修改 `_output`,而 `KeepAliveThread` 同时对其进行序列化,因此报告会混合新旧 LED 值,导致控制器短暂显示错误的颜色或亮度。
请使用序列化期间所用的同一个锁来保护 LED 的修改,或者从一致的快照进行序列化。
此外,还涉及 `AquaMai.Mods/GameSystem/MaimollerIO/Libs/MaimollerDeviceNative.cs:68`、`AquaMai.Mods/GameSystem/MaimollerIO/Libs/MaimollerDeviceNative.cs:206`、`AquaMai.Mods/GameSystem/MaimollerIO/Libs/MaimollerDeviceNative.cs:214` 和 `AquaMai.Mods/GameSystem/MaimollerIO/Libs/MaimollerDeviceNative.cs:230`。
</issue_to_address>Sourcery 评估
等待批准。 请先处理 1 个发现的问题。
阻塞性发现:AquaMai.Mods/GameSystem/MaimollerIO/Libs/MaimollerDeviceNative.cs:41
Original comment in English
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="AquaMai.Mods/GameSystem/MaimollerIO/Libs/MaimollerDeviceNative.cs" line_range="41" />
<code_context>
private readonly InputLatch _inputLatch = new();
private readonly MaimollerOutputReport _output = new();
private readonly MaimollerLedManager _ledManager;
+ private readonly object _outputLock = new();
</code_context>
<issue_to_address>
**Mixed LED states are sent**
When a game-thread LED update overlaps report serialization, `MaimollerLedManager` setters mutate `_output` without `_outputLock`, while `KeepAliveThread` serializes it, so the report combines old and new LED values and the controller briefly shows incorrect colors or brightness.
Protect LED mutations with the same lock used during serialization, or serialize from a consistent snapshot.
Also at `AquaMai.Mods/GameSystem/MaimollerIO/Libs/MaimollerDeviceNative.cs:68`, `AquaMai.Mods/GameSystem/MaimollerIO/Libs/MaimollerDeviceNative.cs:206`, `AquaMai.Mods/GameSystem/MaimollerIO/Libs/MaimollerDeviceNative.cs:214`, `AquaMai.Mods/GameSystem/MaimollerIO/Libs/MaimollerDeviceNative.cs:230`.
</issue_to_address>Sourcery assessment
Approval pending. 1 finding to address first.
Blocking findings: AquaMai.Mods/GameSystem/MaimollerIO/Libs/MaimollerDeviceNative.cs:41
|
我觉得有没有必要,就是主线程就不用发了,发送灯光就直接放在那个单开的线程里面好了,单开的那个线程,看灯光0.5秒没发过或者变化了就发? |
There was a problem hiding this comment.
All reported issues were addressed across 1 file
Reply to a comment to ask cubic a question or push back. It learns from your replies.
View guided diff | Re-trigger cubic
|
那主线程就不发了。改成主线程只管序列化 + 标脏,后台线程统一发包,脏了或者距上次发超过 500ms 就发。 |
- 移除主线程直接写 HID 的逻辑,Update 只发布 64 字节状态快照 - 新增输出线程,Monitor.Wait 等待状态变化或保活超时,是唯一的 HID 写入方 - HID 写入不再持有锁,避免主线程被后台写入阻塞 - 保活间隔改为实测的 500ms,重连后立即补发一次
进游戏之前 PreGameMainUpdate 被 isInitialize 挡着,主循环一发 LED 报告都不发,
手台的 LED 通道静默久了就切回固件自带的待机灯,一直亮到加载结束才恢复。
游戏卡住或者掉帧的时候主循环不跑,一样会断包,现象相同。
加了个后台保活线程,25ms 检查一次,距上次发包超过 100ms 就补发一发当前状态,
这两种情况都能盖住。主线程那边用 Monitor.TryEnter,抢不到锁直接跳过,不阻塞游戏线程。
(一开始用的是阻塞 lock,每帧都会撞上后台那次 HID 写,帧耗时能到 17ms,所以改成不等待的)
Sourcery 摘要
在游戏循环未更新期间保持 Maimoller LED 输出处于活动状态,同时不阻塞帧执行。
新功能:
错误修复:
增强功能:
Original summary in English
Sourcery 摘要
在游戏循环更新停滞期间保持 Maimoller LED 输出,且不会阻塞帧执行。
新功能:
错误修复:
增强:
Original summary in English
Summary by Sourcery
Keep Maimoller LED output alive during stalled game-loop updates without blocking frame execution.
New Features:
Bug Fixes:
Enhancements: