【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)] // 在反序列化时,缺少的字段会使用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::Serializeserde是rust中用于序列化和反序列化(serialize and deserialize)一个框架。详细见这里
  • 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());
    }
    // 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_value<T: 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"
  • 打开文件,可以看到存储的内容确实在,其中还存储了一些其他数据
    在这里插入图片描述
  • 当我们直接修改对应的数据后再打开应用,对应的数据也发生了变化:
    在这里插入图片描述
  • 既然是单个文件存储,那么是否会有竞争问题呢?我们打开两个应用A,B
    在这里插入图片描述
    A想要改字符串,B同时改了字符串和数值,B先关闭,A后关闭
    在这里插入图片描述
    再次打开应用,B修改的数据丢失了
    在这里插入图片描述
    因此在开发/使用的时候需要注意多窗口下的数据存储问题

参考

  • serde
  • serde api
  • ron

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/44264.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git判断本地是否最新

场景需求 需要判断是否有新内容更新,确定有更新之后执行pull操作&#xff0c;然后pull成功之后再将新内容进行复制到其他地方 pgit log -1 --prettyformat:"%H" HEAD -- . "origin/HEAD" rgit rev-parse origin/HEAD if [[ $p $r ]];thenecho "Is La…

域名解析和代理

购买域名 这里使用腾讯云进行购买。 对域名进行解析 通过添加记录接口对域名进行解析。 此时我们的服务器地址就被解析到域名上了。 我们可以通过以下格式进行访问&#xff1a; [域名]:[对应的项目端口] 效果为下: 通过nginx进行代理 如果我们使用上述的方式进行访问还是…

【hive】hive分桶表的学习

hive分桶表的学习 前言&#xff1a; 每一个表或者分区&#xff0c;hive都可以进一步组织成桶&#xff0c;桶是更细粒度的数据划分&#xff0c;他本质不会改变表或分区的目录组织方式&#xff0c;他会改变数据在文件中的分布方式。 分桶规则&#xff1a; 对分桶字段值进行哈…

react之react-redux的介绍、基本使用、获取状态、分发动作、数据流、reducer的分离与合并等

react之react-redux的介绍、基本使用、获取状态、分发动作、数据流、reducer的分离与合并等 一、react-redux介绍二、React-Redux-基本使用三、获取状态useSelector四、分发动作useDispatch五、 Redux 数据流六、代码结构七、ActionType的使用八、Reducer的分离与合并九、购物挣…

计算机视觉的应用11-基于pytorch框架的卷积神经网络与注意力机制对街道房屋号码的识别应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用11-基于pytorch框架的卷积神经网络与注意力机制对街道房屋号码的识别应用&#xff0c;本文我们借助PyTorch&#xff0c;快速构建和训练卷积神经网络&#xff08;CNN&#xff09;等模型&#xff0c;…

【Redis从头学-5】Redis中的List数据类型实战场景之天猫热销榜单

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;啥技术都喜欢捣鼓捣鼓&#xff0c;喜欢分享技术、经验、生活。 &#x1f60e;人生感悟&#xff1a;尝尽人生百味&#xff0c;方知世间冷暖。 &#x1f4d6;所属专栏&#xff1a;Re…

git错误记录

露id没有影响&#xff0c;搞得微软不知道我ip一样 git fatal: 拒绝合并无关的历史的错误解决(亲测有效)

mybatis缓存

目的&#xff1a;提高查询效率。 映射语句文件中的所有 select 语句的结果将会被缓存。映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。缓存会使用最近最少使用算法&#xff08;LRU, Least Recently Used&#xff09;算法来清除不需要的缓存。缓存不会定时进行…

Matplotlib绘图知识小结--Python数据分析学习

一、Pyplot子库绘制2D图表 1、Matplotlib Pyplot Pyplot 是 Matplotlib 的子库&#xff0c;提供了和 MATLAB 类似的绘图 API。 Pyplot 是常用的绘图模块&#xff0c;能很方便让用户绘制 2D 图表。 Pyplot 包含一系列绘图函数的相关函数&#xff0c;每个函数会对当前的图像进行…

爬虫框架- feapder + 爬虫管理系统 - feaplat 的学习简记

文章目录 feapder 的使用feaplat 爬虫管理系统部署 feapder 的使用 feapder是一款上手简单&#xff0c;功能强大的Python爬虫框架 feapder 官方文档 文档写的很详细&#xff0c;可以直接上手。 基本命令&#xff1a; 创建爬虫项目 feapder create -p first-project创建爬虫 …

