在一般软件中,都会有Undo和Redo的功能,那么这个功能该怎么实现呢?在此介绍一种实现方法。(以lua语言为例)

  1. 操作事件化。将用户的操作转换成一个事件数据,里面包括事件类型、操作目标、目标原始状态、操作后状态等。比如:

-- 移动某结点可转换为
local moveEvent = {event = "Move", target = "selectNode", orginPos = cc.p(0, 0), endPos = cc.p(100, 100)}
-- 新建结点可转换为
local newEvent = {event = "Delete", name = "bgSprite"}

  2. 事件处理与存储。新建一个类EventManager,用于存储所有的操作事件。在用户操作时并不直接执行对应的处理,而是将操作命令发给EventManager进行统一的处理。EventManager大致像这样:

-- eventList:存储用户操作的事件列表
-- statusIndex: 当前软件的执行事件位置
-- saveIndex: 当前软件的保存事件位置
EventManager = {eventList = {}, statusIndex = 0}

-- 新加事件
function EventManager:doEvent(cmd)-- 执行真正的操作变化
    UIController:doEvent(cmd)-- 将当前操作位置之后的抛弃,statusIndex在发生Redo后将不再是列表长度for i=#self.eventList, (self.statusIndex + 1), -1 dotable.remove(self.eventList, i)end-- 加入事件队列table.insert(self.eventList, cmd)self.statusIndex = #self.eventList
end

用户撤回(Undo)时,需要将上一个事件转换为撤回事件,如上文的moveEvent可转换为:

{event = "Move", target = "selectNode", orginPos = cc.p(100, 100), endPos = cc.p(0, 0)}

newEvent可转换为:

{event = "Delete", name = "bgSprite"}

具体undo方法大致如下:

-- 撤回操作
function EventManager:undo()if self.statusIndex > 0 then-- 获取撤回事件,依事件情况实现local undoCmd = self:getUndoCmd(self.eventList[self.statusIndex])self.statusIndex = self.statusIndex - 1-- 执行真正的操作变化
        UIController:doEvent(undoCmd)end
end

redo方法就比较简单了,只需将存储的事件再次执行即可:

-- 重做
function EventManager:redo()if self.statusIndex < #self.eventList thenself.statusIndex = self.statusIndex + 1local redoCmd = self.eventList[self.statusIndex]-- 执行真正的操作变化
        UIController:doEvent(redoCmd)end
end

  以上我们就实现了操作的Undo和Redo功能。基于此我们可以引出另外一个功能:在软件中标注当前的修改状态,如图。我们只需要在EventManager中添加一个变量saveIndex来标记当前的保存位置。当saveIndex==statusIndex时表示当前状态已保存,否则当前的修改未保存。需要在doEvent/undo/redo方法中刷新软件标题的显示状态。当用户保存时,则重置saveIndex的位置:

function EventManager:save()self.saveIndex = self.statusIndex-- 重置软件的标题fc.SetWindowTitle("fcediter")
end

转载于:https://www.cnblogs.com/hghhe/p/9669107.html

