FreeCAD中事务机制实现原理分析

1.基本实现思路

实现一个文件的撤销重做最简单的思想就是,在每个撤销重做节点处保存一份文件的内容,撤销重做时,分别替换对应节点处的文件内容即可。这种做法开销太大,每个节点处都需要保存一份完整的文档内容,每次撤销重做时都需要替换全部的文档内容。

如果每个撤销重做节点处只保存此节点相对于上一节点改变的内容,每次撤销重做时只修改两个节点间差异的内容,可以有效的降低撤销重做的开销。FreeCAD的撤销重做机制就是基于这种思想实现的。

节点和节点之间的修改可以总结为三种情况:增加、删除、改变。撤销重做机制的主要内容就是记录这三种情况下的修改,并复原这三种情况的修改。

2.FreeCAD撤销重做对象

FreeCAD撤销重做机制的对象是Document对象,也就是说,Document对象的修改可以被撤销重做,其他的不可以撤销重做。

3.FreeCAD撤销重做相关类

App::Document类中包含了一系列Transaction类的容器,可以看出,Transaction类其实是App::Document撤销重做节点的表示类。

分析Transaction类的成员:


他的成员变量只有三个,一个是表示其名称的Name,一个是表示其标识符的transID,一个是表示修改信息的_Objects。_Objects对象是一个多索引的容器,里面存储了一系列的TransactionalObject和TransactionObject的键值对。TransactionalObject表示的是Document中被修改的对象单元,App层Document的对象单元是以DocumentObject为基类的,Gui层的Document的对象单元是以ViewProviderDocumentObject为基类的。TransactionObject表示对象单元被修改的内容,当文档的对象单元被修改时,将修改前的内容记录在TransactionObject中。对应于Document的对象单元,TransactionObject也被分为两类,TransactionDocumentObject和TransactionViewProvider,分别保存App层和Gui层的对象单元的修改。_Objects对象则表示一系列对文档单元对象的修改。

Transaction类的有几个比较重要的方法:

apply方法时Transaction类执行撤销重做的借口,其流程比较简单,把所有的单元对象的修改依次执行撤销重做(这里之所以要将所有的修改都做一遍Del、New、Change是因为存在耦合的情况,New和Change可能存储在同一个修改记录中)。

以上这几个方法主要是添加单元对象的修改到该类的_Objects对象中。

再来分析TransactionObject类,其成员变量如下:

Status表征此次修改的类型:新建、删除或者修改;_PropChangeMap表示被修改的属性的容器,其key为属性指针,PropData为修改前属性的内容(这里还要说明一下,Document的单元对象其实都是一堆属性的容器,从其基类PropertyContainer可以看出,因此对文档的修改其实就是对其中的Property的修改,所以在此处存在一个容器保存所有被修改的属性);_NameInDocument表示文档中该对象单元的名字(注意这个单元对象在文档中名字与其Label属性不同,Label属性表示其对用户的名字,而这个名字表示这个对象在文档中存储的标识符)。

分析其成员函数:

这三个方法是执行撤销重做的接口,分析其函数内容:

Transaction中的applyDel和applyNew并没有实现任何内容,这是由于,这一层的TransactionObject并不知道到底是该对App层的Document操作还是Gui层的Document操作。

applyChn的主要功能则是将_PropChangeMap中的所有属性依次恢复到原来的状态。

再来分析TransactionDocumentObject类,如下所示,该类无其他成员变量,仅仅是重载了applyNew和applyDel方法。

分析其重载方法的实现:

在这两个方法中,分别将相应的DocumentObject对象移除和添加到App::Document中。

再来分析TransactionViewProvider类,

该类也仅仅是重载了applyNew和applyDel方法,分析其重载方法的实现

其applyNew方法将对应的ViewProviderDocumentObject添加到Gui::Document中,但applyDel方法中并未进行相应的删除工作,这是因为ViewProviderDocumentObject的删除是被DocumentObject触发实现的,并未提交到撤销重做系统中。

4.FreeCAD撤销重做的基本流程

创建撤销节点流程:

撤销执行流程:

重做执行流程:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

fastapi+vue3+primeflex前后端分离开发项目第一个程序

安装axios axios是用来请求后端接口的。 https://www.axios-http.cn/docs/intro pnpm 是一个前端的包管理工具,当我们需要给前端项目添加新的依赖的时候,就可以使用pnpm install 命令进行安装。 pnpm install axios安装 primeflex primeflex是一个cs…

十大经典排序算法——插入排序与希尔排序(超详解)

一、插入排序 1.基本思想 直接插入排序是一种简单的插入排序法,基本思想是:把待排序的记录按其数值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。 2.直接插入排序 当插入第 e…

(八)ReactHooks使用规则

ReactHooks使用规则 只能在组件中或者其他自定义Hook函数中使用只能在组件的顶层调用,不能嵌套在if、for、其他函数中

模拟原神圣遗物系统-小森设计项目,设计圣遗物词条基类

项目分析 首先需要理解圣遗物的方方面面 比如说圣遗物主词条部分和副词条部分都有那些特点 稍等一会:原神,启动! 在此说明了什么? 这是完全体 :主副 词条都有 如果 升级直接暴击率 那么就留点 或者是另外的元素充能 …

如何自制一个Spring Boot Starter并推送到远端公服

在现代Java开发中,Spring Boot无疑是一个强大且便捷的框架,它通过提供大量的Starter来简化依赖管理和项目配置。有时,我们可能需要为特定功能或团队定制Starter。本文将指导你如何创建自己的Spring Boot Starter并将其推送到远程公共服务器上…

