更新数据持久化设计, 分离代码.

pull/7/head
ChenX 7 years ago
parent fbcfd24e29
commit 32c3e591d0

@ -1,16 +0,0 @@
test("", () =>
{
})
// window["t"] = () =>
// {
// app.m_Database.StartTransaction();
// let line = new Line(new THREE.Vector3(Math.random() * 100, Math.random() * 100), new THREE.Vector3(Math.random() * 100, Math.random() * 100))
// app.m_Database.appendEntity(line);
// app.m_Database.CommitTransaction();
// }

@ -1,33 +0,0 @@
import * as mst from 'mobx-state-tree';
import { EntityData } from '../../src/DatabaseServices/EntityData';
test("Entity", () =>
{
let d = EntityData.create({ size: [0, 1, 2] })
console.log(mst.getSnapshot(d));
console.log(d.getSize());
d.setSize(1, 1, 1000);
console.log(d.getSize());
expect(d.getSize().x).toBe(1);
})
test("not late", () =>
{
let d = EntityData.create({ size: [0, 1, 2] })
console.log(mst.getSnapshot(d));
console.log(d.getSize());
d.setSize(1, 1, 1000);
console.log(d.getSize());
expect(d.getSize().x).toBe(1);
expect(d.getSize().y).toBe(1);
expect(d.getSize().z).toBe(1000);
console.log(typeof d.getSize());
})

@ -1,97 +0,0 @@
import { autorun } from 'mobx';
import * as mst from 'mobx-state-tree';
import { EntityData, IEntityData, LineData } from '../src/DatabaseServices/EntityData';
class E
{
m_Data: IEntityData;
constructor()
{
this.initData();
autorun(() =>
{
this.eraseT(this.m_Data.isErase);
})
}
initData()
{
this.m_Data = EntityData.create();
console.log("hello e");
}
erase(isErase: boolean)
{
this.m_Data.setErase(isErase);
}
private eraseT(isErase: boolean)
{
console.log(isErase);
}
}
class L extends E
{
constructor()
{
super()
}
initData()
{
this.m_Data = LineData.create();
console.log("hello l");
}
}
{
let l = new L()
let a: (typeof EntityData.SnapshotType) = mst.getSnapshot(l.m_Data);
console.log(mst.getSnapshot(l.m_Data));
let snp = mst.getSnapshot(l.m_Data);
l.erase(true);
l.erase(true);
l.erase(true);
l.erase(true);
l.erase(true);
console.log(l.m_Data.isErase);
mst.applySnapshot(l.m_Data, snp);
console.log(l.m_Data.isErase);
}
function add(a, b)
{
return a + b;
}
//Remove Path
{
const L = mst.types.model(
"Test",
{
lst: mst.types.array(mst.types.number)
})
.actions(self =>
{
return {
remove(a)
{
this.lst.remove(a)
}
}
})
let l = L.create({ lst: [1, 2, 3] })
mst.onPatch(l, (p, rp) =>
{
console.log(p);
})
l.remove(3);
}

