|
|
@ -96,6 +96,9 @@ cmdName:"Ohther" //假设这个是一个复杂度很高的命令
|
|
|
|
加入ObjectId类.
|
|
|
|
加入ObjectId类.
|
|
|
|
id只有在一个情况下才会更新.跨文档复制时.
|
|
|
|
id只有在一个情况下才会更新.跨文档复制时.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
问题:对象的id如何分配.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -106,13 +109,14 @@ id只有在一个情况下才会更新.跨文档复制时.
|
|
|
|
class CADFactory
|
|
|
|
class CADFactory
|
|
|
|
{
|
|
|
|
{
|
|
|
|
private constructor() { }
|
|
|
|
private constructor() { }
|
|
|
|
private objectNameMap = new Map<string, any>();
|
|
|
|
private objectNameMap = new Map<string, () => CADObject>();
|
|
|
|
private static factory = new CADFactory();
|
|
|
|
private static factory = new CADFactory();
|
|
|
|
static RegisterObject(C)
|
|
|
|
static RegisterObject(C)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let obj = new C();
|
|
|
|
let obj = new C() as CADObject;
|
|
|
|
this.factory.objectNameMap.set(obj.ClassName.toUpperCase(), () => new C());
|
|
|
|
this.factory.objectNameMap.set(obj.ClassName.toUpperCase(), () => new C());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static CreateObject(name: string): CADObject
|
|
|
|
static CreateObject(name: string): CADObject
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let createF = this.factory.objectNameMap.get(name.toUpperCase());
|
|
|
|
let createF = this.factory.objectNameMap.get(name.toUpperCase());
|
|
|
@ -126,21 +130,44 @@ class CADFactory
|
|
|
|
class CADObject
|
|
|
|
class CADObject
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//#region -------------------------DB-------------------------
|
|
|
|
protected db: Database;
|
|
|
|
protected db: Database;
|
|
|
|
//对象是否已经被删除
|
|
|
|
get Db(): Database
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return this.db;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
SetDb(db: Database)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!this.db)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
this.db = db;
|
|
|
|
|
|
|
|
this.objectId = db.AllocateId(this);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
console.warn("同一个对象无法重复设置到数据库中!");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//#region -------------------------isErase-------------------------
|
|
|
|
protected isErase: boolean = false;
|
|
|
|
protected isErase: boolean = false;
|
|
|
|
|
|
|
|
get IsErase(): boolean
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return this.isErase;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//#region -------------------------id-------------------------
|
|
|
|
protected objectId: ObjectId;
|
|
|
|
protected objectId: ObjectId;
|
|
|
|
|
|
|
|
|
|
|
|
get Id(): ObjectId
|
|
|
|
get Id(): ObjectId
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return this.objectId;
|
|
|
|
return this.objectId;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
get IsErase(): boolean
|
|
|
|
//#endregion
|
|
|
|
{
|
|
|
|
|
|
|
|
return this.isErase;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------File-----------------------------
|
|
|
|
//#region -------------------------File-------------------------
|
|
|
|
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
|
|
|
|
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
|
|
|
|
|
|
|
|
|
|
|
|
//类名,保证序列化时得到正确的new
|
|
|
|
//类名,保证序列化时得到正确的new
|
|
|
@ -161,14 +188,23 @@ class CADObject
|
|
|
|
ApplyPartialUndo(file: CADFile)
|
|
|
|
ApplyPartialUndo(file: CADFile)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//#endregion
|
|
|
|
//-----------------------------File End-----------------------------
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class ObjectId
|
|
|
|
class ObjectId
|
|
|
|
{
|
|
|
|
{
|
|
|
|
private id: number;
|
|
|
|
private id: number;
|
|
|
|
private constructor() { }
|
|
|
|
private obj: CADObject;
|
|
|
|
|
|
|
|
constructor(id: number, obj: CADObject)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
this.id = id;
|
|
|
|
|
|
|
|
this.obj = obj;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get Object(): CADObject
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return this.obj;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//cad文件数据
|
|
|
|
//cad文件数据
|
|
|
@ -177,12 +213,36 @@ class CADFile
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//命令历史记录集合
|
|
|
|
//命令历史记录集合
|
|
|
|
class CommandHistoricRecord extends CADObject
|
|
|
|
class CommandHistoryRecord extends CADObject
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
constructor(cmdName: string)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
super();
|
|
|
|
|
|
|
|
this.commandName = cmdName;
|
|
|
|
|
|
|
|
}
|
|
|
|
//命令名称
|
|
|
|
//命令名称
|
|
|
|
commandName: string;
|
|
|
|
private commandName: string;
|
|
|
|
//历史记录表
|
|
|
|
//历史记录表
|
|
|
|
historicCol: Map<number, HistoricRecord[]>;
|
|
|
|
private historyCol = new Map<ObjectId, HistoricRecord[]>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get HistoryList(): Map<ObjectId, HistoricRecord[]>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return this.historyCol;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private GetObjectHistoryList(id: ObjectId)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!this.historyCol.has(id))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
this.historyCol.set(id, []);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.historyCol.get(id);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//对象写入数据
|
|
|
|
|
|
|
|
WriteObjectHistoryPath(obj: CADObject, history: HistoricRecord)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
this.GetObjectHistoryList(obj.Id).push(history);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//历史记录
|
|
|
|
//历史记录
|
|
|
@ -198,40 +258,40 @@ class HistoricRecord extends CADObject
|
|
|
|
class HistoricManage extends CADObject
|
|
|
|
class HistoricManage extends CADObject
|
|
|
|
{
|
|
|
|
{
|
|
|
|
private curIndex: number = -1; //当前执行位置
|
|
|
|
private curIndex: number = -1; //当前执行位置
|
|
|
|
private historicRecord: CommandHistoricRecord[] = [];//历史记录
|
|
|
|
private historyRecord: CommandHistoryRecord[] = []; //历史记录
|
|
|
|
|
|
|
|
|
|
|
|
constructor(db: Database)
|
|
|
|
constructor(db: Database)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
super();
|
|
|
|
this.db = db;
|
|
|
|
this.db = db;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
get UndoData(): CommandHistoricRecord
|
|
|
|
get UndoData(): CommandHistoryRecord
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (this.historicRecord.length === 0)
|
|
|
|
if (this.historyRecord.length === 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
this.StartCmd("");
|
|
|
|
this.StartCmd("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this.historicRecord[this.historicRecord.length - 1];
|
|
|
|
return this.historyRecord[this.historyRecord.length - 1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
StartCmd(cmdName: string)
|
|
|
|
StartCmd(cmdName: string)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
this.historicRecord.splice(this.curIndex, this.historicRecord.length - this.curIndex);
|
|
|
|
this.historyRecord.splice(this.curIndex, this.historyRecord.length - this.curIndex);
|
|
|
|
this.historicRecord.push(new CommandHistoricRecord());
|
|
|
|
this.historyRecord.push(new CommandHistoryRecord(cmdName));
|
|
|
|
this.curIndex = this.historicRecord.length - 1;
|
|
|
|
this.curIndex = this.historyRecord.length - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Undo(): boolean
|
|
|
|
Undo(): boolean
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let historicRec = this.historicRecord[this.curIndex];
|
|
|
|
let historyRec = this.historyRecord[this.curIndex];
|
|
|
|
if (!historicRec)
|
|
|
|
if (!historyRec)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (let [id, recList] of historicRec.historicCol)
|
|
|
|
for (let [id, recList] of historyRec.HistoryList)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let obj = this.db.getObject(id);
|
|
|
|
let obj = id.Object;
|
|
|
|
for (let rec of recList)
|
|
|
|
for (let rec of recList)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
obj.ApplyPartialUndo(rec.undoData);
|
|
|
|
obj.ApplyPartialUndo(rec.undoData);
|
|
|
@ -243,14 +303,14 @@ class HistoricManage extends CADObject
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Redo()
|
|
|
|
Redo()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let historicRec = this.historicRecord[this.curIndex + 1];
|
|
|
|
let historyRec = this.historyRecord[this.curIndex + 1];
|
|
|
|
if (!historicRec)
|
|
|
|
if (!historyRec)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (let [id, recList] of historicRec.historicCol)
|
|
|
|
for (let [id, recList] of historyRec.HistoryList)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let obj = this.db.getObject(id);
|
|
|
|
let obj = id.Object;
|
|
|
|
for (let i = recList.length; i--;)
|
|
|
|
for (let i = recList.length; i--;)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
obj.ApplyPartialUndo(recList[i].redoData);
|
|
|
|
obj.ApplyPartialUndo(recList[i].redoData);
|
|
|
@ -265,16 +325,23 @@ class HistoricManage extends CADObject
|
|
|
|
|
|
|
|
|
|
|
|
class Database
|
|
|
|
class Database
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
hm: HistoricManage;
|
|
|
|
hm: HistoricManage;
|
|
|
|
//块表记录
|
|
|
|
//块表记录
|
|
|
|
blockTableCol: BlockTableRecord[];
|
|
|
|
blockTableCol: BlockTableRecord[];
|
|
|
|
//模型空间
|
|
|
|
//模型空间
|
|
|
|
ModelSpace: BlockTableRecord = new BlockTableRecord();
|
|
|
|
ModelSpace: BlockTableRecord;
|
|
|
|
//材质字典...
|
|
|
|
//材质字典...
|
|
|
|
|
|
|
|
|
|
|
|
objectCol = new Map<number, CADObject>();
|
|
|
|
objectCol = new Map<number, CADObject>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private idCout = -1;
|
|
|
|
|
|
|
|
private idMap = new Map<number, ObjectId>();
|
|
|
|
|
|
|
|
|
|
|
|
constructor()
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
this.ModelSpace = new BlockTableRecord(this);
|
|
|
|
this.hm = new HistoricManage(this);
|
|
|
|
this.hm = new HistoricManage(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -300,12 +367,72 @@ class Database
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//在对象池中创建id.
|
|
|
|
|
|
|
|
AllocateId(obj: CADObject): ObjectId
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (obj.Db === this)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
this.idCout++;
|
|
|
|
|
|
|
|
let id = new ObjectId(this.idCout, obj);
|
|
|
|
|
|
|
|
this.idMap.set(this.idCout, id);
|
|
|
|
|
|
|
|
return id;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
console.warn("对象不属于该数据库!");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//获得指定索引的id
|
|
|
|
|
|
|
|
GetId(index: number)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return this.idMap.get(index);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class BlockTableRecord extends CADObject
|
|
|
|
class BlockTableRecord extends CADObject
|
|
|
|
{
|
|
|
|
{
|
|
|
|
private objectMap = new Map<number, CADObject>();
|
|
|
|
private objectCol: CADObject[] = [];
|
|
|
|
|
|
|
|
constructor(db: Database)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
super();
|
|
|
|
|
|
|
|
this.SetDb(db);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//#region -----------------------------File-----------------------------
|
|
|
|
|
|
|
|
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
|
|
|
|
|
|
|
|
//类名,保证序列化时得到正确的new
|
|
|
|
|
|
|
|
get ClassName(): string
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return "BlockTableRecord";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//对象从文件中读取数据,初始化自身
|
|
|
|
|
|
|
|
FileIn(file: CADFile)
|
|
|
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
//对象将自身数据写入到文件.
|
|
|
|
|
|
|
|
FileOut(file: CADFile)
|
|
|
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
//局部撤销
|
|
|
|
|
|
|
|
ApplyPartialUndo(file: CADFile)
|
|
|
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
//#endregion-----------------------------File End-----------------------------
|
|
|
|
|
|
|
|
AppendEntity(ent: Entity): ObjectId
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (ent.Db)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
console.warn("同一个对象无法重复加入图纸中!");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ent.SetDb(this.Db);
|
|
|
|
|
|
|
|
this.objectCol.push(ent);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let historyData = new HistoricRecord();
|
|
|
|
|
|
|
|
// historyData.undoData
|
|
|
|
|
|
|
|
this.db.hm.UndoData.WriteObjectHistoryPath(this, historyData);
|
|
|
|
|
|
|
|
return ent.Id;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
enum EntityUndoType
|
|
|
|
enum EntityUndoType
|
|
|
@ -317,14 +444,8 @@ enum EntityUndoType
|
|
|
|
//所有图元的基类
|
|
|
|
//所有图元的基类
|
|
|
|
class Entity extends CADObject
|
|
|
|
class Entity extends CADObject
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_Db: Database;
|
|
|
|
|
|
|
|
constructor()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
super();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//直线撤销类型
|
|
|
|
//直线撤销类型
|
|
|
|
export enum LineUndoType
|
|
|
|
export enum LineUndoType
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -375,12 +496,15 @@ class Line extends Entity
|
|
|
|
|
|
|
|
|
|
|
|
CADFactory.RegisterObject(Line);
|
|
|
|
CADFactory.RegisterObject(Line);
|
|
|
|
|
|
|
|
|
|
|
|
let l = CADFactory.CreateObject("Line");
|
|
|
|
let l = CADFactory.CreateObject("Line") as Entity;
|
|
|
|
console.log(l);
|
|
|
|
console.log(l);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let db = new Database();
|
|
|
|
let db = new Database();
|
|
|
|
|
|
|
|
let id = db.ModelSpace.AppendEntity(l);
|
|
|
|
|
|
|
|
db.GetId(0).Object.ClassName /*?*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log(id);
|
|
|
|
|
|
|
|
|
|
|
|
console.log(db.hm.Undo());
|
|
|
|
db.hm.Undo();/*?*/
|
|
|
|
|
|
|
|
|
|
|
|
db.hm.Redo();
|
|
|
|
db.hm.Redo();/*?*/
|