塘厦镇做网站,做网站 钱,家在深圳宝安,网站建设怎么付费说在前面 rust新手#xff0c;egui没啥找到啥教程#xff0c;这里自己记录下学习过程环境#xff1a;windows11 22H2rust版本#xff1a;rustc 1.71.1egui版本#xff1a;0.22.0eframe版本#xff1a;0.22.0上一篇#xff1a;这里 serde
app.rs中首先定义了我们的Templ…说在前面 rust新手egui没啥找到啥教程这里自己记录下学习过程环境windows11 22H2rust版本rustc 1.71.1egui版本0.22.0eframe版本0.22.0上一篇这里 serde
app.rs中首先定义了我们的TemplateApp结构体/// 继承序列化以及反序列化 用于存储一些状态数据
#[derive(serde::Deserialize, serde::Serialize)]
#[serde(default)] // 在反序列化时缺少的字段会使用Default特征对应的值进行初始化
pub struct TemplateApp {// Example stuff:label: String,// 声明该字段跳过序列化#[serde(skip)]value: f32,
}
// 为TemplateApp实现Default特征
impl Default for TemplateApp {fn default() - Self {Self {// Example stuff:label: Hello World!.to_owned(),value: 2.7,}}
}在定义TemplateApp时我们让其继承了serde::Deserialize, serde::Serialize。serde是rust中用于序列化和反序列化(serialize and deserialize)一个框架。详细见这里在eframe中我们使用的是ron提供的序列化实现与json类似但并不一致例如以下是一个ron序列化的结果Scene( // class name is optionalmaterials: { // this is a mapmetal: (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());
}
// output:
// RON: (boolean:true,float:1.23)关于更深层次的内容这里就不再展开了 (咱也展开不下去) 。
持久化存储
有了serde之后我们可以干什么呢让我们继续看代码impl TemplateApp {/// 在第一帧之前调用pub fn new(cc: eframe::CreationContext_) - Self {// 我们也可以在这里定义我们的界面样式 使用cc.egui_ctx.set_visuals and cc.egui_ctx.set_fonts.// 加载一些应用状态比如上一次打开了那些文件之类的 但是我们必须启用persistence特性if let Some(storage) cc.storage {// 这里我们使用ron取出存入的状态数据 并将其反序列化成TemplateAppreturn 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) {// 这里我们使用ron将TemplateApp序列化 并且存入对应的文件中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_valueT: serde::Serialize(storage: mut dyn Storage, key: str, value: T) {// 首先对TemplateApp进行序列化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…打开文件可以看到存储的内容确实在其中还存储了一些其他数据 当我们直接修改对应的数据后再打开应用对应的数据也发生了变化 既然是单个文件存储那么是否会有竞争问题呢我们打开两个应用AB A想要改字符串B同时改了字符串和数值B先关闭A后关闭 再次打开应用B修改的数据丢失了 因此在开发/使用的时候需要注意多窗口下的数据存储问题
参考
serdeserde apiron