@ -1,44 +0,0 @@
import { LineUndoType } from './FileSystem.test';
/**
* ,使.
*
* @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;
}
}
}

@ -0,0 +1,103 @@
import { Vector3 } from "three";
import { Database, Line, CADFactory } from '../../src/DatabaseServices/FileSystem';
test('id分配', () =>
{
CADFactory.RegisterObject(Line);
let db = new Database();
let line = new Line();
line.StartPoint = new Vector3(10, 3, 2);
let id = db.ModelSpace.Append(line);
expect(id != undefined).toBeTruthy();
expect(id.Object === line).toBeTruthy();
db.hm.Undo();
expect(id.IsErase).toBeTruthy();
expect(db.ModelSpace.Cout()).toBe(0);
db.hm.Redo();
expect(db.ModelSpace.Cout()).toBe(1);
expect(!id.IsErase).toBeTruthy();
let file = db.FileOut();
let db2 = new Database();
db2.FileIn(file);
console.log(db2.GetObjectId(0));
db2.GetObjectId(0).Object.ClassName //?
console.log(db2.ModelSpace.Cout());
console.log(file);
});
test('changev', () =>
{
let db = new Database();
let l1 = new Line();
let id = db.ModelSpace.Append(l1);
db.hm.Undo();
db.hm.Redo();
console.log(id.Object === l1);
(id.Object as Line).StartPoint = new Vector3(2, 3, 4);
let file = db.FileOut();
console.log(file.ToString());
});
test('xxx', () =>
{
let db = new Database();
db.hm.StartCmd("");
let l1 = new Line();
let l2 = new Line();
let id1 = db.ModelSpace.Append(l1);
let in2 = db.ModelSpace.Append(l2);
db.hm.Undo(); //?
db.hm.Redo(); //?
db.hm.StartCmd("");
db.ModelSpace.Remove(db.GetObjectId(1).Object);
db.hm.Undo(); //?
db.hm.Undo(); //?
db.hm.Redo(); //?
// db.hm.StartCmd("");
(id1.Object as Line).StartPoint = new Vector3(10, 4, 2);
(id1.Object as Line).EndPoint = new Vector3(2, 2, 2);
let file = db.FileOut();
console.log(file.ToString());
});
// function createLine()
// {
// for (let i = 0; i < 5000; i++)
// {
// let l = CADFactory.CreateObject("Line") as Line;
// }
// }
// // createLine(); //?.
// function undoRedo()
// {
// for (let i = 0; i < 5000; i++)
// {
// db.hm.Undo();
// db.hm.Redo();
// }
// }
// // undoRedo(); //?.

@ -1,19 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`相交测试 1`] = `
Vector3 {
"x": 0.5,
"y": 0,
"z": 0,
}
`;
exports[`相交测试 2`] = `undefined`;
exports[`相交测试 3`] = `
Vector3 {
"x": 0.5,
"y": 5,
"z": 0,
}
`;

@ -1,33 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`测试求向量 1`] = `
Vector3 {
"x": 0,
"y": -1,
"z": 0,
}
`;
exports[`测试求向量 2`] = `
Vector3 {
"x": 0,
"y": -1,
"z": 0,
}
`;
exports[`测试求向量 3`] = `
Vector3 {
"x": 0,
"y": 1,
"z": 0,
}
`;
exports[`测试求向量 4`] = `
Vector3 {
"x": 0.7071067811865475,
"y": 0,
"z": 0.7071067811865475,
}
`;

@ -1,18 +0,0 @@
import { GeUtils } from "../../src/Geometry/GeUtils";
test("GeUtils.angle", () =>
{
let pi2 = Math.PI * 0.5;
let pi4 = pi2 * 0.5;
console.log(GeUtils.fixAngle(0.05, pi2, 0.1)/*?*/ == 0);
console.log(GeUtils.fixAngle(0.08, pi2, 0.1)/*?*/ == 0);
console.log(GeUtils.fixAngle(0.09, pi2, 0.1)/*?*/ == 0);
console.log(GeUtils.fixAngle(-0.05, pi2, 0.1)/*?*/ == Math.PI * 2);
console.log(GeUtils.fixAngle(Math.PI / 2 + 0.01, pi2, 0.1)/*?*/ == Math.PI / 2);
console.log(GeUtils.fixAngle(0.3, pi2));
})

@ -1,32 +0,0 @@
import * as THREE from 'three';
import { Intersect } from '../../src/Geometry/GeUtils';
test('相交测试', () =>
{
let p1 = new THREE.Vector3(0, 0, 0);
let p2 = new THREE.Vector3(1, 0, 0);
let p3 = new THREE.Vector3(0.5, 0.5, 0);
let p4 = new THREE.Vector3(0.5, 1, 0);
let p5 = new THREE.Vector3(3, 0, 0);
let p6 = new THREE.Vector3(6, 0, 0);
let res = Intersect(p1, p2, p3, p4);/*?*/
expect(res).toMatchSnapshot();
res = Intersect(p1, p2, p5, p6);/*?*/
expect(res).toMatchSnapshot();
let ins = Intersect(
new THREE.Vector3(0, 5),
new THREE.Vector3(5, 5),
new THREE.Vector3(0.5, 1),
new THREE.Vector3(0.5, 8));
expect(ins).toMatchSnapshot();
}
)

