开始

这是新版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 {
      while this.cur > 0 and !this.fileList.Has(this.cur)
        this.cru--
      if this.cur = 0
        return
      id := this.cur, fullPath := this.fileList[this.cur--]
    }
    if !FileExist(fullPath) {
      logger.Debug('外部删除了文件:' fullPath)
      return History.Consume()
    }
    return { id: id, fullPath: fullPath }
  }
}
posted on 2024-08-11 13:23  落寞的雪  阅读(20)  评论(0编辑  收藏  举报