前言
这是一个基于原生JavaScript
+Three.js的系统, 我需要在里面增加撤销恢复的功能, 这并非针对一个功能, 而是各种操作.
主要记录思路.
一、初期设想
栈似乎很合适, 用栈存储状态.
最近的一次操作入栈存在于栈顶, 而撤销操作只需要对栈顶的状态进行操作, 这遵循栈的后进先出原则(LIFO).
然后再设置一系列方法去操作栈, 增加一点安全性.
首先是各种功能应该在什么地方发起出入栈操作, 这里有一大堆js文件.
其次对于不同的功能需要收集什么参数来组织状态入栈.
不同的功能出栈应该分别进行什么操作, 回撤出栈肯定要调这堆文件里的方法来把老状态填回去.
二、如何收集状态
先写个demo,我建了一个数组栈放在class Manager
, 设置了入栈方法push
, 出栈方法pop
以及查看栈顶的peek
方法.
class Manager {
constructor() {
this.stats= [];
}
push(action) {
this.stats.push(action);
}
pop() {
const nowAction = this.doActions.pop();
}
peek(which) {
return this.doActions[this.doCount];
}
}
export {
Manager }
收集状态就不得不去满地的找了, 操作都写好了, 还是不要乱动.
除非单独写一套独立的逻辑, 执行系统的同时也执行我自己的, 但这基本是要重写一套系统了(
1.通信尝试
但还是要想办法把各处的数据都划拉到Manager
里.
呃, 老实说我并没有什么原生开发的经验, 我在多个文件里引入了Manager
类并且期望着这些文件可以基于Manager
建立联络实现数据共享, 比如在a.js和b.js内:
只是举个例子, 不要用一个字母去命名文件.
// a.js
import {
manager } from "./backup/manager.js";
const manager = new Manager();
const action = {
name: 'saveWorldList',
params: {
target: '108',
value: [
world: {
psr: {
},
annotation: {
}
}
]
}
}
for (let i = 0; i < 3; i++) {
manager.push(action);
}
// b.js
import {
manager } from "./backup/manager.js";
const manager = new Manager();
const undoAction = manager.pop();
console.log(undoAction);
然而这样做并不能实现数据共享, 每一个刚刚实例化出来的对象都是崭新的.
const manager = new Manager();
只是使用原始干净的class Manger
实例化了一个仅存在于这个模块里的对象manager
.
2.如何通信
如果将一个对象放在公用的模块里, 从各个文件触发去操作这一个对象呢…公用模块里的数据总不至于对来自不同方向的访问做出不同的回应吧?
class