@ -1,111 +0,0 @@
import * as THREE from 'three';
import { GeUtils } from '../../src/Geometry/GeUtils';
import { Orbit } from '../../src/Geometry/Orbit';
test("", () =>
{
//构造一个控制类.
let orb = new Orbit();
let dir = new THREE.Vector3(0, 1, 0);
orb.UpdateRoValue(dir);
expect(GeUtils.equaln(orb.RoX, 0)).toBe(true);
expect(GeUtils.equaln(orb.RoZ, Math.PI * 0.5)).toBe(true);
//试着还原
orb.UpdateDirection(dir);
expect(GeUtils.equal(dir, new THREE.Vector3(0, 1, 0))).toBe(true);
//试试新的
dir.set(1, 0, 0);
orb.UpdateRoValue(dir);
expect(GeUtils.equaln(orb.RoX, 0)).toBe(true);
expect(GeUtils.equaln(orb.RoZ, 0)).toBe(true);
//试着还原
orb.UpdateDirection(dir);
expect(GeUtils.equal(dir, new THREE.Vector3(1, 0, 0))).toBe(true);
//试试新的
dir.set(0.5, 0.5, 0).normalize();
let dirc = dir.clone();
orb.UpdateRoValue(dir);
//试着还原
orb.UpdateDirection(dir);
console.log('dir: ', dir);
expect(GeUtils.equal(dir, dirc)).toBe(true);
//试试新的
dir.set(0.5, 0.5, 1).normalize();
dirc = dir.clone();
orb.UpdateRoValue(dir);
//试着还原
orb.UpdateDirection(dir);
console.log('dir: ', dir);
expect(GeUtils.equal(dir, dirc)).toBe(true);
dir.set(0, 0, -1);
dirc = dir.clone();
orb.UpdateRoValue(dir);
expect(GeUtils.equaln(orb.RoZ, Math.PI * 0.5)).toBe(true);
expect(GeUtils.equaln(orb.RoX, Math.PI * -0.5)).toBe(true);
//试着还原
orb.UpdateDirection(dir);
console.log('dir: ', dir);
expect(GeUtils.equal(dir, dirc)).toBe(true);
let newDir = orb.UpdateDirection();
console.log('newDir: ', newDir);
let up = Orbit.ComputUpDirection(new THREE.Vector3(0, 0, 1));
expect(GeUtils.equal(up, new THREE.Vector3(0, -1, 0))).toBe(true);
Orbit.ComputUpDirection(new THREE.Vector3(0, 0, -1), up);
console.log(up);
Orbit.ComputUpDirection(new THREE.Vector3(0, 0, 1), up);
console.log(up);
Orbit.ComputUpDirection(new THREE.Vector3(1, 0, 0), up);
let newD = orb.UpdateDirection();
console.log(newD);
expect(GeUtils.equal(newD, new THREE.Vector3(0, 0, -1))).toBe(true);
})
test("测试求向量", () =>
{
let dir = new THREE.Vector3(0, 0, 1);
let up = Orbit.ComputUpDirection(dir);
console.log(up);
expect(up).toMatchSnapshot();
Orbit.ComputUpDirection(dir, up);
console.log(up);
expect(up).toMatchSnapshot();
dir.z = -1;
Orbit.ComputUpDirection(dir, up);
console.log('up: ', up);
expect(up).toMatchSnapshot();
dir.x = 1;
Orbit.ComputUpDirection(dir, up);
console.log('up: ', up);
expect(up).toMatchSnapshot();
})

@ -1,15 +0,0 @@
import * as THREE from 'three';
test('should behave...', () =>
{
let p1 = new THREE.Vector3(0, 0, 0);
let p2 = new THREE.Vector3(1, 0, 0);
let p3 = new THREE.Vector3(0.5, 0.5, 0);
let p4 = new THREE.Vector3(0.5, 1, 0);
});