[SAP ABAP] 运算符与操作符

1.算数运算符 算术运算符描述加法-减法*乘法/除法MOD取余 示例1 输出结果: 输出结果: 2.比较运算符 比较运算符描述示例 等于 A B A EQ B <> 不等于 A <> B A NE B >大于 A > B A GT B <小于 A < B A LT B >大于或等于 A > B A GE B <小…

33 - 连续出现的数字(高频 SQL 50 题基础版)

33 - 连续出现的数字 -- 开窗函数lead(col,n) 统计窗口内往下第n行值 -- over(partition by xxx) 按照xxx所有行进行分组 -- over(partition by xxx order by aaa) 按照xxx分组&#xff0c;按照aaa排序select distinct num as ConsecutiveNums from(select num,# 从当前记录获…

Mac M3 Pro 安装 Zookeeper-3.4.6

1、下载安装包 官方下载地址&#xff1a;https://archive.apache.org/dist/zookeeper/ 网盘下载地址&#xff1a;https://pan.baidu.com/s/1j6iy5bZkrY-GKGItenRB2w?pwdirrx 提取码: irrx 2、解压并添加环境变量 # 将安装包移动到目标目录 mv ~/Download/zookeeper-3.4.6.…

回归预测 | Matlab实现NGO-HKELM北方苍鹰算法优化混合核极限学习机多变量回归预测

回归预测 | Matlab实现NGO-HKELM北方苍鹰算法优化混合核极限学习机多变量回归预测 目录 回归预测 | Matlab实现NGO-HKELM北方苍鹰算法优化混合核极限学习机多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现NGO-HKELM北方苍鹰算法优化混合核极限…

elementui表格el-table最右侧操作列展示不完全

解决方法 .el-table__fixed,.el-table__fixed-right{height:100% !important;}

C++继承与多态—多重继承的那些坑该怎么填

课程总目录 文章目录 一、虚基类和虚继承二、菱形继承的问题 一、虚基类和虚继承 虚基类&#xff1a;被虚继承的类&#xff0c;就称为虚基类 virtual作用&#xff1a; virtual修饰成员方法是虚函数可以修饰继承方式&#xff0c;是虚继承&#xff0c;被虚继承的类就称为虚基类…

MySQL学习笔记-进阶篇-视图和存储过程

四、视图和存储过程 视图 存储过程 基本语法 创建 CREATE PROCEDURE ([参数列表]) BEGIN --SQL END; 调用 CALL 存储过程名&#xff08;[参数列表]&#xff09; 查看 --查看指定数据库的存储过程及状态信息 SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SHCEMA…

【网络安全的神秘世界】关于Linux中一些好玩的字符游戏

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 佛祖保佑 把 motd 通过xtp拖到Linux中 liyangUbuntu2204:~$ cp motd /etc/motd #一定要放在etc下 liyangUbuntu2204:~$ exi…

90 Realistic Arctic Environment Textures snow(90+种逼真的北极环境纹理--雪、冰及更多)

一组90多个逼真的雪、冰、雪地岩石和其他被雪覆盖的地面纹理,供在雪地环境中使用。每个纹理都是可贴的/无缝的,并且完全兼容各种不同的场景--标准的Unity地形、Unity标准着色器、URP、HDRP等等都兼容。 所有的纹理都是4096x4096,并包括一个HDRP掩码,以完全支持HDRP。 特点。…

Web项目部署后浏览器刷新返回Nginx的404错误对应解决方案

data: 2024/6/22 16:05:34 周六 limou3434 叠甲&#xff1a;以下文章主要是依靠我的实际编码学习中总结出来的经验之谈&#xff0c;求逻辑自洽&#xff0c;不能百分百保证正确&#xff0c;有错误、未定义、不合适的内容请尽情指出&#xff01; 文章目录 1.源头2.排错3.原因4.解…

MSPM0G3507——特殊的串口0

在烧录器中有串口0&#xff0c;默认也是串口0通过烧录线给电脑发数据。 如果要改变&#xff0c;需要变一下LP上的跳线帽。 需要更改如下位置的跳线帽

fastapi+vue3+primeflex前后端分离开发项目环境搭建

创建后端项目 创建文件夹&#xff1a; mkdir backend创建python虚拟环境&#xff1a; python -m venv venv使用Pycharm打开文件夹&#xff0c;然后配置python解释器为venv虚拟环境。 安装fastapi&#xff1a; pip install "fastapi[all]"编写第一个程序&#xf…

Vue56-组件的自定义事件

一、什么是自定义事件 二、子组件—【传值】—>父组件 2-1、prop属性 2-2、自定义事件 v-on在谁身上&#xff0c;就给谁绑定事件&#xff01; 给谁绑定的事件&#xff0c;想触发就找谁&#xff01; 2-3、prop属性VS自定义属性 2-4、简写形式 2-5、ref属性实现 加了ref属性…

华为---- RIP路由协议基本配置

08、RIP 8.1 RIP路由协议基本配置 8.1.1 原理概述 RIP(Routing Information Protocol,路由协议)作为最早的距离矢量IP路由协议&#xff0c;也是最先得到广泛使用的一种路由协议&#xff0c;采用了Bellman-Ford算法&#xff0c;其最大的特点就是配置简单。 RIP协议要求网络中…

分页查询前端对接

文章目录 添加角色修改角色当点击修改按钮后,那么就会弹出对话框,所以要设置显示为true点击修改的时候就是 要显示对话框 制作用户管理页面开发后端接口用户查询前端整合新增接口功能实现修改 添加角色 首先添加 添加表单的组件 那么总结一下 就是使用 组件 然后再使用变量接…