2019-03-04 18:16:11 +00:00
|
|
|
class FSMDocument {
|
|
|
|
|
|
|
|
constructor(name) {
|
|
|
|
this.id = guid();
|
|
|
|
this.name = null;
|
|
|
|
this.createdAt = Date.now();
|
|
|
|
this.lastModified = Date.now();
|
|
|
|
this.element = null;
|
|
|
|
this.unsaved = true;
|
|
|
|
this.lastSavedHash = '';
|
|
|
|
this.states = [];
|
|
|
|
this.connections = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
tick() {
|
|
|
|
this.states.forEach(stateA => {
|
|
|
|
this.states.forEach(stateB => {
|
|
|
|
if (stateA !== stateB && stateA.intersects(stateB)) {
|
|
|
|
const inter = stateA.intersection(stateB);
|
|
|
|
const angle1 = stateA.directionTo(stateB);
|
|
|
|
const angle2 = angle1 + Math.PI;
|
|
|
|
|
|
|
|
const x1 = Math.cos(angle1) * inter + stateA.x;
|
|
|
|
const y1 = Math.sin(angle1) * inter + stateA.y;
|
|
|
|
const x2 = Math.cos(angle2) * inter + stateB.x;
|
|
|
|
const y2 = Math.sin(angle2) * inter + stateB.y;
|
|
|
|
|
|
|
|
stateA.moveTo(x1, y1);
|
|
|
|
stateB.moveTo(x2, y2);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
this.states.forEach(state => {
|
|
|
|
if (state.v) {
|
|
|
|
state.moveToStep();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if(!this.unsaved) {
|
|
|
|
if(this.hashCode() !== this.lastSavedHash) {
|
|
|
|
this.unsaved = true;
|
|
|
|
this.element.classList.add('unsaved');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
draw() {
|
|
|
|
this.states.forEach(state => state.draw());
|
|
|
|
this.connections.forEach(connection => connection.draw());
|
|
|
|
}
|
|
|
|
|
|
|
|
onDblClick(x, y) {
|
|
|
|
if (!selectedObject) {
|
|
|
|
selectedObject = new State(x, y);
|
|
|
|
this.states.push(selectedObject);
|
|
|
|
resetCaret();
|
|
|
|
} else if (selectedObject instanceof State) {
|
|
|
|
selectedObject.isAcceptState = !selectedObject.isAcceptState;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-07 15:13:08 +00:00
|
|
|
onRightClick(x, y) {
|
|
|
|
if(!selectedObject) {
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-04 18:16:11 +00:00
|
|
|
deleteCurrentObject() {
|
|
|
|
if (!!selectedObject) {
|
|
|
|
if (selectedObject instanceof State) {
|
|
|
|
this.states.splice(this.states.findIndex(state => state === selectedObject), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let i = 0; i < this.connections.length; i++) {
|
|
|
|
const con = this.connections[i];
|
|
|
|
if (con === selectedObject || con.state === selectedObject || con.stateA === selectedObject || con.stateB === selectedObject) {
|
|
|
|
this.connections.splice(i--, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
selectedObject = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-07 15:13:08 +00:00
|
|
|
}
|