添加命令结束和全部撤销

pull/7/head
ChenX 7 years ago
parent 533815c1be
commit 32f48dd8bb

@ -78,7 +78,26 @@ test('xxx', () =>
let file = db.FileWrite(); let file = db.FileWrite();
console.log(file.ToString()); console.log(file.ToString());
console.log(JSON.stringify(db.ObjectOut())); db.hm.StartCmd("");
(id1.Object as Line).StartPoint = new Vector3(100, 300, 400);
(id1.Object as Line).EndPoint = new Vector3(2000, 3000, 4000);
console.log((id1.Object as Line).StartPoint);
console.log((id1.Object as Line).EndPoint);
db.hm.Undo();
console.log((id1.Object as Line).StartPoint);
console.log((id1.Object as Line).EndPoint);
db.hm.Redo();
console.log((id1.Object as Line).StartPoint);
console.log((id1.Object as Line).EndPoint);
console.log(db.hm.historyRecord);
}); });

@ -1,5 +1,5 @@
import { ArrayRemove } from '../../src/Common/Utils'; import { ArrayRemove } from '../../src/Common/Utils';
import { Vector3 } from 'three'; import { Vector3, Line3 } from 'three';
/* /*
webCAD . webCAD .
,,. ,,.
@ -90,6 +90,17 @@ cmdName:"Ohther" //假设这个是一个复杂度很高的命令
] ]
A
2A,Aundo
A,P.
A,undo,redo.,redo.
C:
C,P.
A ,UNDO,redo,,redo
:id. :id.
,idid. ,idid.
ObjectId. ObjectId.
@ -123,20 +134,6 @@ export class CADFactory
if (createF) if (createF)
return createF(); return createF();
} }
static ReadObject(data: any, db: Database): CADObject
{
if (data.className)
{
let obj = this.CreateObject(data.className);
if (obj)
{
obj.SetDefaultDb(db);
obj.ObjectIn(data);
return obj
}
}
}
} }
//所有cad对象的基类 //所有cad对象的基类
@ -227,21 +224,32 @@ export class CADObject
file.Write(1); file.Write(1);
this.WriteObjectId(file) this.WriteObjectId(file)
} }
ObjectIn(obj: any) //局部撤销
ApplyPartialUndo(undoData: CADObject)
{ {
this.objectId = ObjectId.Create(this._db, obj.id); if (undoData instanceof AllObjectData)
{
this.ReadFile(undoData.file);
}
} }
ObjectOut(): Object
//撤销所保存的位置
UndoRecord(): CommandHistoryRecord
{ {
return { if (this._db)
className: this.ClassName, return this._db.hm.UndoData;
id: this.Id.Index
};
} }
//局部撤销
ApplyPartialUndo(file: CADObject) //写入所有的对象数据 以便还原对象
protected WriteAllObjectRecord()
{
let undoData = this.UndoRecord();
if (undoData)
{ {
undoData.WriteObjectHistoryPath(this, new ObjectAllDataHistoryRecord(this));
}
} }
//#endregion //#endregion
@ -393,13 +401,14 @@ export class CADFile
} }
} }
export class AppendData extends CADObject export class CreateObjectData extends CADObject
{ {
private cadFile: CADFile; private cadFile: CADFile;
constructor(obj: CADObject) constructor(obj?: CADObject)
{ {
super(); super();
this.cadFile = new CADFile(); this.cadFile = new CADFile();
if (obj)
this.cadFile.WriteObject(obj); this.cadFile.WriteObject(obj);
} }
@ -415,20 +424,27 @@ export class AppendData extends CADObject
//类名,保证序列化时得到正确的new //类名,保证序列化时得到正确的new
get ClassName(): string get ClassName(): string
{ {
return "AppendData"; return "CreateObjectData";
} }
//对象从文件中读取数据,初始化自身 //对象从文件中读取数据,初始化自身
ReadFile(file: CADFile) ReadFile(file: CADFile)
{ } {
file.Write(1);//ver
let data = file.Read();
this.cadFile.Data = data;
}
//对象将自身数据写入到文件. //对象将自身数据写入到文件.
WriteFile(file: CADFile) WriteFile(file: CADFile)
{ } {
file.Read();//ver;
file.Write(this.cadFile.Data);
}
//局部撤销 //局部撤销
ApplyPartialUndo(file: CADObject) ApplyPartialUndo(file: CADObject)
{ } { }
//#endregion -----------------------------File End----------------------------- //#endregion -----------------------------File End-----------------------------
} }
export class RemoveData extends CADObject export class RemoveObjectData extends CADObject
{ {
private index: number; private index: number;
constructor(index?: number) constructor(index?: number)
@ -450,16 +466,34 @@ export class RemoveData extends CADObject
} }
//对象从文件中读取数据,初始化自身 //对象从文件中读取数据,初始化自身
ReadFile(file: CADFile) ReadFile(file: CADFile)
{ } {
file.Read();//ver
this.index = file.Read();
}
//对象将自身数据写入到文件. //对象将自身数据写入到文件.
WriteFile(file: CADFile) WriteFile(file: CADFile)
{ } {
file.Write(1);
file.Write(this.index);
}
//局部撤销 //局部撤销
ApplyPartialUndo(file: CADObject) ApplyPartialUndo(file: CADObject)
{ } { }
//#endregion -----------------------------File End----------------------------- //#endregion -----------------------------File End-----------------------------
} }
export class AllObjectData extends CADObject
{
file: CADFile;
constructor(obj?: CADObject)
{
super();
this.file = new CADFile();
if (obj)
obj.WriteFile(this.file);
}
}
//对象集合. //对象集合.
export class ObjectCollection<T> extends CADObject export class ObjectCollection<T> extends CADObject
{ {
@ -475,13 +509,14 @@ export class ObjectCollection<T> extends CADObject
obj.InitObjectId(this._db); obj.InitObjectId(this._db);
} }
if (this._db && this._db.hm.UndoData) let undoRec = this.UndoRecord();
if (undoRec)
{ {
let hisRec = new HistoricRecord(); let hisRec = new HistorycRecord();
hisRec.redoData = new AppendData(obj); hisRec.redoData = new CreateObjectData(obj);
hisRec.undoData = new RemoveData(this.objectCol.length - 1); hisRec.undoData = new RemoveObjectData(this.objectCol.length - 1);
this._db.hm.UndoData.WriteObjectHistoryPath(this, hisRec); undoRec.WriteObjectHistoryPath(this, hisRec);
} }
return obj.Id; return obj.Id;
@ -490,13 +525,14 @@ export class ObjectCollection<T> extends CADObject
{ {
ArrayRemove(this.objectCol, obj); ArrayRemove(this.objectCol, obj);
obj.Erase(); obj.Erase();
if (this._db && this._db.hm.UndoData) let undoRec = this.UndoRecord();
if (undoRec)
{ {
let hisRec = new HistoricRecord(); let hisRec = new HistorycRecord();
hisRec.undoData = new AppendData(obj); hisRec.undoData = new CreateObjectData(obj);
hisRec.redoData = new RemoveData(this.objectCol.length - 1); hisRec.redoData = new RemoveObjectData(this.objectCol.length - 1);
this._db.hm.UndoData.WriteObjectHistoryPath(this, hisRec); undoRec.WriteObjectHistoryPath(this, hisRec);
} }
} }
Cout(): number Cout(): number
@ -504,12 +540,6 @@ export class ObjectCollection<T> extends CADObject
return this.objectCol.length; return this.objectCol.length;
} }
//迭代器
Entries()
{
return this.objectCol.entries;
}
//#region -----------------------------File----------------------------- //#region -----------------------------File-----------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化 //对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
//类名,保证序列化时得到正确的new //类名,保证序列化时得到正确的new
@ -539,28 +569,15 @@ export class ObjectCollection<T> extends CADObject
file.WriteObject(obj); file.WriteObject(obj);
} }
} }
ObjectIn(obj: any)
{
super.ObjectIn(obj);
let objList: Object[] = obj.objectCol;
this.objectCol = objList.map(o => CADFactory.ReadObject(o, this._db));
}
ObjectOut(): Object
{
let obj = super.ObjectOut() as any;
obj.objectCol = this.objectCol.map(o => o.ObjectOut());
return obj;
}
//局部撤销 //局部撤销
ApplyPartialUndo(undoData: CADObject) ApplyPartialUndo(undoData: CADObject)
{ {
if (undoData instanceof AppendData) if (undoData instanceof CreateObjectData)
{ {
let obj = undoData.getObject(this._db); let obj = undoData.getObject(this._db);
this.objectCol.push(obj); this.objectCol.push(obj);
} }
else if (undoData instanceof RemoveData) else if (undoData instanceof RemoveObjectData)
{ {
this.Remove(this.objectCol[undoData.Index]); this.Remove(this.objectCol[undoData.Index]);
} }
@ -579,9 +596,9 @@ export class CommandHistoryRecord extends CADObject
//命令名称 //命令名称
private commandName: string; private commandName: string;
//历史记录表 //历史记录表
private historyCol = new Map<ObjectId, HistoricRecord[]>(); private historyCol = new Map<ObjectId, HistorycRecord[]>();
get HistoryList(): Map<ObjectId, HistoricRecord[]> get HistoryList(): Map<ObjectId, HistorycRecord[]>
{ {
return this.historyCol; return this.historyCol;
} }
@ -594,20 +611,76 @@ export class CommandHistoryRecord extends CADObject
return this.historyCol.get(id); return this.historyCol.get(id);
} }
EndCommand()
{
for (let [id, recs] of this.historyCol)
{
let rec = this.GetObjectAllDataRecord(recs);
if (rec)
{
rec.WriteRedo();
}
}
}
//获得对象的记录
GetObjectAllDataRecord(historyList: HistorycRecord[]): ObjectAllDataHistoryRecord
{
if (historyList.length > 0)
{
let rec = historyList[historyList.length - 1];
if (rec instanceof ObjectAllDataHistoryRecord)
{
return rec;
}
}
}
//对象写入数据 //对象写入数据
WriteObjectHistoryPath(obj: CADObject, history: HistoricRecord) WriteObjectHistoryPath(obj: CADObject, history: HistorycRecord)
{
let his = this.GetObjectHistoryList(obj.Id);
if (this.GetObjectAllDataRecord(his))
{
console.log("优化掉重复的全部数据");
return;
}
if (history instanceof ObjectAllDataHistoryRecord)
{ {
this.GetObjectHistoryList(obj.Id).push(history); history.WriteUndo();
} }
his.push(history);
}
//#region -------------------------File-------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
//类名,保证序列化时得到正确的new
get ClassName(): string
{
return "CommandHistoryRecord";
}
//对象从文件中读取数据,初始化自身
ReadFile(file: CADFile)
{
let ver = file.Read();
}
//对象将自身数据写入到文件.
WriteFile(file: CADFile)
{
}
//#endregion
} }
/** /**
* ,. * ,.
* *
* @class HistoricRecord * @class HistoricRecord
* @extends {CADObject} * @extends {CADObject}
*/ */
export class HistoricRecord extends CADObject export class HistorycRecord extends CADObject
{ {
//指定撤销时所需要的数据 //指定撤销时所需要的数据
undoData: CADObject; undoData: CADObject;
@ -616,6 +689,29 @@ export class HistoricRecord extends CADObject
userData: CADObject; userData: CADObject;
} }
export class ObjectAllDataHistoryRecord extends HistorycRecord
{
obj: CADObject;
file: CADFile;
constructor(obj?: CADObject)
{
super();
this.obj = obj;
this.file = new CADFile();
}
//将数据写入 手动调用
WriteUndo()
{
this.undoData = new AllObjectData(this.obj);
}
WriteRedo()
{
this.redoData = new AllObjectData(this.obj);
}
}
//历史记录管理 //历史记录管理
export class HistoricManage extends CADObject export class HistoricManage extends CADObject
{ {
@ -627,29 +723,73 @@ export class HistoricManage extends CADObject
{ {
super(); super();
} }
get UndoData(): CommandHistoryRecord
//对象从文件中读取数据,初始化自身
ReadFile(file: CADFile)
{ {
if (this.doing) let ver = file.Read();
this.curIndex = file.Read();
this.historyRecord = [];
let cout = file.Read();
for (let i = 0; i < cout; i++)
{ {
return undefined; this.historyRecord.push(file.ReadObject(this._db) as CommandHistoryRecord);
}
} }
if (this.historyRecord.length === 0 || this.curIndex != this.historyRecord.length - 1) //对象将自身数据写入到文件.
WriteFile(file: CADFile)
{ {
this.StartCmd(""); file.Write(1);
file.Write(this.historyRecord.length);
for (let rec of this.historyRecord)
{
file.WriteObject(rec);
}
}
//命令正在当前状态
get IsNow(): boolean
{
return this.historyRecord.length !== 0 && this.curIndex === this.historyRecord.length - 1;
} }
get UndoData(): CommandHistoryRecord
{
if (this.doing)
return undefined;
if (!this.IsNow)
this.StartCmd("");
return this.historyRecord[this.historyRecord.length - 1]; return this.historyRecord[this.historyRecord.length - 1];
} }
StartCmd(cmdName: string) StartCmd(cmdName: string)
{ {
this.EndCmd();
//删除当前状态以后的所有状态 //删除当前状态以后的所有状态
this.historyRecord.splice(this.curIndex + 1, this.historyRecord.length - (this.curIndex + 1)); this.historyRecord.splice(this.curIndex + 1, this.historyRecord.length - (this.curIndex + 1));
this.historyRecord.push(new CommandHistoryRecord(cmdName)); this.historyRecord.push(new CommandHistoryRecord(cmdName));
this.curIndex = this.historyRecord.length - 1; this.curIndex = this.historyRecord.length - 1;
} }
//结束当前的命令.
EndCmd()
{
if (!this.IsNow)
return;
let lastRec = this.historyRecord[this.curIndex];
if (lastRec)
{
lastRec.EndCommand();
}
}
Undo(): boolean Undo(): boolean
{ {
this.EndCmd();
let historyRec = this.historyRecord[this.curIndex]; let historyRec = this.historyRecord[this.curIndex];
if (!historyRec) if (!historyRec)
{ {
@ -724,18 +864,6 @@ export class Database
file.ReadObject(this, this.ModelSpace); file.ReadObject(this, this.ModelSpace);
} }
ObjectIn(obj: any)
{
}
ObjectOut(): Object
{
return {
idCout: this.idCout,
ms: this.ModelSpace.ObjectOut(),
}
}
//创建一个id,自动递增它的索引号,并且会自动加入到db的id列表中. //创建一个id,自动递增它的索引号,并且会自动加入到db的id列表中.
AllocateId(obj: CADObject): ObjectId AllocateId(obj: CADObject): ObjectId
{ {
@ -747,10 +875,8 @@ export class Database
return id; return id;
} }
else else
{
console.warn("警告:对象不属于该数据库!"); console.warn("警告:对象不属于该数据库!");
} }
}
/* /*
private , ObjectId使. private , ObjectId使.
@ -770,9 +896,7 @@ export class Database
SetObjectId(index: number, id: ObjectId) SetObjectId(index: number, id: ObjectId)
{ {
if (this.idMap.has(index)) if (this.idMap.has(index))
{
console.warn("警告:尝试加入已经存在的id!"); console.warn("警告:尝试加入已经存在的id!");
}
this.idMap.set(index, id); this.idMap.set(index, id);
} }
} }
@ -802,9 +926,9 @@ export class BlockTableRecord extends ObjectCollection<Entity>
super.WriteFile(file); super.WriteFile(file);
} }
//局部撤销 //局部撤销
ApplyPartialUndo(file: CADObject) ApplyPartialUndo(undoData: CADObject)
{ {
super.ApplyPartialUndo(file); super.ApplyPartialUndo(undoData);
} }
//#endregion-----------------------------File End----------------------------- //#endregion-----------------------------File End-----------------------------
} }
@ -850,26 +974,16 @@ export class Line extends Entity
file.Write(this.startPoint.toArray()); file.Write(this.startPoint.toArray());
file.Write(this.endPoint.toArray()); file.Write(this.endPoint.toArray());
} }
ObjectIn(obj: any)
{
}
ObjectOut(): Object
{
let obj = super.ObjectOut() as any;
obj.sp = this.startPoint.toArray();
obj.ep = this.endPoint.toArray();
return obj
}
ApplyPartialUndo(data) ApplyPartialUndo(data)
{ {
super.ApplyPartialUndo(data);
} }
//-----------------------------File End----------------------------- //-----------------------------File End-----------------------------
set StartPoint(v: Vector3) set StartPoint(v: Vector3)
{ {
this.WriteAllObjectRecord();
this.startPoint.copy(v); this.startPoint.copy(v);
} }
get StartPoint(): Vector3 get StartPoint(): Vector3
@ -879,11 +993,12 @@ export class Line extends Entity
get EndPoint(): Vector3 get EndPoint(): Vector3
{ {
return this.endPoint; return this.endPoint.clone();
} }
set EndPoint(v: Vector3) set EndPoint(v: Vector3)
{ {
this.endPoint = v; this.WriteAllObjectRecord();
this.endPoint.copy(v);
} }
} }

Loading…
Cancel
Save