更新数据持久化设计

pull/7/head
cx 7 years ago
parent fdf14278c5
commit 980b5529fb

@ -1,5 +1,6 @@
import { ArrayRemove } from '../../src/Common/Utils';
import { Vector3 } from 'three';
/*
webCAD .
,,.
@ -96,12 +97,13 @@ cmdName:"Ohther" //假设这个是一个复杂度很高的命令
id..
:id.
,id.
*/
,,.
,,.
*/
//CAD对象工厂,通过注册 和暴露的创建方法,动态创建对象
@ -130,16 +132,16 @@ class CADObject
{
//#region -------------------------DB-------------------------
protected db: Database;
protected _db: Database;
get Db(): Database
{
return this.db;
return this._db;
}
SetDb(db: Database)
{
if (!this.db)
if (!this._db)
{
this.db = db;
this._db = db;
this.objectId = db.AllocateId(this);
}
else
@ -150,14 +152,14 @@ class CADObject
//#endregion
//#region -------------------------isErase-------------------------
protected isErase: boolean = false;
protected _isErase: boolean = false;
get IsErase(): boolean
{
return this.isErase;
return this._isErase;
}
Erase(isErase: boolean = true)
{
this.isErase = isErase;
this._isErase = isErase;
}
//#endregion
@ -182,49 +184,153 @@ class CADObject
//对象从文件中读取数据,初始化自身
FileIn(file: CADFile)
{
//write Id;
this.objectId = this.ReadObjectId(file);
if (this.objectId)
{
this.objectId.Object = this;
}
}
//对象将自身数据写入到文件.
FileOut(file: CADFile)
{
this.WriteObjectId(file)
}
//局部撤销
ApplyPartialUndo(file: CADFile)
ApplyPartialUndo(file: CADObject)
{
}
//#endregion
private WriteObjectId(file: CADFile)
{
if (this.objectId)
{
file.Write(this.objectId.Index);
}
else
file.Write(-1);
}
private ReadObjectId(file: CADFile): ObjectId
{
let index = file.Read();
if (index >= 0 && this._db)
{
return this._db.GetObjectId(index);
}
}
}
/*
CADObjectId,.
id,.
ObjectId使 Database(dbid,便id)
*/
class ObjectId
{
private id: number;
private obj: CADObject;
constructor(id: number, obj: CADObject)
private constructor()
{
this.id = id;
this.obj = obj;
this.id = -1;
}
static Create(db: Database, index: number): ObjectId
{
let id = db.GetObjectId(index);
if (!id)
{
id = new ObjectId();
id.id = index;
}
return id;
}
set Object(v: CADObject)
{
this.obj = v;
}
get Object(): CADObject
{
return this.obj;
}
get Index(): number
{
return this.id;
}
}
//cad文件数据
class CADFile
{
private readIndex: number = 0;
private dataList: any[] = [];
WriteString(str: string)
{
this.dataList.push(str);
}
ReadString(): string
{
let str = this.dataList[this.readIndex] as string;
this.readIndex++;
return str;
}
WriteObject(obj: CADObject)
{
this.WriteString(obj.ClassName);
obj.FileOut(this);
}
ReadObject(db: Database): CADObject
{
let className = this.ReadString();
let obj = CADFactory.CreateObject(className);
obj.SetDb(db);
obj.FileIn(this);
return obj;
}
Write(data: any)
{
this.dataList.push(data);
}
Read(): any
{
let data = this.dataList[this.readIndex];
this.readIndex++;
return data;
}
}
class AppendData extends CADObject
{
objData: CADFile;
private object: CADObject;
private cadFile: CADFile;
constructor(obj: CADObject)
{
super();
this.cadFile = new CADFile();
this.cadFile.WriteObject(obj);
}
getObject(db: Database): CADObject
{
if (!this.object)
{
this.object = this.cadFile.ReadObject(db);
}
return this.object;
}
//#region -----------------------------File-----------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
//类名,保证序列化时得到正确的new
get ClassName(): string
{
return "CADObject";
return "AppendData";
}
//对象从文件中读取数据,初始化自身
FileIn(file: CADFile)
@ -233,20 +339,29 @@ class AppendData extends CADObject
FileOut(file: CADFile)
{ }
//局部撤销
ApplyPartialUndo(file: CADFile)
ApplyPartialUndo(file: CADObject)
{ }
//#endregion -----------------------------File End-----------------------------
}
class RemoveData extends CADObject
{
index: number;
private index: number;
constructor(index: number)
{
super();
this.index = index;
}
get Index()
{
return this.index;
}
//#region -----------------------------File-----------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
//类名,保证序列化时得到正确的new
get ClassName(): string
{
return "CADObject";
return "RemoveData";
}
//对象从文件中读取数据,初始化自身
FileIn(file: CADFile)
@ -255,7 +370,7 @@ class RemoveData extends CADObject
FileOut(file: CADFile)
{ }
//局部撤销
ApplyPartialUndo(file: CADFile)
ApplyPartialUndo(file: CADObject)
{ }
//#endregion -----------------------------File End-----------------------------
}
@ -268,23 +383,31 @@ class ObjectCollection<T> extends CADObject
{
this.objectCol.push(obj);
let hisRec = new HistoricRecord();
let redo = new AppendData();
redo.objData = new CADFile();
obj.FileOut(redo.objData);
hisRec.redoData = redo;
let undo = new RemoveData();
undo.index = this.objectCol.length - 1;
hisRec.undoData = undo;
if (this._db && this._db.hm.UndoData)
{
let hisRec = new HistoricRecord();
hisRec.redoData = new AppendData(obj);
hisRec.undoData = new RemoveData(this.objectCol.length - 1);
this.db.hm.UndoData.WriteObjectHistoryPath(this, hisRec);
this._db.hm.UndoData.WriteObjectHistoryPath(this, hisRec);
}
}
Remove(obj: CADObject)
{
ArrayRemove(this.objectCol, obj);
if (this._db && this._db.hm.UndoData)
{
let hisRec = new HistoricRecord();
hisRec.undoData = new AppendData(obj);
hisRec.redoData = new RemoveData(this.objectCol.length - 1);
this.db.hm.UndoData.WriteObjectHistoryPath(this, undefined);
this._db.hm.UndoData.WriteObjectHistoryPath(this, hisRec);
}
}
Cout(): number
{
return this.objectCol.length;
}
//#region -----------------------------File-----------------------------
@ -301,17 +424,15 @@ class ObjectCollection<T> extends CADObject
FileOut(file: CADFile)
{ }
//局部撤销
ApplyPartialUndo(file: CADObject)
ApplyPartialUndo(undoData: CADObject)
{
if (file instanceof AppendData)
if (undoData instanceof AppendData)
{
file.objData//cad file.
//create object
//append object
let obj = undoData.getObject(this._db);
}
else if (file instanceof RemoveData)
else if (undoData instanceof RemoveData)
{
//remove object
this.Remove(this.objectCol[undoData.Index]);
}
}
//#endregion -----------------------------File End-----------------------------
@ -363,14 +484,19 @@ class HistoricManage extends CADObject
{
private curIndex: number = -1; //当前执行位置
private historyRecord: CommandHistoryRecord[] = []; //历史记录
private doing: boolean = false;
constructor(db: Database)
{
super();
this.db = db;
this._db = db;
}
get UndoData(): CommandHistoryRecord
{
if (this.doing)
{
return undefined;
}
if (this.historyRecord.length === 0)
{
this.StartCmd("");
@ -392,7 +518,7 @@ class HistoricManage extends CADObject
{
return false;
}
this.doing = true;
for (let [id, recList] of historyRec.HistoryList)
{
let obj = id.Object;
@ -402,7 +528,7 @@ class HistoricManage extends CADObject
}
}
this.curIndex--;
this.doing = false;
return true;
}
Redo()
@ -412,6 +538,7 @@ class HistoricManage extends CADObject
{
return false;
}
this.doing = true;
for (let [id, recList] of historyRec.HistoryList)
{
let obj = id.Object;
@ -421,7 +548,7 @@ class HistoricManage extends CADObject
}
}
this.curIndex++;
this.doing = false;
return true;
}
}
@ -478,7 +605,7 @@ class Database
if (obj.Db === this)
{
this.idCout++;
let id = new ObjectId(this.idCout, obj);
let id = ObjectId.Create(this, this.idCout);
this.idMap.set(this.idCout, id);
return id;
}
@ -487,18 +614,15 @@ class Database
console.warn("对象不属于该数据库!");
}
}
//获得指定索引的id
GetId(index: number)
GetObjectId(index: number): ObjectId
{
return this.idMap.get(index);
}
}
class BlockTableRecord extends CADObject
class BlockTableRecord extends ObjectCollection<Entity>
{
private objectCol: CADObject[] = [];
constructor(db: Database)
{
super();
@ -519,8 +643,10 @@ class BlockTableRecord extends CADObject
FileOut(file: CADFile)
{ }
//局部撤销
ApplyPartialUndo(file: CADFile)
{ }
ApplyPartialUndo(file: CADObject)
{
super.ApplyPartialUndo(file);
}
//#endregion-----------------------------File End-----------------------------
AppendEntity(ent: Entity): ObjectId
{
@ -530,28 +656,19 @@ class BlockTableRecord extends CADObject
return;
}
ent.SetDb(this.Db);
this.objectCol.push(ent);
let historyData = new HistoricRecord();
// historyData.undoData
this.db.hm.UndoData.WriteObjectHistoryPath(this, historyData);
this.Append(ent);
return ent.Id;
}
}
enum EntityUndoType
{
}
//所有图元的基类
class Entity extends CADObject
{
}
//直线撤销类型
export enum LineUndoType
export enum LineUndoType
{
Full = 0,
StartPoint = 1,
@ -561,9 +678,11 @@ export enum LineUndoType
//直线对象
class Line extends Entity
{
private startPoint: Vector3;
constructor()
{
super();
this.startPoint = new Vector3(0, 0, 0);
}
//-----------------------------File-----------------------------
@ -578,10 +697,14 @@ class Line extends Entity
//对象从文件中读取数据,初始化自身
FileIn(file: CADFile)
{
super.FileIn(file);
this.startPoint.fromArray(file.Read());
}
//对象将自身数据写入到文件.
FileOut(file: CADFile)
{
super.FileOut(file);
file.Write(this.startPoint.toArray());
}
ApplyPartialUndo(data)
{
@ -596,19 +719,54 @@ class Line extends Entity
}
}
//-----------------------------File End-----------------------------
set StartPoint(v: Vector3)
{
this.startPoint.copy(v);
}
get StartPoint(): Vector3
{
return this.startPoint.clone();
}
}
CADFactory.RegisterObject(Line);
let l = CADFactory.CreateObject("Line") as Entity;
let db = new Database();
let l = CADFactory.CreateObject("Line") as Line;
console.log(l);
let db = new Database();
l.StartPoint = new Vector3(0, 1, 0);
let id = db.ModelSpace.AppendEntity(l);
db.GetId(0).Object.ClassName /*?*/
db.GetObjectId(0).Object.ClassName /*?*/
console.log(id);
db.hm.Undo();/*?*/
db.hm.Redo();/*?*/
function createLine()
{
for (let i = 0; i < 5000; i++)
{
let l = CADFactory.CreateObject("Line") as Line;
}
}
test('create line', () =>
{
});
// createLine(); //?.
function undoRedo()
{
for (let i = 0; i < 5000; i++)
{
db.hm.Undo();
db.hm.Redo();
}
}
// undoRedo(); //?.

