Skip to content

Commit 1f69908

Browse files
committed
update: modifyWeight will sync after 1 second;
1 parent c459750 commit 1f69908

File tree

6 files changed

+110
-6
lines changed

6 files changed

+110
-6
lines changed

core/core.go

+16-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
"github.com/MapoMagpie/rimedm/dict"
1515
"github.com/MapoMagpie/rimedm/tui"
16+
mutil "github.com/MapoMagpie/rimedm/util"
1617

1718
tea "github.com/charmbracelet/bubbletea"
1819
"github.com/junegunn/fzf/src/util"
@@ -178,7 +179,8 @@ func Start(opts *Options) {
178179
},
179180
}
180181

181-
// 修改权重
182+
// 修改权重,这是一个高频操作,通过debouncer延迟同步到文件。
183+
modifyWeightDebouncer := mutil.NewDebouncer(time.Millisecond * 1000) // 一秒后
182184
modifyWeightEvent := &tui.Event{
183185
Keys: []string{"ctrl+up", "ctrl+down", "ctrl+left", "ctrl+right"},
184186
Cb: func(key string, m *tui.Model) (tea.Model, tea.Cmd) {
@@ -230,14 +232,17 @@ func Start(opts *Options) {
230232
currEntry.ReRaw(currEntryData.ToBytes())
231233
listManager.ReSort()
232234
list := listManager.List()
233-
234235
// 重新设置 listManager 的 currIndex为当前修改的项
235236
for i, item := range list {
236237
if item.(*dict.MatchResult).Entry == currEntry {
237238
listManager.SetIndex(i)
238239
break
239240
}
240241
}
242+
// 延迟同步到文件
243+
modifyWeightDebouncer.Do(func() {
244+
FlushAndSync(opts, dc, opts.SyncOnChange)
245+
})
241246
}
242247
return m, func() tea.Msg { return 0 } // trigger bubbletea update
243248
},
@@ -265,6 +270,7 @@ func Start(opts *Options) {
265270
model := tui.NewModel(listManager, menuFetcher, events...)
266271
teaProgram := tea.NewProgram(model)
267272

273+
// 输入处理 搜索
268274
go func() {
269275
var cancelFunc context.CancelFunc
270276
resultChan := make(chan []*dict.MatchResult)
@@ -312,7 +318,15 @@ func Start(opts *Options) {
312318
}
313319
}
314320

321+
var lock *mutil.FLock = mutil.NewFLock()
322+
323+
// 同步变更到文件中,如果启用了自动部署Rime的功能则调用部署指令
315324
func FlushAndSync(opts *Options, dc *dict.Dictionary, sync bool) {
325+
// 此操作的阻塞的,但可能被异步调用,因此加上防止重复调用机制
326+
if lock.Should() {
327+
return
328+
}
329+
defer lock.Done()
316330
if !sync {
317331
return
318332
}

dict/dictionary.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func (d *Dictionary) Entries() []*Entry {
3838
}
3939

4040
func (d *Dictionary) Search(key []rune, resultChan chan<- []*MatchResult, ctx context.Context) {
41-
log.Println("search key: ", string(key))
41+
// log.Println("search key: ", string(key))
4242
if len(key) == 0 {
4343
done := false
4444
go func() {

dict/loader.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"reflect"
1111
"sync"
1212

13+
"github.com/MapoMagpie/rimedm/util"
1314
"github.com/goccy/go-yaml"
1415
)
1516

@@ -65,7 +66,7 @@ var (
6566

6667
func loadFromFile(path string, ch chan<- *FileEntries, wg *sync.WaitGroup) {
6768
defer wg.Done()
68-
fe := &FileEntries{FilePath: path, Entries: make([]*Entry, 0), ID: idgen.NextID()}
69+
fe := &FileEntries{FilePath: path, Entries: make([]*Entry, 0), ID: util.IDGen.NextID()}
6970
file, err := os.OpenFile(path, os.O_RDONLY, 0666)
7071
if fe.Err = err; err != nil {
7172
ch <- fe

util/debounce.go

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package util
2+
3+
import (
4+
"sync"
5+
"time"
6+
)
7+
8+
// Debouncer 防抖结构体
9+
type Debouncer struct {
10+
duration time.Duration
11+
timer *time.Timer
12+
mu sync.Mutex
13+
}
14+
15+
// New 创建一个新的防抖实例
16+
func NewDebouncer(duration time.Duration) *Debouncer {
17+
return &Debouncer{
18+
duration: duration,
19+
}
20+
}
21+
22+
// Debounce 防抖方法
23+
func (d *Debouncer) Do(f func()) {
24+
d.mu.Lock()
25+
defer d.mu.Unlock()
26+
27+
// 如果已有定时器,先停止
28+
if d.timer != nil {
29+
d.timer.Stop()
30+
}
31+
32+
// 设置新的定时器
33+
d.timer = time.AfterFunc(d.duration, f)
34+
}
35+
36+
// 使用示例:
37+
/*
38+
func main() {
39+
debouncer := debounce.New(500 * time.Millisecond)
40+
41+
for i := 0; i < 10; i++ {
42+
debouncer.Debounce(func() {
43+
fmt.Println("Executed after last call!")
44+
})
45+
time.Sleep(100 * time.Millisecond)
46+
}
47+
48+
// 等待足够长时间以确保最后一次执行
49+
time.Sleep(600 * time.Millisecond)
50+
}
51+
*/

dict/util.go renamed to util/id_generator.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dict
1+
package util
22

33
import "sync"
44

@@ -8,7 +8,7 @@ type IDGenerator struct {
88
}
99

1010
var (
11-
idgen *IDGenerator = &IDGenerator{currentID: 0}
11+
IDGen *IDGenerator = &IDGenerator{currentID: 0}
1212
)
1313

1414
func (gen *IDGenerator) NextID() uint8 {

util/lock.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package util
2+
3+
import (
4+
"sync"
5+
)
6+
7+
// FLock 用于防止函数重复调用的互斥锁工具
8+
type FLock struct {
9+
mu sync.Mutex
10+
inUse bool
11+
}
12+
13+
// NewFLock 创建一个新的 FunctionLock 实例
14+
func NewFLock() *FLock {
15+
return &FLock{}
16+
}
17+
18+
// Should 判断函数是否应该继续执行
19+
// 返回 true 表示可以执行,false 表示函数正在执行中
20+
func (fl *FLock) Should() bool {
21+
fl.mu.Lock()
22+
defer fl.mu.Unlock()
23+
24+
if fl.inUse {
25+
return false
26+
}
27+
28+
fl.inUse = true
29+
return true
30+
}
31+
32+
// Done 标记函数执行完成
33+
func (fl *FLock) Done() {
34+
fl.mu.Lock()
35+
defer fl.mu.Unlock()
36+
37+
fl.inUse = false
38+
}

0 commit comments

Comments
 (0)