## 核心改进 ### TTS 模块重构 - 统一 API,仅保留 Sound(ctx, text) 方法 - 优化日志,添加 [TTS] 前缀和结构化字段 - 实现互斥等待:同时只播放一个,新请求等待旧播放完成 - 响应 context 取消:超时或断开时立即停止播放 - 移除全局 context 存储,改为参数传递 - 简化实例化:New(config) 无需传入 context ### 代码质量提升 - 修复 PlayWav/PlayMP3 的死循环 bug(context 取消时缺少 return) - 修复 standby_ctrl/pause.go 的忙循环(添加 Sleep 避免CPU 100%) - 添加关键路径错误传播(only_video.go 不再忽略播放错误) - 新增 pkg/errorsx/handler.go 统一错误处理工具 ## 代码优化 - TTS 代码从 234 行精简到 166 行(减少 29%) - 移除冗余状态管理(playing 标志、等待循环) - 利用互斥锁的阻塞特性实现优雅等待 - 保持简洁易读的代码风格 ## 行为说明 ✅ 同时只能播放一个 TTS(互斥) ✅ 新请求等待当前播放完成(不打断) ✅ 响应 context 取消(超时停止) ✅ 日志完善,便于排查问题 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
68 lines
1.2 KiB
Go
68 lines
1.2 KiB
Go
package standby_ctrl
|
|
|
|
import (
|
|
"context"
|
|
"game-driver/internal/common"
|
|
"go.uber.org/zap"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// Pause 暂停控制器
|
|
func Pause(ps *common.PauseSub, isPause bool, play func(c context.Context) error) func(c context.Context) error {
|
|
return func(c context.Context) error {
|
|
var cancel context.CancelFunc
|
|
run := true
|
|
|
|
if isPause {
|
|
zap.S().Infoln("待机暂停控制器")
|
|
defer zap.S().Infoln("待机暂停控制器结束")
|
|
|
|
p := ps.GetNew()
|
|
defer ps.Close(p)
|
|
|
|
// 等待组
|
|
var wait sync.WaitGroup
|
|
defer wait.Wait()
|
|
|
|
wait.Add(1)
|
|
go func() {
|
|
defer wait.Done()
|
|
for {
|
|
select {
|
|
case <-c.Done():
|
|
return
|
|
case v := <-p:
|
|
if v == 1 {
|
|
zap.S().Infoln("待机控制器 Pause 触发")
|
|
run = false
|
|
cancel()
|
|
} else {
|
|
zap.S().Infoln("待机控制器 Resume 触发")
|
|
run = true
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
for {
|
|
select {
|
|
case <-c.Done():
|
|
return nil
|
|
default:
|
|
if run {
|
|
nc, cc := context.WithCancel(c)
|
|
cancel = cc
|
|
err := play(nc)
|
|
if err != nil {
|
|
zap.S().Infoln("执行后续操作异常: ", err)
|
|
}
|
|
}
|
|
// 避免忙循环,短暂休眠
|
|
time.Sleep(10 * time.Millisecond)
|
|
}
|
|
}
|
|
}
|
|
}
|