作用
当前的作用是作为命令行终端中的图片显示的适配器,后面可能会引入更多的适配器?
Ueberzug
Ueberzug 是一个用于在终端显示图片的工具
引入的crate及其作用
|
|
静态变量及其作用
|
|
上面的代码定义了一个静态变量DEMON
,用于存储发送图片,显示命令的通道。这里的RoCell是一个只读Read-only的Cell
,用于存储初始化时消耗大的不可变静态对象。
Ueberzug的相关方法
start
如果不需要Ueberzug
,则直接用None
初始化静态变量DEMON
,否则,进入Ueberzug
的初始化逻辑。
当前终端不属于Self::Kitty | Self::KittyOld | Self::Iterm2 | Self::Sixel
这个集合时,需要初始化Ueberzug
,具体而言实际上是X11
,Wayland
,Chafa
这三种情况。
在初始化Ueberzug
的过程中,实际上是创建了一个Ueberzug
的进程,但是使用的并不是标准库的Command
和Child
而是异步版本的相关内容。
之后创建一个无界的多生产者,单消费者的通道,这里的无界的通道在中低负载的情况,因为减少了等待队列变得可用的时间,性能优于有界的通道,但是在高负载的情况下,有可能导致内存问题。
这个通道的消费者 接收端 ,被传入一个新的异步任务中,这个异步任务循环从接收端获取命令,并发送到Ueberzug
进程中。每次发到子进程前,都会检查进程是否仍存在,若不存在,则新建一个Ueberzug
进程。
而通道的生产者,则用于初始化上面的静态变量DEMON
。
image_show
这个方法的作用是,对给定的图片进行判断,来决定是缩放图片还是保持原样。
几个我觉得比较负责的语句是
模式匹配拿到tx
|
|
注意其中的DEMON
和RoCell
的定义如下,
|
|
这里的 &*DEMON
的解释是,首先对DEMON
进行解引用,获取RoCell
中的Option<UnboundedSender<Option<(PathBuf, Rect)>>>
,因为RoCell
实现了Deref
的Trait,所以可以这么做,然后再通过&
获取到Option<UnboundedSender<Option<(PathBuf, Rect)>>>
的引用,最后通过Some(tx)
,将其中的内容模式匹配到tx
中。
获取图片尺寸
|
|
spawn_blocking
是用于在异步运行时中,执行一个阻塞的操作,而这个阻塞操作是imagesize::size(path)
,这里的move
关键字的作用是获取path
的所有权,从而安全的使用该变量。
这句代码的一个特点是有两个?
,其中,第一个?
是用来处理spawn_blocking
返回的JoinHandle
中可能存在的错误,而第二个?
则是用于处理闭包中的imagesize::size(path)
的返回值,用于传播这个错误。
最后,let ImageSize { width: w, height: h }
这部分代码,是通过模式匹配来解构实例,最后的结果被赋值到了w
和h
这两个字段。
image_erase
擦除图片,通过在tx
上传一个None
来实现。
creat_demon
封装了创建Ueberzug
进程的代码。
adjust_rect
通过yazi-config
中的值,调整图片显示区域
send_command
和Ueberzug
进行通信的一层封装,实际用于画图和清除图片的代码都是通过调用send_command
来通知Ueberzug
进程的。