diff --git a/__test__/Geometry/EdgeGeometry.test.ts b/__test__/Geometry/EdgeGeometry.test.ts
index 51bec397b..3a69470ba 100644
--- a/__test__/Geometry/EdgeGeometry.test.ts
+++ b/__test__/Geometry/EdgeGeometry.test.ts
@@ -76,7 +76,7 @@ test('构建盖子失败2', () =>
{
//因为修改RegionParse精度降低到2个小数点就没问题了
let d =
- { "file": [1, "Board", 8, 2, 100, false, 1, 6, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 97.11678151856177, -50.86622139217798, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 97.11678151856177, -50.86622139217798, 0, 1], 0, 3, 633, 361.5, 18, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 4, [0, 0], 0, [361.5, 0], 0, [361.5, 633], 0, [0, 633], 0, true, 2, 3, 100, 10, 5, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 4, [0, 0], 0, [10, 0], 0, [10, 100], 0, [0, 100], 0, true, 0, 3, 0, 0, 0, 0, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 448.61678151856177, -63.86622139217798, 266.5, 1], 3, 100, 20, 2.001107831095416, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 4, [0, 0], 0, [20, 0], 0, [20, 100], 0, [0, 100], 0, true, 0, 3, 0, 0, 0, 0, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 438.61678151856177, -50.86622139217798, 266.49751214702076, 1], 3, 0, 0, 0, 0, 0, 9, 2, "左开门板", "主卧", "衣柜", "", "", "", 0, 0, "不排", 2, 0, "1.5", "1.5", "1.5", "1.5", "", "", "", 4, "不排", "不排", "不排", "不排", true, true, 0, 0, 0, 0, 0, 0, 0, 1, true], "basePt": { "x": 97.11678151856177, "y": -68.86622139217798, "z": 0; }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; };
+ { "file": [1, "Board", 8, 2, 100, false, 1, 6, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 97.11678151856177, -50.86622139217798, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 97.11678151856177, -50.86622139217798, 0, 1], 0, 3, 633, 361.5, 18, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 4, [0, 0], 0, [361.5, 0], 0, [361.5, 633], 0, [0, 633], 0, true, 2, 3, 100, 10, 5, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 4, [0, 0], 0, [10, 0], 0, [10, 100], 0, [0, 100], 0, true, 0, 3, 0, 0, 0, 0, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 448.61678151856177, -63.86622139217798, 266.5, 1], 3, 100, 20, 2.001107831095416, true, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 4, [0, 0], 0, [20, 0], 0, [20, 100], 0, [0, 100], 0, true, 0, 3, 0, 0, 0, 0, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 438.61678151856177, -50.86622139217798, 266.49751214702076, 1], 3, 0, 0, 0, 0, 0, 9, 2, "左开门板", "主卧", "衣柜", "", "", "", 0, 0, "不排", 2, 0, "1.5", "1.5", "1.5", "1.5", "", "", "", 4, "不排", "不排", "不排", "不排", true, true, 0, 0, 0, 0, 0, 0, 0, 1, true], "basePt": { "x": 97.11678151856177, "y": -68.86622139217798, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let brs = LoadBoardsFromFileData(d);
for (let br of brs)
diff --git a/src/Add-on/Save.ts b/src/Add-on/Save.ts
index 92abadee4..95194ea82 100644
--- a/src/Add-on/Save.ts
+++ b/src/Add-on/Save.ts
@@ -60,14 +60,25 @@ export class Save implements Command
}
let db = app.Database;
- let f = db.FileWrite();
- let vf = new CADFiler();
- app.Viewer.CameraCtrl.WriteFile(vf);
+ let f: CADFiler;
let isError = false;
if (userConfig.autoClearHistory)
{
+ //备份,清理
+ let hrBak = app.Database.hm.historyRecord;
+ let hrIndex = app.Database.hm.curIndex;
+ app.Database.hm.historyRecord = [];
+ app.Database.hm.curIndex = -1;
+
+ //拷贝db
+ f = db.FileWrite();
db = new Database().FileRead(f);
+
+ //还原
+ app.Database.hm.historyRecord = hrBak;
+ app.Database.hm.curIndex = hrIndex;
+
try
{
Purge(db);
@@ -89,7 +100,11 @@ export class Save implements Command
intent: Intent.SUCCESS,
});
}
+ else
+ f = db.FileWrite();
+ let vf = new CADFiler();
+ app.Viewer.CameraCtrl.WriteFile(vf);
f.Write(vf.Data);
f.Write(app.Editor.UCSMatrix.toArray());
@@ -214,7 +229,7 @@ function UploadFileHistory(file: any)
let userName = localStorage.getItem(StoreageKeys.UserName);
//记录历史记录
- let hisStart = app.Database.hm.curIndex - 3;//前十个
+ let hisStart = app.Database.hm.curIndex - 3 + 1;//前n条历史记录
let hisIndex = app.Database.hm.curIndex;
//修正当前开始位置
if (hisStart < 0)
@@ -222,7 +237,7 @@ function UploadFileHistory(file: any)
else
hisIndex -= hisStart;
- let hisEnd = Math.min(app.Database.hm.historyRecord.length, hisIndex + 3);//后10
+ let hisEnd = Math.min(app.Database.hm.historyRecord.length, app.Database.hm.curIndex + 3 + 1);//后n条历史记录
let hisf = new CADFiler();
//参考HistoryManager的序列化
diff --git a/src/Editor/AutoSave.ts b/src/Editor/AutoSave.ts
index 8ae470a19..4c8281e7b 100644
--- a/src/Editor/AutoSave.ts
+++ b/src/Editor/AutoSave.ts
@@ -1,18 +1,30 @@
+import { Purge } from "../Add-on/Purge";
import { app } from "../ApplicationServices/Application";
-import { Database } from "../DatabaseServices/Database";
-import { arrayRemoveIf } from "../Common/ArrayExt";
-import { IndexedDbStore, StoreName } from "../IndexedDb/IndexedDbStore";
import { Log } from "../Common/Log";
import { StoreageKeys } from "../Common/StoreageKeys";
-import { TopPanelStore } from "../UI/Store/TopPanelStore";
-import { userConfig } from "./UserConfig";
+import { CADFiler } from "../DatabaseServices/CADFiler";
+import { Database } from "../DatabaseServices/Database";
import { FileServer } from "../DatabaseServices/FileServer";
+import { IndexedDbStore, StoreName } from "../IndexedDb/IndexedDbStore";
+import { TopPanelStore } from "../UI/Store/TopPanelStore";
+import { CommandState } from "./CommandState";
import { TempEditor } from "./TempEditor";
+import { userConfig } from "./UserConfig";
+/**
+ * TENET(时间钳攻击)
+ * 这个类保证了在某个时间周期内的操作被保存,通过2个机制来确定生效.
+ * 1.周期调用.若有未保存的,则保存它,并且重置计时器.(常规操作)
+ * 2.命令结束后调用.若超过时间周期,则保存它,并且重置计时器.(容错操作,避免在周期后产生的记录需要到下个周期才能保存)
+ *
+ * 保证了:
+ * 在命令结束后才运行(避免在命令状态下保存导致的错误)
+ */
export class AutoSaveServer
{
//缓存过了
isCached = false;
+ private lastTime = 0;
private timeId: NodeJS.Timeout;
constructor()
{
@@ -22,31 +34,13 @@ export class AutoSaveServer
this.isCached = false;
});
}
+
Start()
{
this.Stop();
- const topStore = TopPanelStore.GetInstance() as TopPanelStore;
- this.timeId = setInterval(async () =>
- {
- if (app.Saved || !topStore.editoring || this.isCached || TempEditor.EditorIng) return;
-
- let f = app.Database.FileWrite();
- if (false)
- {
- let newDB = new Database().FileRead(f);
- newDB.hm.Clear();
- arrayRemoveIf(newDB.ModelSpace.Entitys, e => e.IsErase);
- arrayRemoveIf(newDB.TemplateTable.Objects, e => e.IsErase);
- arrayRemoveIf(newDB.GroupTable.Objects, g =>
- {
- return g.Entitys.length === 0 || g.Entitys.every(e => !e || e.IsErase);
- });
- f = newDB.FileWrite();
- }
- //异步不等待
- this.SavaData(f.Data);
- }, userConfig.autoSaveConfig.time * 60 * 1000);
+ this.timeId = setInterval(() => this.Do(), userConfig.autoSaveConfig.time * 60 * 1000);
}
+
Stop()
{
if (this.timeId)
@@ -55,6 +49,46 @@ export class AutoSaveServer
this.timeId = null;
}
}
+
+ Do()
+ {
+ let now = Date.now();
+ if (userConfig.autoSaveConfig.enable
+ && now - this.lastTime > userConfig.autoSaveConfig.time * 60 * 1000)
+ {
+ this.SaveFile();
+ this.lastTime = now;
+ }
+ }
+
+ private SaveFile()
+ {
+ const topStore = TopPanelStore.GetInstance() as TopPanelStore;
+ if (app.Saved || this.isCached)
+ {
+ // console.log("文件已经被保存,不需要自动保存!");
+ return;
+ }
+
+ if (!topStore.editoring || TempEditor.EditorIng || CommandState.CommandIng)
+ {
+ console.log("文件正在编辑中稍后重试!");
+ // setTimeout(() => this.SaveFile(), 1000);//
+ return;
+ };
+
+ let f = AppDbWriteToFile();
+
+ if (false)
+ {
+ let newDB = new Database().FileRead(f);
+ Purge(newDB);
+ f = newDB.FileWrite();
+ }
+ //异步不等待
+ this.SavaData(f.Data);
+ }
+
async SavaData(data: any[])
{
const indexDbStore = await IndexedDbStore.CADStore();
@@ -63,13 +97,47 @@ export class AutoSaveServer
if (uid)
{
indexDbStore.Put(StoreName.FileCache, uid, { time: new Date().toLocaleString(), data, fid: server.m_CurFileId });
- Log("文件缓存成功!");
+ Log("文件自动备份成功!");
}
this.isCached = true;
}
- async Clear()
+
+ public async Clear()
{
const store = await IndexedDbStore.CADStore();
store.Delete(StoreName.FileCache, localStorage.getItem(StoreageKeys.Uid));
}
}
+
+/**
+ * 当前图纸写入到文件中,并且只保存一些命令历史记录
+ * @returns
+ */
+function AppDbWriteToFile(): CADFiler
+{
+ const SaveRecordCount = 3; //前N条和后N条历史记录
+ let hisStart = app.Database.hm.curIndex - SaveRecordCount + 1; //前n条历史记录
+ let hisIndex = app.Database.hm.curIndex;
+ //修正当前开始位置
+ if (hisStart < 0)
+ hisStart = 0;
+
+ else
+ hisIndex -= hisStart;
+
+ //结束为止
+ let hisEnd = Math.min(app.Database.hm.historyRecord.length, app.Database.hm.curIndex + SaveRecordCount + 1); //后n条历史记录
+
+ //备份,清理
+ let hrBak = app.Database.hm.historyRecord;
+ let hrIndex = app.Database.hm.curIndex;
+
+ app.Database.hm.curIndex = hisIndex;
+ app.Database.hm.historyRecord = hrBak.slice(hisStart, hisEnd);
+
+ let f = app.Database.FileWrite();
+
+ app.Database.hm.historyRecord = hrBak;
+ app.Database.hm.curIndex = hrIndex;
+ return f;
+}
diff --git a/src/Editor/CommandMachine.ts b/src/Editor/CommandMachine.ts
index 732f166b0..74d91b68b 100644
--- a/src/Editor/CommandMachine.ts
+++ b/src/Editor/CommandMachine.ts
@@ -157,6 +157,8 @@ class CommandMachine
app.Database.hm.Undo();
}
+ app.AutoSaveServer.Do();//触发自动保存,在这里触发自动保存,保证历史记录已经被写入(是完整的)
+
app.Viewer.GripScene.visible = true;
app.Viewer.GripScene.UpdateAll();
app.Editor.UpdateScreen();
diff --git a/src/UI/Components/Modal/OptionModal/SystemConfig.tsx b/src/UI/Components/Modal/OptionModal/SystemConfig.tsx
index a19bc9b1f..a61a1141f 100644
--- a/src/UI/Components/Modal/OptionModal/SystemConfig.tsx
+++ b/src/UI/Components/Modal/OptionModal/SystemConfig.tsx
@@ -94,7 +94,7 @@ export class SystemConfigPanel extends React.Component
uiOption={this.saveUiData}
type={CheckObjectType.GT0Num}
/>
- mins
+ 分钟