我目前正在为Sway WM做一个小的状态栏.条形图由多个实现Widget
trait的对象组成.
在所有小部件中,时钟有点特殊.我不只是想渲染它,而且我还想确保它的渲染是及时完成的,否则显示的时间往往会有点偏离.由于这一要求,我需要既与时钟作为一个Widget
,也作为自己的Clock
.
我面临的问题是,一旦时钟小部件与其他小部件一起存储在一个向量中,borrow 判断器就不允许该向量之外的任何可变引用存在.这使得不可能在主应用程序循环中将时钟用作Clock
的实例.
在不引入运行时开销的情况下,我发现解决该问题的最干净的方法是通过原始指针和不安全代码.我想知道这个问题的其他零运行时开销解决方案.
以下是该代码的一个过度简化的版本,说明了当前代码的样子:
trait Widget {
fn update_info(&mut self);
fn render(&self);
}
struct NetworkStatus{}
impl Widget for NetworkStatus {
fn update_info(&mut self) {
// query the OS for network information
}
fn render(&self) {
println!("Connected wirelessly");
}
}
struct Clock{}
impl Widget for Clock {
fn update_info(&mut self) {
// query the OS for the current time
}
fn render(&self) {
println!("2024-03-06T19:25:17");
}
}
impl Clock {
fn get_alignment_delay(&mut self) -> std::time::Duration {
return std::time::Duration::new(1, 0);
}
}
fn main() {
let mut netstat = NetworkStatus{};
let mut clock = Clock{};
let clock_ptr = &mut clock as *mut Clock;
let mut widgets: Vec<&mut dyn Widget> = vec![
&mut netstat,
&mut clock,
];
loop {
for w in widgets.iter_mut() {
w.update_info();
}
for w in widgets.iter() {
w.render();
}
std::thread::sleep(unsafe {
(*clock_ptr).get_alignment_delay()
});
}
}
我知道不同的体系 struct 可以解决这个问题,但我只是有兴趣了解这个问题的一些解决方案,以便下次看到类似的情况时知道该怎么做.