软件中Undo(撤回)和Redo(重做)的实现相关推荐

  1. Oracle 中UNDO与REDO的差别具体解释

    一 为了更清楚的看出2者差别,请看下表:                                               UNDO                             ...

  2. oracle的redo和undo,Oracle的redo 和undo的區別

    寫的次序: redo--> undo-->datafile insert一條記錄時, 表跟undo的信息都會放進 redo 中, 在commit 或之前, redo 的信息會放進硬盤上. ...

  3. MySQL日志(undo log 和 redo log 实现事务的原子性/持久性/一致性)

    日志的重要性 日志绝对是数据库的核心.   持久化的日志记录了各种重要的信息. 数据的恢复需要依赖日志.  慢查询sql语句需要用到慢查询日志.以及错误日志中保存着mysqld数据库服务端在启动过程中 ...

  4. Oracle学习笔记:redo重做日志

    redo重做日志对于oracle来说犹如 肝脏 那么重要,是oracle机能中的排毒恢复健康的重要部件!! 相关的基本概念: 1.scn 2.日志序列号 3.日志组 和 日志 成员,尤其是日志文件的尺 ...

  5. 中怎么撤回消息_微信消息撤回也能看到,这个开源神器牛x!语音、图片、文字都支持!...

    1.前言 微信在2014年的时候,发布的v5.3.1 版本中推出了消息撤回功能,用户可以选择撤回 2 分钟内发送的最后一条信息. 现在很多即时通讯的软件都有撤回这个功能. 腾讯为了照顾手残党,在微信和 ...

  6. python里的demo是什么意思_软件中的“DEMO” 是什么意思?游戏中的“DEMO呢?

    软件中的"DEMO" 是什么意思?游戏中的"DEMO呢? 2020-08-27 提示Initialization failure:0x0000000c错误无法上网?解决方 ...

  7. 电气设计软件中最常见的10个错误

    设计早期的设备名称重复,组件之间交叉引用的断开链接以及耗时的组件生成,这些只是在低质量CAD软件中生成电气设计时发生的一些令人头疼的错误.这些花费大量时间修复的错误只是冰山一角.本文将深入探讨所有电气 ...

  8. 勒索文件恢复_我将如何从勒索软件中恢复

    勒索文件恢复 There are very few things that genuinely worry me in cybersecurity. Recovering from ransomwar ...

  9. cad沿线插入块 lisp_CAD制图软件中如何快速绘制推拉窗平面简图

    CAD建筑软件中为了方便绘图提供了强大的建筑门窗绘制功能.但是当电脑中没有CAD建筑软件的时候,怎么才能快速绘制出门窗或者简图呢?下面给大家分享一下CAD入门学习教程之在浩辰CAD中绘制推拉窗平面简图 ...

最新文章

  1. spring集成xmemcached
  2. icem密度盒怎么设置_icem一些总结精编版
  3. python一些小操作
  4. 解决android studio引用远程仓库下载慢(JCenter下载慢)
  5. 加装的硬盘进入后点不了文件夹_在外接移动硬盘上制作win to go教程
  6. js中数字直接点方法会报错,如1.toString()
  7. python时间格式化
  8. sql server 替换字符串中的某些字符
  9. js去掉前后空格的函数_Node.js十年,你大爷还是你大爷
  10. 人脑词典、亡者归来……来看库兹韦尔对于未来的四个疯狂预测
  11. 计算机毕业设计项目推荐 - 毕设开题选题
  12. refind引导的win10+ubuntu18.04开机启动
  13. 使用线程持续产生随机数
  14. 雍正王朝里康熙临终予四爷言
  15. Android使用第三方字体
  16. Latex完成入侵检测系统综述论文
  17. 2021-2022-1 ACM集训队每周程序设计竞赛(5) - 问题 C: 剪切 - 题解
  18. 各国际会议的影响因子
  19. Effective C++知识点
  20. 数学建模从入门到放弃

热门文章

  1. 电脑音频服务未运行怎么解决_【电脑技能】女生专属,学会这几招也可以修好你的电脑...
  2. 永恒python怎么用_毫无基础的人如何入门 Python ?Python入门教程拿走不谢啦!
  3. 仓库货位卡标识牌_仓库应如何规划?
  4. 火影忍者服务器维护时间,火影手游12月12日更新:仙鸣增加破霸体,小自来也变蛙时间减半!...
  5. python包管理工具ports_如何从自制程序,分发,macports,pip卸载所有软件包?
  6. [USACO13FEB]Tractor【二分 + BFS】
  7. docker︱在nvidia-docker中使用tensorflow-gpu/jupyter
  8. REVerb三元抽取工具
  9. python爬取公众号,用最简单的方式爬虫
  10. IDEACould not autowire. No beans of 'xxxMapper' type found.