@ -83,20 +83,6 @@
"ts",
"tsx",
"js"
],
"moduleNameMapper": {
"dat.gui": "<rootDir>/node_modules/dat.gui/build/dat.gui.js",
"three-FBXLoader": "<rootDir>/src/Loader/FBXLoader.js",
"zlib": "<rootDir>/node_modules/three/examples/js/libs/inflate.min.js",
"three-CopyShader": "<rootDir>/node_modules/three/examples/js/shaders/CopyShader.js",
"three-SMAAShader": "<rootDir>/node_modules/three/examples/js/shaders/SMAAShader.js",
"three-FXAAShader": "<rootDir>/node_modules/three/examples/js/shaders/FXAAShader.js",
"three-OutlinePass": "<rootDir>/src/GraphicsSystem/OutlinePass.js",
"three-EffectComposer": "<rootDir>/node_modules/three/examples/js/postprocessing/EffectComposer.js",
"three-RenderPass": "<rootDir>/node_modules/three/examples/js/postprocessing/RenderPass.js",
"three-ShaderPass": "<rootDir>/node_modules/three/examples/js/postprocessing/ShaderPass.js",
"three-SMAAPass": "<rootDir>/node_modules/three/examples/js/postprocessing/SMAAPass.js",
"three-Reflector": "<rootDir>/src/objects/Reflector.js"
}
]
}
}

