【rust/egui】(三)看看template的app.rs:序列化、持久化存储
说在前面
rust新手,egui没啥找到啥教程,这里自己记录下学习过程 环境:windows11 22H2 rust版本:rustc 1.71.1 egui版本:0.22.0 eframe版本:0.22.0 上一篇:这里
serde
app.rs
中首先定义了我们的TemplateApp
结构体
#[derive(serde::Deserialize, serde::Serialize)]
#[serde(default)]
pub struct TemplateApp { label: String , #[serde(skip)] value: f32 ,
}
impl Default for TemplateApp { fn default ( ) -> Self { Self { label: "Hello World!" . to_owned ( ) , value: 2.7 , } }
}
在定义TemplateApp
时,我们让其继承了serde::Deserialize, serde::Serialize
。serde
是rust中用于序列化和反序列化(ser ialize and de serialize)一个框架。详细见这里 在eframe
中,我们使用的是ron
提供的序列化实现,与json
类似,但并不一致,例如以下是一个ron
序列化的结果:Scene( // class name is optionalmaterials: { // this is a map"metal" : ( reflectivity: 1.0 ,) ,"plastic" : ( reflectivity: 0.5 ,) ,} ,entities: [ // this is an array( name: "hero" ,material: "metal" ,) ,( name: "monster" ,material: "plastic" ,) ,] ,
)
详细请参考https://github.com/ron-rs/ron 看一个简单的ron
序列化例子use serde:: { Deserialize , Serialize } ; #[derive(Debug, Deserialize, Serialize)]
struct MyStruct { boolean: bool , float: f32 ,
} impl MyStruct { fn new ( ) -> Self { return ron:: from_str ( "(boolean: true, float: 1.23)" ) . unwrap ( ) ; }
} fn main ( ) { let x = MyStruct :: new ( ) ; println! ( "RON: {}" , ron:: to_string ( & x) . unwrap ( ) ) ;
}
关于更深层次的内容这里就不再展开了 (咱也展开不下去) 。
持久化存储
有了serde
之后我们可以干什么呢?让我们继续看代码:impl TemplateApp { pub fn new ( cc: & eframe:: CreationContext < '_ > ) -> Self { if let Some ( storage) = cc. storage { return eframe:: get_value ( storage, eframe:: APP_KEY ) . unwrap_or_default ( ) ; } Default :: default ( ) }
} impl eframe:: App for TemplateApp { fn save ( & mut self , storage: & mut dyn eframe:: Storage ) { eframe:: set_value ( storage, eframe:: APP_KEY , self ) ; }
首先我们为TemplateApp
实现了new方法 而在之前的main.rs
中,我们可以看到该方法的调用,实际上,该函数是在eframe
的各种准备工作完成后,才进行的回调eframe:: run_native ( "demo app" , native_options, Box :: new ( | cc| Box :: new ( demo_app:: TemplateApp :: new ( cc) ) ) , )
在该函数中,我们完成了一些状态数据的还原,即读取应用上一次的工作状态,那么这些数据又是在什么时候存储下来的呢?以及存在了哪里呢? 在接下来的代码中,我们实现了eframe::App
特征,在save
方法中,我们对状态数据进行了存储,我们可以看看eframe::set_value
的具体实现:#[cfg(feature = "ron" )]
pub fn set_value < T : serde:: Serialize > ( storage: & mut dyn Storage , key: & str , value: & T ) { match ron:: ser:: to_string ( value) { Ok ( string) => storage. set_string ( key, string) , Err ( err) => log:: error! ( "eframe failed to encode data using ron: {}" , err) , }
}
我们可以运行一下应用看看效果,先修改输入: 关闭应用后再打开: 可以看到字符串确实保持一致,而数值已经变回原样了。 那我们的数据到底存储在哪里呢?参照上一节的做法,将eframe
的日志输出打开,可以看到存储路径打印出来了[ 2023 -08-19T09:26:27Z DEBUG eframe] Using the glow renderer
[ 2023 -08-19T09:26:27Z DEBUG eframe::native::run] Entering the winit event loop ( run_return) …
[ 2023 -08-19T09:26:27Z DEBUG eframe::native::file_storage] Loading app state from "C:\\ Users\\ xxxx\\ AppData\\ Roaming\\ demo app\\ data\\ app.ron" …
打开文件,可以看到存储的内容确实在,其中还存储了一些其他数据 当我们直接修改对应的数据后再打开应用,对应的数据也发生了变化: 既然是单个文件存储,那么是否会有竞争问题呢?我们打开两个应用A,B A想要改字符串,B同时改了字符串和数值,B先关闭,A后关闭 再次打开应用,B修改的数据丢失了 因此在开发/使用的时候需要注意多窗口下的数据存储问题
参考
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/44264.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!