根据源码,模拟实现 RabbitMQ - 实现消息持久化,统一硬盘操作(3)

目录 一、实现消息持久化 1.1、消息的存储设定 1.1.1、存储方式 1.1.2、存储格式约定 1.1.3、queue_data.txt 文件内容 1.1.4、queue_stat.txt 文件内容 1.2、实现 MessageFileManager 类 1.2.1、设计目录结构和文件格式 1.2.2、实现消息的写入 1.2.3、实现消息的删除…

如何将常用的jdbc方法封装起来???

你是否还在为每次新建项目连接数据库而烦恼&#xff1f;&#xff1f;&#xff1f;&#xff08;教你一次代码&#xff0c;简单完成每次连接&#xff09; 1.建立maven项目 还没下载安装或者不会建立maven项目的可以看这里哦&#xff1a;maven的下载安装与配置环境变量&#xff0…

javascript期末作业【三维房屋设计】 【源码+文档下载】

1、引入three.js库 官网下载three.js 库 放置目录并引用 引入js文件: 设置场景&#xff08;scene&#xff09; &#xff08;1&#xff09;创建场景对象 &#xff08;2&#xff09;设置透明相机 1,透明相机的优点 透明相机机制更符合于人的视角,在场景预览和游戏场景多有使用…

VALN-hybrid模式

实验拓扑及要求 一、实验思路 1.R1-R3按要求配置&#xff0c;R2不划分vlan使其全部都可以访问 2.交换机和路由器的交换机直连接口设为hybrid模式且R4-R6不带vlan标签访问路由器 3.交换机和交换机的两个直连接口设为hybrid模式且只允许R4-R6所在vlan标签通过 4.R4-R6只允许其…

怎么对视频进行压缩?

怎么对视频进行压缩&#xff1f;视频压缩&#xff0c;我们都知道是将视频文件进行压缩变小的过程&#xff0c;是我们日常办公中较为常用的手段。现如今&#xff0c;在视频技术不断发展与创新的基础上&#xff0c;视频分辨率也在不断提高&#xff0c;进而导致文件占有量也非常大…

2023河南萌新联赛第(五)场:郑州轻工业大学

A.买爱心气球 原题链接 : 登录—专业IT笔试面试备考平台_牛客网 博弈论 : #include <iostream> using namespace std; int t,n,m; string s1 "Alice",s2 "Bob"; int main() {cin>>t;while(t--){cin>>n>>m;if (n % 3 0) {cou…

【HarmonyOS】codelab在hvigor版本2.4.2上无法运行问题

【关键字】 HarmonyOS、codelab、hvigor 【问题描述】 有cp反馈集成鸿蒙codelab报错。 下载音乐专辑示例文件&#xff08;一次开发&#xff0c;多端部署-音乐专辑&#xff08;ArkTS&#xff09; (huawei.com)&#xff09;后构建项目&#xff0c;显示找不到2.5.0的hvigor。 …

数学建模之“层次分析法”原理和代码详解

一、层次分析法简介 层次分析法&#xff08;Analytic Hierarchy Process&#xff0c;AHP&#xff09;是一种用于多准则决策分析和评估问题的定量方法&#xff0c;常用于数学建模中。它是由数学家托马斯赛蒂&#xff08;Thomas Saaty&#xff09;开发的。 层次分析法将复杂的决…

读发布!设计与部署稳定的分布式系统(第2版)笔记33_混沌工程

1. 康威定律 1.1. 梅尔文康威 1.1.1. Melvin Conway 1.1.2. 1968年 1.1.3. 在设计系统时&#xff0c;组织受制于其自身的沟通结构&#xff0c;这使得它设计的系统结构与沟通结构相一致。 1.1.3.1. 社会学现象 1.2. 要在系统内部或系统之间构建接口&#xff0c;两个人必须…

Spring事件监听源码解析

spring事件监听机制离不开容器IOC特性提供的支持&#xff0c;比如容器会自动创建事件发布器&#xff0c;自动识别用户注册的监听器并进行管理&#xff0c;在特定的事件发布后会找到对应的事件监听器并对其监听方法进行回调。Spring帮助用户屏蔽了关于事件监听机制背后的很多细节…