@ -1,4 +1,3 @@
import { ArrayRemove } from '../../src/Common/Utils';
import { Vector3 } from 'three';
/*
@ -107,7 +106,7 @@ id只有在一个情况下才会更新.跨文档复制时.
//CAD对象工厂,通过注册 和暴露的创建方法,动态创建对象
class CADFactory
export class CADFactory
{
private constructor() { }
private objectNameMap = new Map<string, () => CADObject>();
@ -128,7 +127,7 @@ class CADFactory
//所有cad对象的基类
class CADObject
export class CADObject
{
//#region -------------------------DB-------------------------
@ -234,7 +233,7 @@ class CADObject
let index = file.Read();
if (index >= 0 && this._db)
{
return this._db.GetObjectId(index);
return ObjectId.Create(this._db, index);
}
}
}
@ -246,7 +245,7 @@ CADObject对象拥有Id属性,用来记录引用关系.
ObjectId使 Database(dbid,便id)
*/
class ObjectId
export class ObjectId
{
private id: number;
private obj: CADObject;
@ -270,12 +269,12 @@ class ObjectId
3.redo
4.
*/
static Create(db: Database, index: number, obj: CADObject): ObjectId
static Create(db: Database, index: number): ObjectId
{
let id = db.GetObjectId(index);
if (!id)
{
id = new ObjectId(index, obj);
id = new ObjectId(index);
db.SetObjectId(index, id);
}
return id;
@ -296,10 +295,15 @@ class ObjectId
}
//cad文件数据
class CADFile
export class CADFile
{
private readIndex: number = 0;
private dataList: any[] = [];
Rest()
{
this.readIndex = 0;
}
WriteString(str: string)
{
this.dataList.push(str);
@ -334,12 +338,15 @@ class CADFile
this.readIndex++;
return data;
}
ToString()
{
return JSON.stringify(this.dataList);
}
}
class AppendData extends CADObject
export class AppendData extends CADObject
{
private object: CADObject;
private cadFile: CADFile;
constructor(obj: CADObject)
{
@ -350,12 +357,9 @@ class AppendData extends CADObject
getObject(db: Database): CADObject
{
if (!this.object)
{
this.object = this.cadFile.ReadObject(db);
}
return this.object;
let obj = this.cadFile.ReadObject(db);
this.cadFile.Rest();
return obj;
}
//#region -----------------------------File-----------------------------
@ -376,7 +380,7 @@ class AppendData extends CADObject
{ }
//#endregion -----------------------------File End-----------------------------
}
class RemoveData extends CADObject
export class RemoveData extends CADObject
{
private index: number;
constructor(index?: number)
@ -409,9 +413,9 @@ class RemoveData extends CADObject
}
//对象集合.
class ObjectCollection<T> extends CADObject
export class ObjectCollection<T> extends CADObject
{
private objectCol: CADObject[] = [];
objectCol: CADObject[] = [];
//添加一个对象进入集合,这个集合存在db中,那么将自动分配id.
Append(obj: CADObject)
@ -423,7 +427,6 @@ class ObjectCollection<T> extends CADObject
obj.InitObjectId(this._db);
}
if (this._db && this._db.hm.UndoData)
{
let hisRec = new HistoricRecord();
@ -468,10 +471,26 @@ class ObjectCollection<T> extends CADObject
}
//对象从文件中读取数据,初始化自身
FileIn(file: CADFile)
{ }
{
super.FileIn(file);
let cout = file.Read();
this.objectCol = [];
for (let i = 0; i < cout; i++)
{
let obj = file.ReadObject(this._db);
this.objectCol.push(obj);
}
}
//对象将自身数据写入到文件.
FileOut(file: CADFile)
{ }
{
super.FileOut(file);
file.Write(this.objectCol.length);
for (let obj of this.objectCol)
{
file.WriteObject(obj);
}
}
//局部撤销
ApplyPartialUndo(undoData: CADObject)
{
@ -489,7 +508,7 @@ class ObjectCollection<T> extends CADObject
}
//命令历史记录集合
class CommandHistoryRecord extends CADObject
export class CommandHistoryRecord extends CADObject
{
constructor(cmdName: string)
{
@ -527,7 +546,7 @@ class CommandHistoryRecord extends CADObject
* @class HistoricRecord
* @extends {CADObject}
*/
class HistoricRecord extends CADObject
export class HistoricRecord extends CADObject
{
//指定撤销时所需要的数据
undoData: CADObject;
@ -537,10 +556,10 @@ class HistoricRecord extends CADObject
}
//历史记录管理
class HistoricManage extends CADObject
export class HistoricManage extends CADObject
{
private curIndex: number = -1; //当前执行位置
private historyRecord: CommandHistoryRecord[] = []; //历史记录
curIndex: number = -1; //当前执行位置,也就是当前的状态, undo时,撤销当前状态,redo时,应用下一个状态
historyRecord: CommandHistoryRecord[] = []; //历史记录
private doing: boolean = false;
constructor()
@ -553,7 +572,7 @@ class HistoricManage extends CADObject
{
return undefined;
}
if (this.historyRecord.length === 0)
if (this.historyRecord.length === 0 || this.curIndex != this.historyRecord.length - 1)
{
this.StartCmd("");
}
@ -562,7 +581,8 @@ class HistoricManage extends CADObject
StartCmd(cmdName: string)
{
this.historyRecord.splice(this.curIndex, this.historyRecord.length - this.curIndex);
//删除当前状态以后的所有状态
this.historyRecord.splice(this.curIndex + 1, this.historyRecord.length - (this.curIndex + 1));
this.historyRecord.push(new CommandHistoryRecord(cmdName));
this.curIndex = this.historyRecord.length - 1;
}
@ -578,9 +598,9 @@ class HistoricManage extends CADObject
for (let [id, recList] of historyRec.HistoryList)
{
let obj = id.Object;
for (let rec of recList)
for (let i = recList.length; i--;)
{
obj.ApplyPartialUndo(rec.undoData);
obj.ApplyPartialUndo(recList[i].undoData);
}
}
this.curIndex--;
@ -598,9 +618,9 @@ class HistoricManage extends CADObject
for (let [id, recList] of historyRec.HistoryList)
{
let obj = id.Object;
for (let i = recList.length; i--;)
for (let rec of recList)
{
obj.ApplyPartialUndo(recList[i].redoData);
obj.ApplyPartialUndo(rec.redoData);
}
}
this.curIndex++;
@ -609,8 +629,7 @@ class HistoricManage extends CADObject
}
}
class Database
export class Database
{
hm: HistoricManage;
@ -620,9 +639,6 @@ class Database
ModelSpace: BlockTableRecord;
//材质字典...
objectCol = new Map<number, CADObject>();
private idCout = -1;
private idMap = new Map<number, ObjectId>();
@ -633,36 +649,29 @@ class Database
this.hm = new HistoricManage();
this.hm.SetDefaultDb(this);
}
getObject(id: number): CADObject
{
return this.objectCol.get(id);
}
appendObject(obj: CADObject)
FileOut(): CADFile
{
let id = this.objectCol.size;
this.objectCol.set(id, obj);
let file = new CADFile();
file.Write(1);//ver;
file.Write(this.idCout);
this.ModelSpace.FileOut(file);
return file;
}
ApplyPartialUndo(data)
{
switch (data)
FileIn(file: CADFile)
{
case 1:
// this.objectCol.get(data.i).IsErase = true;
break;
case 2:
// this.objectCol.get(data.i).isErase = false;
break;
let ver = file.Read();
this.idCout = file.Read();
this.ModelSpace.FileIn(file);
}
}
//创建一个id,自动递增它的索引号,并且会自动加入到db的id列表中.
AllocateId(obj: CADObject): ObjectId
{
if (obj.Db === this)
{
this.idCout++;
let id = ObjectId.Create(this, this.idCout, obj);
let id = ObjectId.Create(this, this.idCout);
id.Object = obj;
return id;
}
else
@ -696,7 +705,7 @@ class Database
}
}
class BlockTableRecord extends ObjectCollection<Entity>
export class BlockTableRecord extends ObjectCollection<Entity>
{
constructor()
{
@ -712,10 +721,14 @@ class BlockTableRecord extends ObjectCollection<Entity>
}
//对象从文件中读取数据,初始化自身
FileIn(file: CADFile)
{ }
{
super.FileIn(file);
}
//对象将自身数据写入到文件.
FileOut(file: CADFile)
{ }
{
super.FileOut(file);
}
//局部撤销
ApplyPartialUndo(file: CADObject)
{
@ -724,26 +737,20 @@ class BlockTableRecord extends ObjectCollection<Entity>
//#endregion-----------------------------File End-----------------------------
}
//所有图元的基类
class Entity extends CADObject
export class Entity extends CADObject
{
}
//直线撤销类型
export enum LineUndoType
{
Full = 0,
StartPoint = 1,
EndPoint = 2,
}
//直线对象
class Line extends Entity
export class Line extends Entity
{
private startPoint: Vector3;
private endPoint: Vector3;
constructor()
{
super();
this.startPoint = new Vector3(0, 0, 0);
this.endPoint = new Vector3(0, 0, 0);
}
//-----------------------------File-----------------------------
@ -759,25 +766,20 @@ class Line extends Entity
FileIn(file: CADFile)
{
super.FileIn(file);
let ver = file.Read();
this.startPoint.fromArray(file.Read());
this.endPoint.fromArray(file.Read());
}
//对象将自身数据写入到文件.
FileOut(file: CADFile)
{
super.FileOut(file);
file.Write(1);//ver
file.Write(this.startPoint.toArray());
file.Write(this.endPoint.toArray());
}
ApplyPartialUndo(data)
{
switch (data.type)
{
case LineUndoType.Full:
break;
case LineUndoType.StartPoint:
break;
default:
break;
}
}
//-----------------------------File End-----------------------------
@ -790,61 +792,16 @@ class Line extends Entity
{
return this.startPoint.clone();
}
}
CADFactory.RegisterObject(Line);
test('工厂构造实体', () =>
get EndPoint(): Vector3
{
let l = CADFactory.CreateObject("Line") as Line;
expect(l != undefined).toBeTruthy();
expect(l.ClassName).toBe("Line");
expect(l.Id).toBeUndefined();
});
test('id分配', () =>
return this.endPoint;
}
set EndPoint(v: Vector3)
{
let db = new Database();
let line = new Line();
let id = db.ModelSpace.Append(line);
expect(id != undefined).toBeTruthy();
expect(id.Object === line).toBeTruthy();
db.hm.Undo();
expect(id.IsErase).toBeTruthy();
expect(db.ModelSpace.Cout()).toBe(0);
db.hm.Redo();
expect(db.ModelSpace.Cout()).toBe(1);
expect(!id.IsErase).toBeTruthy();
});
// function createLine()
// {
// for (let i = 0; i < 5000; i++)
// {
// let l = CADFactory.CreateObject("Line") as Line;
// }
// }
// // createLine(); //?.
this.endPoint = v;
}
// function undoRedo()
// {
// for (let i = 0; i < 5000; i++)
// {
// db.hm.Undo();
// db.hm.Redo();
// }
// }
}
// // undoRedo(); //?.
CADFactory.RegisterObject(Line);
Loading…
Cancel
Save