【发布时间】:2020-01-13 14:25:29
【问题描述】:
所以基本上我在考虑一个撤消重做系统(我已经听过足够多的记忆模式和命令模式了,我只会 REEEEEEEEEEE),你可以在任何需要的类中创建这个 UndoRedo 类的对象一个 UR 系统,然后每个可以撤消的函数都将从生成一串代码开始,该代码将撤消操作(考虑到传递给函数的参数和任何其他相关信息之类的东西)并将其推送到URobject,它将适当地处理 2 个堆栈,并具有用于撤消和重做的功能,只需弹出代码并对其进行评估
然后我找到了this SO post,了解如何在 c# 中进行 Eval,但它没有用,因为它是沙盒的,我需要 Eval-ed 代码来与我的其余代码和其他东西进行通信。
然后,在@CodeCharmander 的建议和@Fixation 的澄清以及一些研究下,我设法让它发挥了作用!
对决赛课程感兴趣的人:
using System;
using System.Collections.Generic;
class UndoRedo
{
public Stack<Action> UndoStack { get; } = new Stack<Action>();
public Stack<Action> RedoStack { get; } = new Stack<Action>();
public Stack<Action> DoStack { get; } = new Stack<Action>();
public Stack<Action> BackupStack { get; } = new Stack<Action>();
public void Do(Action DoAct, Action UndoAct, bool Entry)
{
if ( Entry )
{
DoStack.Push( DoAct );
UndoStack.Push( UndoAct );
RedoStack.Clear();
BackupStack.Clear();
}
DoAct();
}
public void Undo()
{
var undoAct = UndoStack.Pop();
undoAct();
BackupStack.Push( undoAct );
RedoStack.Push( DoStack.Pop() );
}
public void Redo()
{
var redoAct = RedoStack.Pop();
redoAct();
DoStack.Push( redoAct );
UndoStack.Push( BackupStack.Pop() );
}
}
信息:
Do 函数接受 2 个 Lambda 表达式作为委托。 (感谢@CodeCharmander 的建议,@Fixation 的澄清,以及 Google 提醒我代表的工作方式)
() => { //Code here }
Entry 参数适用于 Undo 操作是调用任何其他可撤消方法的情况,通常应根据调用该其他可撤消方法的对象/类/方法进行设置;如果设置不正确,可能会导致撤消操作将所说的“撤消”添加为另一个操作、创建无限循环并在不应该时清除重做/备份堆栈的问题
【问题讨论】:
-
为什么不和代表一起做呢?
-
Wdym @CoderCharmander ?
标签: c# reflection eval undo-redo