@ -1,353 +0,0 @@
/*
webCAD .
,,.
.
ID
.
*/
import { List } from "immutable"
class CADObject
{
ApplyUndoData(data: any)
{
}
}
/**
*
*
* @class Database
*/
class Database extends CADObject
{
private curUndoIndex = -1;
//命令撤销数据列表
commandUndoData: { cmdName: string, undoData: Map<CADObject, UndoFile> }[] = [];
get UndoData(): Map<CADObject, UndoFile>
{
if (this.commandUndoData.length == 0)
{
this.startCmd("");
}
return this.commandUndoData[this.commandUndoData.length - 1].undoData;
}
startCmd(cmdName: string)
{
if (this.commandUndoData.length > 0 && this.curUndoIndex != this.commandUndoData.length - 1)
{
this.commandUndoData.splice(this.curUndoIndex, this.commandUndoData.length - this.curUndoIndex);
}
this.commandUndoData.push({ cmdName: "", undoData: new Map<CADObject, UndoFile>() });
this.curUndoIndex = this.commandUndoData.length - 1;
}
Undo(cout: number)
{
if (this.curUndoIndex == -1)
{
return;
}
for (let [obj, data] of this.commandUndoData[this.curUndoIndex].undoData)
{
for (let i = data.m_UndoDataList.length; i--;)
{
let d = data.m_UndoDataList[i];
obj.ApplyUndoData(d);
}
}
this.curUndoIndex--;
}
Redo(cout: number)
{
let undoFile = this.commandUndoData[this.curUndoIndex + 1];
if (undoFile)
{
for (let [obj, data] of undoFile.undoData)
{
for (let d of data.m_UndoDataList)
{
obj.ApplyUndoData(d);
}
}
this.curUndoIndex++;
}
}
}
let arr = [0, 1, 2, 3, 4, 5, 6];
arr.splice(3, arr.length - 3);
arr
/**
*
*
* @class UndoFile
*/
class UndoFile
{
m_UndoDataList = [];
}
enum EntityUndoType
{
}
//
interface EntityData
{
id: number;
isErase: boolean;
}
/**
*
*
*
* @class Entity
*/
class Entity extends CADObject
{
protected m_Data: EntityData;
m_Db: Database;
constructor()
{
super();
this.m_Data = {
id: -1,
isErase: false
}
}
get UndoFile(): UndoFile
{
if (this.m_Db)
{
let undoData = this.m_Db.UndoData;
if (!undoData.has(this))
{
undoData.set(this, new UndoFile());
}
return undoData.get(this);
}
}
WriteUndoData(data: any)
{
let undoFile = this.UndoFile;
if (undoFile)
{
undoFile.m_UndoDataList.push(data);
}
}
}
/**
* 线
*
* @enum {number}
*/
enum LineUndoType
{
Full = 0,
StartPoint = 1,
EndPoint = 2,
}
//
interface LineData extends EntityData
{
startPoint: List<number>,
endPoint: List<number>
}
/**
* 线
*
* @class Line
*/
class Line extends Entity
{
protected m_Data: LineData;
constructor()
{
super();
this.m_Data.startPoint = List([0, 0, 0]);
this.m_Data.endPoint = List([0, 0, 0]);
}
get StartPoint(): number[]
{
return this.m_Data.startPoint.toJS();
}
set StartPoint(value: number[])
{
let newP = List(value);
this.WriteUndoData({ type: LineUndoType.StartPoint, data: { startPoint: this.m_Data.startPoint } });
this.m_Data.startPoint = newP;
}
ApplyUndoData(data: any)
{
switch (data.type)
{
case LineUndoType.Full:
break;
case LineUndoType.StartPoint:
this.m_Data.startPoint = data.data.startPoint;
break;
default:
break;
}
}
}
/**
* ,使.
*
* @class EentiyDrawAdapter
*/
class EentiyDrawAdapter
{
Draw()
{
return undefined;
}
}
/**
* 线
*
* @class LineAdapter
* @extends {EentiyDrawAdapter}
*/
class LineAdapter extends EentiyDrawAdapter
{
Draw()
{
return undefined;
}
Update(type: number)
{
switch (type)
{
case LineUndoType.Full:
break;
case LineUndoType.StartPoint:
break;
case LineUndoType.EndPoint:
break;
default:
break;
}
}
}
let line = new Line();
console.log(line);
line.StartPoint = [1, 2, 3];
console.log(line);
let db = new Database();
line.m_Db = db;
line.StartPoint = [3, 3, 3];
console.log(line);
line.StartPoint = [3, 3, 5];
line.StartPoint = [12, 3, 5];
console.log(line);
console.log(db.commandUndoData);
db.Undo(1);
console.log(line.StartPoint);
db.Redo(1);
db.startCmd("");
console.log(line.StartPoint);
function per()
{
for (let i = 0; i < 5000; i++)
{
new Line();
}
}
function per2()
{
for (let i = 0; i < 5000; i++)
{
line.StartPoint = [3, 3, 3];
// console.log(line);
// line.StartPoint = [3, 3, 5];
line.StartPoint = [12, 3, 5];
// console.log(line);
// console.log(db.commandUndoData);
db.Undo(1);
// console.log(line);
db.Redo(1);
db.startCmd("");
// console.log(line.StartPoint);
}
}
per();/*?.*/
per2();/*?.*/
per2();/*?.*/
per2();/*?.*/
per2();/*?.*/
console.log(3);

@ -1,15 +0,0 @@
import { GeUtils } from '../../src/Geometry/GeUtils';
import * as THREE from "three";
import { Vector3 } from 'three';
test("测试平行", () =>
{
let v1 = new Vector3(0, 0, 1);
let v2 = new Vector3(0.0001, 0, 1);
expect(GeUtils.isParallelTo(v1, v2)).toBe(false);
expect(v1.equals(new THREE.Vector3(0, 0, 1))).toBe(true);
expect(v2.equals(new THREE.Vector3(0.0001, 0, 1))).toBe(true);
// console.log(v1.isParallelTo(v2));
// console.log(v1);
// console.log(v2);
})
Loading…
Cancel
Save