开始
这是新版MeowPaste
工程的第一篇博客,我将履行重写MeowPaste
的承诺,使它更好用,代码更优雅。
MeowPaste是ahk编写的截图工具,目标是轻量且优雅
这次我们来重写历史图片管理,先前的版本太偏执,十分混乱。
需要的功能如下:
- 热键贴出历史图片,按时间顺序贴出
- 贴出的图如果关闭了,将放到重用池中,在下次优先贴出
- 如果程序启动间截图产生或销毁删除了图片,要能够适应
- 如果程序外部删除了图片,也要适应
实现
我的想法是:
- 先读取文件列表
- 当脚本新增图片时存入列表
- 删除时将列表的数据删除、
- 读取列表中文件时判断数据和文件是否存在,不存在则读取列表中下一条,直到找到为止。
我们需要三个变量:
- fileList 存储文件列表
- backPool 存储关闭的贴图id,将优先读取
- cur 指向当前文件在fileList中的下标
static fileList := [], backPool := [], cur := -1
具体的说:
在程序启动时读取历史目录中图片列表,之后不再读取(尽可能减少io)。
读取的列表按时间倒序存入数组(新的在数组末尾)。
static Init(_dir, _match := '*.bmp') {
l := this.fileList
; 时间倒序(默认就是)存入
FS.ReadDir(_dir, Noop, fullPath => l.Push(fullPath), _match)
this.cur := l.Length
}
使用倒序,则新增文件是添加到数组末尾,可以保证cur
不会被干扰。
- 增加文件时向数组末尾添加文件,同时向池中添加此id,保证在下次贴图时优先。
- 删除时使用delete()删除数组数据,这个方法不会改变数组长度。
static AddFile(fileName) {
this.fileList.Push(fileName), this.backPool.Push(this.fileList.Length)
}
static DelFile(id) => this.fileList.Delete(id) ; not removeAt
static ReturnToPool(id) => this.backPool.Push(id)
最后是关键的读取方法:
static Consume() {
if this.cur = -1
throw Error('未初始化')
if this.backPool.Length {
id := this.backPool.Pop()
if this.fileList.Has(id)
fullPath := this.fileList[id]
else {
logger.Debug('返回池中存放已销毁')
return History.Consume()
}
} else {
if this.cur = 0 {
return
} else {
id := this.cur, fullPath := this.fileList[this.cur--]
}
}
if !FileExist(fullPath) {
logger.Debug('外部删除了文件:' fullPath)
return History.Consume()
}
return { id: id, fullPath: fullPath }
}
里面使用递归,直到找到有效的文件为止,这样就解决了外部删除的问题。
完整代码
Include文件见仓库ahk-lib
当然,现在是看不出什么名堂的,当与贴图结合在一起才会感觉到它的好用。
我在旧工程中使用了它,感觉相当不错!
#Requires AutoHotkey v2.0
#Include g:\AHK\git-ahk-lib\util\Fs.ahk
class History {
static fileList := [], backPool := [], cur := -1
static Init(_dir, _match := '*.bmp') {
l := this.fileList
FS.ReadDir(_dir, Noop, fullPath => l.Push(fullPath), _match)
this.cur := l.Length
}
static Reset() {
this.cur := this.fileList.Length, this.backPool := []
}
static AddFile(fileName) {
this.fileList.Push(fileName), this.backPool.Push(this.fileList.Length)
}
static DelFile(id) => this.fileList.Delete(id) ; not removeAt
static ReturnToPool(id) => this.backPool.Push(id)
static Consume() {
if this.cur = -1
throw Error('未初始化')
if this.backPool.Length {
id := this.backPool.Pop()
if this.fileList.Has(id)
fullPath := this.fileList[id]
else {
logger.Debug('返回池中存放已销毁')
return History.Consume()
}
} else {
if this.cur = 0 {
return
} else {
id := this.cur, fullPath := this.fileList[this.cur--]
}
}
if !FileExist(fullPath) {
logger.Debug('外部删除了文件:' fullPath)
return History.Consume()
}
return { id: id, fullPath: fullPath }
}
}
标签:截图,cur,AHK2,backPool,fileList,id,static,fullPath,工具
From: https://www.cnblogs.com/refiz/p/18353280