circuitscript 0.0.22 → 0.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/BaseVisitor.js +487 -0
- package/dist/cjs/SemanticTokenVisitor.js +218 -0
- package/dist/cjs/SymbolValidatorVisitor.js +233 -0
- package/dist/cjs/antlr/CircuitScriptLexer.js +302 -0
- package/dist/cjs/antlr/CircuitScriptParser.js +5128 -0
- package/dist/cjs/antlr/CircuitScriptVisitor.js +7 -0
- package/dist/cjs/draw_symbols.js +819 -0
- package/dist/cjs/execute.js +778 -0
- package/{src/export.ts → dist/cjs/export.js} +34 -56
- package/dist/cjs/fonts.js +4 -0
- package/dist/cjs/geometry.js +450 -0
- package/dist/cjs/globals.js +60 -0
- package/dist/cjs/helpers.js +269 -0
- package/dist/cjs/index.js +31 -0
- package/{src/layout.ts → dist/cjs/layout.js} +421 -1002
- package/dist/cjs/lexer.js +111 -0
- package/dist/cjs/logger.js +17 -0
- package/dist/cjs/main.js +82 -0
- package/dist/cjs/objects/ClassComponent.js +145 -0
- package/dist/cjs/objects/ExecutionScope.js +135 -0
- package/dist/cjs/objects/Frame.js +22 -0
- package/{src/objects/Net.ts → dist/cjs/objects/Net.js} +9 -24
- package/dist/cjs/objects/ParamDefinition.js +42 -0
- package/dist/cjs/objects/PinDefinition.js +31 -0
- package/dist/cjs/objects/PinTypes.js +11 -0
- package/dist/cjs/objects/Wire.js +9 -0
- package/dist/cjs/objects/types.js +15 -0
- package/dist/cjs/parser.js +70 -0
- package/dist/cjs/regenerate-tests.js +23 -0
- package/dist/cjs/render.js +155 -0
- package/{src/server.ts → dist/cjs/server.js} +15 -21
- package/dist/cjs/sizing.js +105 -0
- package/{src/utils.ts → dist/cjs/utils.js} +25 -35
- package/dist/cjs/validate.js +81 -0
- package/dist/cjs/visitor.js +844 -0
- package/dist/esm/BaseVisitor.mjs +488 -0
- package/dist/esm/SemanticTokenVisitor.mjs +215 -0
- package/dist/esm/SymbolValidatorVisitor.mjs +222 -0
- package/dist/esm/antlr/CircuitScriptLexer.mjs +276 -0
- package/dist/esm/antlr/CircuitScriptParser.mjs +5038 -0
- package/{build/src/antlr/CircuitScriptVisitor.js → dist/esm/antlr/CircuitScriptVisitor.mjs} +8 -3
- package/{build/src/draw_symbols.js → dist/esm/draw_symbols.mjs} +78 -33
- package/{build/src/execute.js → dist/esm/execute.mjs} +59 -60
- package/{build/src/export.js → dist/esm/export.mjs} +2 -2
- package/{build/src/geometry.js → dist/esm/geometry.mjs} +31 -15
- package/dist/esm/helpers.mjs +252 -0
- package/dist/esm/index.mjs +15 -0
- package/{build/src/layout.js → dist/esm/layout.mjs} +19 -11
- package/{build/src/lexer.js → dist/esm/lexer.mjs} +10 -10
- package/{build/src/main.js → dist/esm/main.mjs} +9 -14
- package/{build/src/objects/ClassComponent.js → dist/esm/objects/ClassComponent.mjs} +6 -3
- package/{build/src/objects/ExecutionScope.js → dist/esm/objects/ExecutionScope.mjs} +1 -0
- package/{build/src/objects/PinDefinition.js → dist/esm/objects/PinDefinition.mjs} +1 -1
- package/dist/esm/objects/types.mjs +12 -0
- package/dist/esm/parser.mjs +64 -0
- package/{build/src/regenerate-tests.js → dist/esm/regenerate-tests.mjs} +1 -1
- package/{build/src/render.js → dist/esm/render.mjs} +7 -24
- package/{build/src/sizing.js → dist/esm/sizing.mjs} +22 -8
- package/{src/main.ts → dist/esm/validate.mjs} +31 -62
- package/dist/esm/visitor.mjs +838 -0
- package/dist/types/BaseVisitor.d.ts +69 -0
- package/dist/types/SemanticTokenVisitor.d.ts +36 -0
- package/dist/types/SymbolValidatorVisitor.d.ts +61 -0
- package/{build/src → dist/types}/antlr/CircuitScriptLexer.d.ts +28 -27
- package/dist/types/antlr/CircuitScriptParser.d.ts +719 -0
- package/{build/src → dist/types}/antlr/CircuitScriptVisitor.d.ts +69 -59
- package/{build/src → dist/types}/draw_symbols.d.ts +11 -2
- package/{build/src → dist/types}/execute.d.ts +6 -9
- package/{build/src → dist/types}/geometry.d.ts +5 -1
- package/dist/types/helpers.d.ts +40 -0
- package/dist/types/index.d.ts +15 -0
- package/{build/src → dist/types}/layout.d.ts +10 -10
- package/{build/src → dist/types}/lexer.d.ts +2 -2
- package/{build/src → dist/types}/objects/ClassComponent.d.ts +2 -2
- package/{build/src → dist/types}/objects/ExecutionScope.d.ts +4 -1
- package/{build/src → dist/types}/objects/PinDefinition.d.ts +1 -1
- package/{build/src → dist/types}/objects/types.d.ts +5 -0
- package/dist/types/parser.d.ts +25 -0
- package/{build/src → dist/types}/render.d.ts +1 -1
- package/{build/src → dist/types}/sizing.d.ts +3 -1
- package/dist/types/validate.d.ts +2 -0
- package/dist/types/visitor.d.ts +80 -0
- package/libs/lib.cst +0 -2
- package/package.json +38 -15
- package/.editorconfig +0 -15
- package/.eslintignore +0 -1
- package/.eslintrc.json +0 -27
- package/.gitlab-ci.yml +0 -81
- package/.prettierignore +0 -8
- package/.prettierrc +0 -16
- package/__tests__/expectedResults.ts +0 -657
- package/__tests__/helpers.ts +0 -82
- package/__tests__/parseScripts.ts +0 -593
- package/__tests__/renderData/script1.cst +0 -58
- package/__tests__/renderData/script1.cst.svg +0 -1
- package/__tests__/renderData/script2.cst +0 -16
- package/__tests__/renderData/script2.cst.svg +0 -1
- package/__tests__/renderData/script3.cst +0 -30
- package/__tests__/renderData/script3.cst.svg +0 -1
- package/__tests__/renderData/script4.cst +0 -54
- package/__tests__/renderData/script4.cst.svg +0 -1
- package/__tests__/renderData/script5.cst +0 -23
- package/__tests__/renderData/script5.cst.svg +0 -1
- package/__tests__/renderData/script6.cst +0 -28
- package/__tests__/renderData/script6.cst.svg +0 -1
- package/__tests__/renderData/script7.cst +0 -26
- package/__tests__/renderData/script7.cst.svg +0 -1
- package/__tests__/renderData/script8.cst +0 -37
- package/__tests__/renderData/script8.cst.svg +0 -1
- package/__tests__/testCLI.ts +0 -68
- package/__tests__/testMathOps.ts +0 -36
- package/__tests__/testMergeWires.ts +0 -141
- package/__tests__/testParse.ts +0 -263
- package/__tests__/testRender.ts +0 -38
- package/build/src/antlr/CircuitScriptLexer.js +0 -287
- package/build/src/antlr/CircuitScriptParser.d.ts +0 -674
- package/build/src/antlr/CircuitScriptParser.js +0 -4841
- package/build/src/helpers.d.ts +0 -1
- package/build/src/helpers.js +0 -73
- package/build/src/objects/types.js +0 -6
- package/build/src/parser.js +0 -69
- package/build/src/visitor.d.ts +0 -133
- package/build/src/visitor.js +0 -1154
- package/documentation.md +0 -238
- package/examples/example_arduino_uno.cst +0 -1146
- package/examples/example_garden_pump.cst +0 -567
- package/examples/lib.cst +0 -185
- package/jest.config.js +0 -23
- package/refresh.html +0 -42
- package/server.cjs +0 -50
- package/src/antlr/CircuitScript.g4 +0 -209
- package/src/antlr/CircuitScriptLexer.ts +0 -317
- package/src/antlr/CircuitScriptParser.ts +0 -4979
- package/src/antlr/CircuitScriptVisitor.ts +0 -420
- package/src/draw_symbols.ts +0 -1085
- package/src/execute.ts +0 -1227
- package/src/fonts.ts +0 -1
- package/src/geometry.ts +0 -638
- package/src/globals.ts +0 -67
- package/src/helpers.ts +0 -114
- package/src/lexer.ts +0 -151
- package/src/logger.ts +0 -17
- package/src/objects/ClassComponent.ts +0 -223
- package/src/objects/ExecutionScope.ts +0 -201
- package/src/objects/Frame.ts +0 -20
- package/src/objects/ParamDefinition.ts +0 -49
- package/src/objects/PinDefinition.ts +0 -49
- package/src/objects/PinTypes.ts +0 -7
- package/src/objects/Wire.ts +0 -19
- package/src/objects/types.ts +0 -66
- package/src/parser.ts +0 -106
- package/src/regenerate-tests.ts +0 -25
- package/src/render.ts +0 -260
- package/src/sizing.ts +0 -96
- package/src/visitor.ts +0 -1691
- package/tsconfig.json +0 -27
- package/tsconfig.release.json +0 -8
- /package/{build/src/fonts.js → dist/esm/fonts.mjs} +0 -0
- /package/{build/src/globals.js → dist/esm/globals.mjs} +0 -0
- /package/{build/src/logger.js → dist/esm/logger.mjs} +0 -0
- /package/{build/src/objects/Frame.js → dist/esm/objects/Frame.mjs} +0 -0
- /package/{build/src/objects/Net.js → dist/esm/objects/Net.mjs} +0 -0
- /package/{build/src/objects/ParamDefinition.js → dist/esm/objects/ParamDefinition.mjs} +0 -0
- /package/{build/src/objects/PinTypes.js → dist/esm/objects/PinTypes.mjs} +0 -0
- /package/{build/src/objects/Wire.js → dist/esm/objects/Wire.mjs} +0 -0
- /package/{build/src/server.js → dist/esm/server.mjs} +0 -0
- /package/{build/src/utils.js → dist/esm/utils.mjs} +0 -0
- /package/{build/src → dist/types}/export.d.ts +0 -0
- /package/{build/src → dist/types}/fonts.d.ts +0 -0
- /package/{build/src → dist/types}/globals.d.ts +0 -0
- /package/{build/src → dist/types}/logger.d.ts +0 -0
- /package/{build/src → dist/types}/main.d.ts +0 -0
- /package/{build/src → dist/types}/objects/Frame.d.ts +0 -0
- /package/{build/src → dist/types}/objects/Net.d.ts +0 -0
- /package/{build/src → dist/types}/objects/ParamDefinition.d.ts +0 -0
- /package/{build/src → dist/types}/objects/PinTypes.d.ts +0 -0
- /package/{build/src → dist/types}/objects/Wire.d.ts +0 -0
- /package/{build/src → dist/types}/regenerate-tests.d.ts +0 -0
- /package/{build/src → dist/types}/server.d.ts +0 -0
- /package/{build/src → dist/types}/utils.d.ts +0 -0
|
@@ -1,71 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export class LayoutEngine {
|
|
16
|
-
|
|
17
|
-
logger: Logger;
|
|
18
|
-
|
|
19
|
-
placeSubgraphVersion = 2;
|
|
20
|
-
|
|
21
|
-
layoutWarnings: string[] = [];
|
|
22
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RenderJunction = exports.RenderFrameType = exports.RenderFrame = exports.RenderText = exports.RenderComponent = exports.RenderWire = exports.RenderObject = exports.getBounds = exports.LayoutEngine = void 0;
|
|
4
|
+
const graphlib_1 = require("@dagrejs/graphlib");
|
|
5
|
+
const draw_symbols_js_1 = require("./draw_symbols.js");
|
|
6
|
+
const ExecutionScope_js_1 = require("./objects/ExecutionScope.js");
|
|
7
|
+
const globals_js_1 = require("./globals.js");
|
|
8
|
+
const ParamDefinition_js_1 = require("./objects/ParamDefinition.js");
|
|
9
|
+
const geometry_js_1 = require("./geometry.js");
|
|
10
|
+
const logger_js_1 = require("./logger.js");
|
|
11
|
+
const Frame_js_1 = require("./objects/Frame.js");
|
|
12
|
+
const utils_js_1 = require("./utils.js");
|
|
13
|
+
class LayoutEngine {
|
|
23
14
|
constructor() {
|
|
24
|
-
this.
|
|
15
|
+
this.placeSubgraphVersion = 2;
|
|
16
|
+
this.layoutWarnings = [];
|
|
17
|
+
this.logger = new logger_js_1.Logger();
|
|
25
18
|
}
|
|
26
|
-
|
|
27
|
-
protected print(...params: any[]): void {
|
|
19
|
+
print(...params) {
|
|
28
20
|
this.logger.add(params.join(' '));
|
|
29
21
|
}
|
|
30
|
-
|
|
31
|
-
protected printLevel(level: number, ...params: any[]): void {
|
|
22
|
+
printLevel(level, ...params) {
|
|
32
23
|
this.logger.add(this.padLevel(level) + params.join(' '));
|
|
33
24
|
}
|
|
34
|
-
|
|
35
|
-
protected padLevel(value: number): string {
|
|
25
|
+
padLevel(value) {
|
|
36
26
|
const padding = ''.padStart(value * 4, ' ');
|
|
37
|
-
return "[" + value + "]" + padding
|
|
27
|
+
return "[" + value + "]" + padding;
|
|
38
28
|
}
|
|
39
|
-
|
|
40
|
-
runLayout(
|
|
41
|
-
sequence: SequenceItem[],
|
|
42
|
-
nets: [ClassComponent, pin: number, net: Net][]
|
|
43
|
-
): {
|
|
44
|
-
components: RenderComponent[], wires: RenderWire[],
|
|
45
|
-
junctions: RenderJunction[], mergedWires: MergedWire[],
|
|
46
|
-
frameObjects: RenderFrame[],
|
|
47
|
-
textObjects: RenderText[]
|
|
48
|
-
} {
|
|
29
|
+
runLayout(sequence, nets) {
|
|
49
30
|
const logNodesAndEdges = false;
|
|
50
|
-
|
|
51
31
|
this.print('===== creating graph and populating with nodes =====');
|
|
52
|
-
const {graph, containerFrames } =
|
|
53
|
-
this.generateLayoutGraph(sequence, nets);
|
|
54
|
-
|
|
32
|
+
const { graph, containerFrames } = this.generateLayoutGraph(sequence, nets);
|
|
55
33
|
this.print('===== done populating graph =====');
|
|
56
34
|
this.print('');
|
|
57
|
-
|
|
58
|
-
if (logNodesAndEdges){
|
|
35
|
+
if (logNodesAndEdges) {
|
|
59
36
|
this.print('===== graph edges =====');
|
|
60
|
-
// dump all edges in the graph
|
|
61
37
|
const allEdges = graph.edges();
|
|
62
38
|
allEdges.forEach(edge => {
|
|
63
39
|
const [nodeId1, pin1, nodeId2, pin2] = graph.edge(edge);
|
|
64
40
|
this.print(nodeId1, 'pin', pin1, '-----', nodeId2, 'pin', pin2);
|
|
65
41
|
});
|
|
66
42
|
this.print('===== end edges =====');
|
|
67
|
-
this.print()
|
|
68
|
-
|
|
43
|
+
this.print();
|
|
69
44
|
this.print('===== graph nodes =====');
|
|
70
45
|
const nodes = graph.nodes();
|
|
71
46
|
nodes.forEach(node => {
|
|
@@ -74,436 +49,286 @@ export class LayoutEngine {
|
|
|
74
49
|
this.print('===== end nodes =====');
|
|
75
50
|
this.print('');
|
|
76
51
|
}
|
|
77
|
-
|
|
78
52
|
const subgraphInfo = this.sizeSubGraphs(graph);
|
|
79
|
-
|
|
80
53
|
const dumpSubgraphInfo = true;
|
|
81
|
-
if (dumpSubgraphInfo){
|
|
54
|
+
if (dumpSubgraphInfo) {
|
|
82
55
|
this.print('===== subgraphs =====');
|
|
83
56
|
subgraphInfo.forEach(item => {
|
|
84
|
-
this.print('first node:', item.firstNodeId, 'bounds:',
|
|
85
|
-
item.bounds.xmin, item.bounds.ymin,
|
|
86
|
-
item.bounds.xmax, item.bounds.ymax);
|
|
87
|
-
|
|
57
|
+
this.print('first node:', item.firstNodeId, 'bounds:', item.bounds.xmin, item.bounds.ymin, item.bounds.xmax, item.bounds.ymax);
|
|
88
58
|
this.print('-- items:', item.components);
|
|
89
59
|
});
|
|
90
60
|
}
|
|
91
|
-
|
|
92
|
-
const {textObjects, elementFrames} =
|
|
93
|
-
this.placeFrames(graph, subgraphInfo, containerFrames);
|
|
61
|
+
const { textObjects, elementFrames } = this.placeFrames(graph, subgraphInfo, containerFrames);
|
|
94
62
|
const frameObjects = [...elementFrames, ...containerFrames];
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
const placedWires: RenderWire[] = [];
|
|
98
|
-
|
|
63
|
+
const placedComponents = [];
|
|
64
|
+
const placedWires = [];
|
|
99
65
|
const tmpNodes = graph.nodes();
|
|
100
66
|
tmpNodes.forEach(item => {
|
|
101
67
|
const nodeValue = graph.node(item);
|
|
102
|
-
const [nodeType, nodeItem]
|
|
103
|
-
|
|
68
|
+
const [nodeType, nodeItem] = nodeValue;
|
|
104
69
|
if (nodeType === RenderItemType.Component) {
|
|
105
|
-
placedComponents.push(nodeItem
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
placedWires.push(nodeItem
|
|
70
|
+
placedComponents.push(nodeItem);
|
|
71
|
+
}
|
|
72
|
+
else if (nodeType === RenderItemType.Wire) {
|
|
73
|
+
placedWires.push(nodeItem);
|
|
109
74
|
}
|
|
110
75
|
});
|
|
111
|
-
|
|
112
|
-
const wireGroups = new Map<string, RenderWire[]>();
|
|
113
|
-
|
|
114
|
-
// Merge wires in the same group?
|
|
76
|
+
const wireGroups = new Map();
|
|
115
77
|
placedWires.forEach(wire => {
|
|
116
|
-
const {netName} = wire;
|
|
117
|
-
if (!wireGroups.has(netName)){
|
|
78
|
+
const { netName } = wire;
|
|
79
|
+
if (!wireGroups.has(netName)) {
|
|
118
80
|
wireGroups.set(netName, []);
|
|
119
81
|
}
|
|
120
|
-
|
|
121
82
|
wireGroups.get(netName).push(wire);
|
|
122
83
|
});
|
|
123
|
-
|
|
124
84
|
const { junctions, mergedWires } = this.findJunctions(wireGroups);
|
|
125
|
-
|
|
126
85
|
return {
|
|
127
86
|
components: placedComponents,
|
|
128
87
|
wires: placedWires,
|
|
129
88
|
mergedWires,
|
|
130
89
|
junctions,
|
|
131
|
-
|
|
132
90
|
frameObjects,
|
|
133
91
|
textObjects,
|
|
134
92
|
};
|
|
135
93
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
mergedWires: MergedWire[],
|
|
140
|
-
} {
|
|
141
|
-
const junctions: RenderJunction[] = [];
|
|
142
|
-
|
|
143
|
-
const mergedWires: MergedWire[] = [];
|
|
144
|
-
|
|
94
|
+
findJunctions(wireGroups) {
|
|
95
|
+
const junctions = [];
|
|
96
|
+
const mergedWires = [];
|
|
145
97
|
for (const [key, wires] of wireGroups) {
|
|
146
|
-
|
|
147
|
-
// Create array of all wires with the same net name
|
|
148
98
|
const allLines = wires.map(wire => {
|
|
149
99
|
return wire.points.map(pt => {
|
|
150
100
|
return {
|
|
151
101
|
x: wire.x + pt.x,
|
|
152
102
|
y: wire.y + pt.y,
|
|
153
|
-
}
|
|
103
|
+
};
|
|
154
104
|
});
|
|
155
105
|
});
|
|
156
|
-
|
|
157
|
-
const { intersectPoints, segments } = Geometry.mergeWires(allLines);
|
|
106
|
+
const { intersectPoints, segments } = geometry_js_1.Geometry.mergeWires(allLines);
|
|
158
107
|
mergedWires.push({
|
|
159
108
|
netName: key,
|
|
160
109
|
segments,
|
|
161
110
|
intersectPoints,
|
|
162
111
|
});
|
|
163
|
-
|
|
164
112
|
intersectPoints.forEach(([x, y]) => {
|
|
165
113
|
junctions.push(new RenderJunction(x, y));
|
|
166
114
|
});
|
|
167
115
|
}
|
|
168
|
-
|
|
169
116
|
return {
|
|
170
117
|
junctions,
|
|
171
118
|
mergedWires
|
|
172
|
-
}
|
|
119
|
+
};
|
|
173
120
|
}
|
|
174
|
-
|
|
175
|
-
placeFrames(graph: graphlib.Graph, subgraphInfo: SubGraphInfo[],
|
|
176
|
-
frameObjects: RenderFrame[]): {
|
|
177
|
-
elementFrames: RenderFrame[],
|
|
178
|
-
textObjects: RenderText[],
|
|
179
|
-
} {
|
|
180
|
-
|
|
181
|
-
// The base/default frame will always be the first element
|
|
121
|
+
placeFrames(graph, subgraphInfo, frameObjects) {
|
|
182
122
|
const baseFrame = frameObjects[0];
|
|
183
123
|
baseFrame.padding = 0;
|
|
184
124
|
baseFrame.borderWidth = 0;
|
|
185
|
-
|
|
186
125
|
baseFrame.x = 0;
|
|
187
126
|
baseFrame.y = 0;
|
|
188
|
-
|
|
189
|
-
let
|
|
190
|
-
let elementFrames: RenderFrame[] = [];
|
|
191
|
-
|
|
127
|
+
let textObjects = [];
|
|
128
|
+
let elementFrames = [];
|
|
192
129
|
baseFrame.bounds = {
|
|
193
130
|
xmin: 0, ymin: 0,
|
|
194
131
|
xmax: 0, ymax: 0,
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
// Update render frames so that frames consist of only nested frames.
|
|
199
|
-
// Layout is easier, since it only has to consider frames.
|
|
200
|
-
// Subgraphs are wrapped inside a subgraph frame.
|
|
201
|
-
const result =
|
|
202
|
-
this.prepareFrames(graph, subgraphInfo, baseFrame);
|
|
132
|
+
};
|
|
133
|
+
if (subgraphInfo.length > 0) {
|
|
134
|
+
const result = this.prepareFrames(graph, subgraphInfo, baseFrame);
|
|
203
135
|
textObjects = result.textObjects;
|
|
204
136
|
elementFrames = result.elementFrames;
|
|
205
|
-
|
|
206
137
|
const logFrames = false;
|
|
207
138
|
if (logFrames) {
|
|
208
139
|
this.print('===== dump frames =====');
|
|
209
140
|
this.dumpFrame(baseFrame);
|
|
210
141
|
this.print('===== dump frames =====');
|
|
211
142
|
}
|
|
212
|
-
|
|
213
143
|
this.placeAndSizeFrame(baseFrame);
|
|
214
144
|
}
|
|
215
|
-
|
|
216
|
-
// All items in the frames are now ready for final placement.
|
|
217
145
|
this.print('===== flatten frame items =====');
|
|
218
146
|
this.applyFrameOffset(baseFrame);
|
|
219
147
|
this.print('===== flatten frame items =====');
|
|
220
|
-
|
|
221
148
|
return {
|
|
222
149
|
elementFrames,
|
|
223
150
|
textObjects,
|
|
224
|
-
}
|
|
151
|
+
};
|
|
225
152
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
const innerItems = frame.innerItems as RenderFrame[];
|
|
231
|
-
|
|
232
|
-
const frames: RenderFrame[] = [];
|
|
233
|
-
|
|
153
|
+
collectElementFrames(frame, level = 0) {
|
|
154
|
+
const innerItems = frame.innerItems;
|
|
155
|
+
const frames = [];
|
|
234
156
|
innerItems.forEach(item => {
|
|
235
157
|
if (item.type === RenderFrameType.Elements) {
|
|
236
158
|
frames.push(item);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
|
|
159
|
+
}
|
|
160
|
+
else if (item.type === RenderFrameType.Container) {
|
|
161
|
+
const innerFrames = this.collectElementFrames(item, level + 1);
|
|
162
|
+
frames.push(...innerFrames);
|
|
240
163
|
}
|
|
241
164
|
});
|
|
242
|
-
|
|
243
165
|
return frames;
|
|
244
166
|
}
|
|
245
|
-
|
|
246
|
-
applyFrameOffset(frame: RenderFrame, level = 0): void {
|
|
167
|
+
applyFrameOffset(frame, level = 0) {
|
|
247
168
|
this.print(level, "".padStart(level * 4), 'frame', frame.x, frame.y);
|
|
248
|
-
const innerItems = frame.innerItems
|
|
249
|
-
|
|
169
|
+
const innerItems = frame.innerItems;
|
|
250
170
|
innerItems.forEach(innerFrame => {
|
|
251
|
-
// Translate the subgraph frame by the parent frame's position
|
|
252
171
|
innerFrame.x += frame.x;
|
|
253
172
|
innerFrame.y += frame.y;
|
|
254
|
-
|
|
255
173
|
if (innerFrame.type === RenderFrameType.Elements) {
|
|
256
|
-
this.print(level, "".padStart(level * 4), 'element frame',
|
|
257
|
-
innerFrame.x, innerFrame.y);
|
|
258
|
-
|
|
174
|
+
this.print(level, "".padStart(level * 4), 'element frame', innerFrame.x, innerFrame.y);
|
|
259
175
|
innerFrame.innerItems.forEach(item2 => {
|
|
260
176
|
item2.x += innerFrame.x - innerFrame.translateX;
|
|
261
177
|
item2.y += innerFrame.y - innerFrame.translateY;
|
|
262
178
|
});
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
this.print(level, "".padStart(level * 4), 'container frame',
|
|
266
|
-
innerFrame.x, innerFrame.y);
|
|
267
|
-
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
this.print(level, "".padStart(level * 4), 'container frame', innerFrame.x, innerFrame.y);
|
|
268
182
|
this.applyFrameOffset(innerFrame, level + 1);
|
|
269
183
|
}
|
|
270
184
|
});
|
|
271
185
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
// Recursively walk through the frame's inner items and lay them out
|
|
275
|
-
// depending on their bounds and position in the parent frame.
|
|
276
|
-
|
|
277
|
-
const innerFrames = frame.innerItems as RenderFrame[];
|
|
186
|
+
placeAndSizeFrame(frame, level = 0) {
|
|
187
|
+
const innerFrames = frame.innerItems;
|
|
278
188
|
const gridSize = 20;
|
|
279
|
-
|
|
280
189
|
let accumX = 0;
|
|
281
190
|
let accumY = 0;
|
|
282
|
-
|
|
283
|
-
// This is used to determine the final bounds of this frame
|
|
284
191
|
const boundPoints = [];
|
|
285
|
-
|
|
286
|
-
// First pass collects the size of all inner frames
|
|
287
192
|
const frameSizes = innerFrames.map(innerFrame => {
|
|
288
193
|
if (innerFrame.type === RenderFrameType.Elements) {
|
|
289
|
-
|
|
290
|
-
// upper left corner.
|
|
291
|
-
innerFrame.bounds = resizeToNearestGrid(
|
|
292
|
-
innerFrame.bounds, gridSize);
|
|
293
|
-
|
|
194
|
+
innerFrame.bounds = (0, utils_js_1.resizeToNearestGrid)(innerFrame.bounds, gridSize);
|
|
294
195
|
innerFrame.translateX = innerFrame.bounds.xmin;
|
|
295
196
|
innerFrame.translateY = innerFrame.bounds.ymin;
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
// If this is a container frame, then apply the same strategy
|
|
299
|
-
// to size the inner items of this frame.
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
300
199
|
this.placeAndSizeFrame(innerFrame, level + 1);
|
|
301
200
|
}
|
|
302
|
-
|
|
303
201
|
return innerFrame.bounds;
|
|
304
202
|
});
|
|
305
|
-
|
|
306
|
-
// Find the largest width (should already be aligned to grid size).
|
|
307
203
|
const maxWidth = Math.max(...frameSizes.map(item => {
|
|
308
|
-
const { width } = getBoundsSize(item);
|
|
204
|
+
const { width } = (0, utils_js_1.getBoundsSize)(item);
|
|
309
205
|
return width;
|
|
310
206
|
}));
|
|
311
|
-
|
|
312
207
|
let accumRowWidth = 0;
|
|
313
208
|
let titleFrameWidth = null;
|
|
314
|
-
|
|
315
209
|
const inRowShouldCenterInnerFrames = true;
|
|
316
|
-
|
|
317
|
-
if (frame.direction === FramePlotDirection.Row) {
|
|
318
|
-
|
|
319
|
-
// When plot direction is row, then sum all inner frame widths.
|
|
210
|
+
if (frame.direction === Frame_js_1.FramePlotDirection.Row) {
|
|
320
211
|
accumRowWidth = frameSizes.reduce((accum, item, index) => {
|
|
321
|
-
const { width } = getBoundsSize(item);
|
|
322
|
-
|
|
323
|
-
if ((frame.innerItems[index] as RenderFrame).containsTitle){
|
|
324
|
-
// If frame contains title, then skip it for
|
|
325
|
-
// the width calculation
|
|
212
|
+
const { width } = (0, utils_js_1.getBoundsSize)(item);
|
|
213
|
+
if (frame.innerItems[index].containsTitle) {
|
|
326
214
|
titleFrameWidth = width;
|
|
327
215
|
return accum;
|
|
328
216
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
((index + 1 < frameSizes.length) ? frame.gap: 0);
|
|
217
|
+
return accum + width +
|
|
218
|
+
((index + 1 < frameSizes.length) ? frame.gap : 0);
|
|
332
219
|
}, 0);
|
|
333
|
-
|
|
334
|
-
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
335
222
|
accumRowWidth = maxWidth;
|
|
336
223
|
}
|
|
337
|
-
|
|
338
|
-
// Always start arranging inner frames (excluding frame with title)
|
|
339
|
-
// from the top left corner.
|
|
340
224
|
const offsetX = frame.padding;
|
|
341
225
|
const offsetY = frame.padding;
|
|
342
|
-
|
|
343
226
|
let centeredOffsetX = 0;
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
let widthForTitle: number;
|
|
347
|
-
|
|
348
|
-
if (titleFrameWidth > accumRowWidth){
|
|
227
|
+
let widthForTitle;
|
|
228
|
+
if (titleFrameWidth > accumRowWidth) {
|
|
349
229
|
widthForTitle = titleFrameWidth;
|
|
350
|
-
}
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
351
232
|
widthForTitle = accumRowWidth;
|
|
352
233
|
}
|
|
353
|
-
|
|
354
|
-
if (frame.direction === FramePlotDirection.Row &&
|
|
234
|
+
if (frame.direction === Frame_js_1.FramePlotDirection.Row &&
|
|
355
235
|
inRowShouldCenterInnerFrames &&
|
|
356
236
|
titleFrameWidth !== null && titleFrameWidth > accumRowWidth) {
|
|
357
|
-
|
|
358
|
-
centeredOffsetX = toNearestGrid(titleFrameWidth / 2 - accumRowWidth / 2, gridSize);
|
|
237
|
+
centeredOffsetX = (0, utils_js_1.toNearestGrid)(titleFrameWidth / 2 - accumRowWidth / 2, gridSize);
|
|
359
238
|
}
|
|
360
|
-
|
|
361
|
-
// Second pass arranges the items and sets the height
|
|
362
239
|
innerFrames.forEach(innerFrame => {
|
|
363
|
-
|
|
364
|
-
const { width: frameWidth, height: frameHeight }
|
|
365
|
-
= getBoundsSize(innerFrame.bounds);
|
|
366
|
-
|
|
240
|
+
const { width: frameWidth, height: frameHeight } = (0, utils_js_1.getBoundsSize)(innerFrame.bounds);
|
|
367
241
|
if (innerFrame.containsTitle) {
|
|
368
|
-
innerFrame.x = offsetX + accumX + toNearestGrid(widthForTitle / 2 - frameWidth / 2, gridSize);
|
|
242
|
+
innerFrame.x = offsetX + accumX + (0, utils_js_1.toNearestGrid)(widthForTitle / 2 - frameWidth / 2, gridSize);
|
|
369
243
|
innerFrame.y = offsetY + accumY;
|
|
370
244
|
accumY += (frameHeight + frame.gap);
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
if (frame.direction === FramePlotDirection.Column) {
|
|
374
|
-
|
|
375
|
-
innerFrame.x = offsetX + accumX + toNearestGrid(maxWidth / 2 - frameWidth / 2, gridSize);
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
if (frame.direction === Frame_js_1.FramePlotDirection.Column) {
|
|
248
|
+
innerFrame.x = offsetX + accumX + (0, utils_js_1.toNearestGrid)(maxWidth / 2 - frameWidth / 2, gridSize);
|
|
376
249
|
innerFrame.y = offsetY + accumY;
|
|
377
|
-
|
|
378
250
|
accumY += (frameHeight + frame.gap);
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
// Align to the top?
|
|
251
|
+
}
|
|
252
|
+
else if (frame.direction === Frame_js_1.FramePlotDirection.Row) {
|
|
382
253
|
innerFrame.x = offsetX + centeredOffsetX + accumX;
|
|
383
|
-
innerFrame.y = offsetY + accumY;
|
|
384
|
-
|
|
254
|
+
innerFrame.y = offsetY + accumY;
|
|
385
255
|
accumX += (frameWidth + frame.gap);
|
|
386
256
|
}
|
|
387
257
|
}
|
|
388
|
-
|
|
389
|
-
boundPoints.push(
|
|
390
|
-
[innerFrame.x, innerFrame.y],
|
|
391
|
-
[innerFrame.x + frameWidth, innerFrame.y + frameHeight]
|
|
392
|
-
);
|
|
258
|
+
boundPoints.push([innerFrame.x, innerFrame.y], [innerFrame.x + frameWidth, innerFrame.y + frameHeight]);
|
|
393
259
|
});
|
|
394
|
-
|
|
395
|
-
// Determine the bounds based on the points. The points should already
|
|
396
|
-
// be aligned to the grid, add the frame padding to expand the bounds correctly.
|
|
397
|
-
frame.bounds = resizeBounds(getBoundsFromPoints(boundPoints),
|
|
398
|
-
frame.padding);
|
|
260
|
+
frame.bounds = (0, utils_js_1.resizeBounds)(getBoundsFromPoints(boundPoints), frame.padding);
|
|
399
261
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
this.print(level, "".padStart(level * 4), 'frame, items:',
|
|
403
|
-
frame.innerItems.length);
|
|
404
|
-
|
|
262
|
+
dumpFrame(frame, level = 0) {
|
|
263
|
+
this.print(level, "".padStart(level * 4), 'frame, items:', frame.innerItems.length);
|
|
405
264
|
frame.innerItems.forEach(item => {
|
|
406
|
-
|
|
407
|
-
item = item as RenderFrame;
|
|
408
|
-
|
|
265
|
+
item = item;
|
|
409
266
|
if (item.type === RenderFrameType.Elements) {
|
|
410
|
-
this.print(level, "".padStart(level * 4),
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
}
|
|
267
|
+
this.print(level, "".padStart(level * 4), 'element frame, items:', item.innerItems.map(item => {
|
|
268
|
+
if (item instanceof RenderComponent) {
|
|
269
|
+
return item.component.instanceName;
|
|
270
|
+
}
|
|
271
|
+
else if (item instanceof RenderWire) {
|
|
272
|
+
return getWireName(item.id);
|
|
273
|
+
}
|
|
274
|
+
return null;
|
|
275
|
+
}));
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
420
278
|
this.print(level, "".padStart(level * 4), 'container');
|
|
421
|
-
this.dumpFrame(
|
|
279
|
+
this.dumpFrame(item, level + 1);
|
|
422
280
|
}
|
|
423
281
|
});
|
|
424
282
|
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
frame: RenderFrame, level = 0): {
|
|
428
|
-
elementFrames: RenderFrame[],
|
|
429
|
-
textObjects: RenderText[]
|
|
430
|
-
} {
|
|
431
|
-
|
|
432
|
-
const ignoreItems: string[] = [];
|
|
283
|
+
prepareFrames(graph, subgraphInfo, frame, level = 0) {
|
|
284
|
+
const ignoreItems = [];
|
|
433
285
|
const textObjects = [];
|
|
434
286
|
const elementFrames = [];
|
|
435
|
-
|
|
436
287
|
frame.innerItems = frame.innerItems.reduce((accum, item) => {
|
|
437
288
|
if (item instanceof RenderFrame) {
|
|
438
|
-
|
|
439
|
-
// elements into element frames.
|
|
440
|
-
const objects =
|
|
441
|
-
this.prepareFrames(graph, subgraphInfo, item, level + 1);
|
|
289
|
+
const objects = this.prepareFrames(graph, subgraphInfo, item, level + 1);
|
|
442
290
|
textObjects.push(...objects.textObjects);
|
|
443
291
|
elementFrames.push(...objects.elementFrames);
|
|
444
|
-
|
|
445
292
|
accum.push(item);
|
|
446
|
-
}
|
|
293
|
+
}
|
|
294
|
+
else if (item instanceof RenderComponent) {
|
|
447
295
|
const instanceName = item.component.instanceName;
|
|
448
|
-
|
|
449
296
|
if (ignoreItems.indexOf(instanceName) === -1) {
|
|
450
|
-
// Only if not ignored already, then create the elements
|
|
451
|
-
// frame for the subgraph containing the instance.
|
|
452
297
|
const subgraph = subgraphInfo.find(item => {
|
|
453
298
|
return item.components.indexOf(instanceName) !== -1;
|
|
454
299
|
});
|
|
455
|
-
|
|
456
300
|
if (subgraph !== undefined) {
|
|
457
|
-
const tmpFrame = new RenderFrame(new Frame(-2),
|
|
458
|
-
RenderFrameType.Elements);
|
|
301
|
+
const tmpFrame = new RenderFrame(new Frame_js_1.Frame(-2), RenderFrameType.Elements);
|
|
459
302
|
tmpFrame.subgraphId = instanceName;
|
|
460
|
-
tmpFrame.innerItems =
|
|
303
|
+
tmpFrame.innerItems =
|
|
461
304
|
subgraph.components.map(instanceName => {
|
|
462
305
|
const [, component,] = graph.node(instanceName);
|
|
463
306
|
return component;
|
|
464
307
|
});
|
|
465
|
-
|
|
466
|
-
// Set the size of the element frame to be the size of
|
|
467
|
-
// the subgraph
|
|
468
308
|
tmpFrame.bounds = subgraph.bounds;
|
|
469
309
|
ignoreItems.push(...subgraph.components);
|
|
470
|
-
|
|
471
310
|
accum.push(tmpFrame);
|
|
472
311
|
elementFrames.push(tmpFrame);
|
|
473
|
-
}
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
474
314
|
throw `Could not find subgraph for ${instanceName}`;
|
|
475
315
|
}
|
|
476
316
|
}
|
|
477
317
|
}
|
|
478
|
-
|
|
479
318
|
return accum;
|
|
480
|
-
}, []
|
|
481
|
-
|
|
482
|
-
// If the frame has a title specified, then this is added as an
|
|
483
|
-
// element frame.
|
|
319
|
+
}, []);
|
|
484
320
|
if (frame.type === RenderFrameType.Container) {
|
|
485
321
|
const frameObject = frame.frame;
|
|
486
|
-
if (frameObject.parameters.has(FrameParamKeys.Title)) {
|
|
487
|
-
const title =
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
// Add the element frame containing the text item
|
|
491
|
-
const tmpFrame = new RenderFrame(new Frame(-2),
|
|
492
|
-
RenderFrameType.Elements);
|
|
493
|
-
|
|
494
|
-
// Mark this render frame as containing only the title element,
|
|
495
|
-
// this is used later during inner item placement of the frame.
|
|
322
|
+
if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Title)) {
|
|
323
|
+
const title = frameObject.parameters.get(Frame_js_1.FrameParamKeys.Title);
|
|
324
|
+
const tmpFrame = new RenderFrame(new Frame_js_1.Frame(-2), RenderFrameType.Elements);
|
|
496
325
|
tmpFrame.containsTitle = true;
|
|
497
|
-
|
|
498
326
|
tmpFrame.subgraphId = title.replace(/\s/g, "_");
|
|
499
|
-
|
|
500
327
|
const textObject = new RenderText(title);
|
|
501
328
|
textObject.fontSize = 16;
|
|
502
329
|
textObject.fontWeight = 'bold';
|
|
503
|
-
|
|
504
330
|
textObject.symbol.refreshDrawing();
|
|
505
331
|
tmpFrame.innerItems.push(textObject);
|
|
506
|
-
|
|
507
332
|
const tmpBox = textObject.symbol.drawing.getBoundingBox();
|
|
508
333
|
tmpFrame.bounds = {
|
|
509
334
|
xmin: tmpBox.start[0],
|
|
@@ -511,786 +336,517 @@ export class LayoutEngine {
|
|
|
511
336
|
xmax: tmpBox.start[0] + tmpBox.width,
|
|
512
337
|
ymax: tmpBox.start[1] + tmpBox.height
|
|
513
338
|
};
|
|
514
|
-
|
|
515
339
|
textObject.x = 0;
|
|
516
340
|
textObject.y = 0;
|
|
517
|
-
|
|
518
|
-
// Add as first element
|
|
519
341
|
frame.innerItems.splice(0, 0, tmpFrame);
|
|
520
|
-
|
|
521
342
|
this.printLevel(level, frame, 'added text', tmpFrame);
|
|
522
|
-
|
|
523
343
|
textObjects.push(textObject);
|
|
524
|
-
|
|
525
|
-
// Add frame to the start
|
|
526
344
|
elementFrames.splice(0, 0, tmpFrame);
|
|
527
345
|
}
|
|
528
346
|
}
|
|
529
|
-
|
|
530
347
|
return {
|
|
531
348
|
elementFrames,
|
|
532
349
|
textObjects,
|
|
533
|
-
}
|
|
350
|
+
};
|
|
534
351
|
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
containerFrames: RenderFrame[],
|
|
540
|
-
} {
|
|
541
|
-
// Based on the sequence of actions, generate a graph that links
|
|
542
|
-
// the nodes (components and wires)
|
|
543
|
-
|
|
544
|
-
let previousNode: string | null = null;
|
|
545
|
-
let previousPin: number | null = null;
|
|
546
|
-
|
|
547
|
-
const graph = new graphlib.Graph({
|
|
352
|
+
generateLayoutGraph(sequence, nets) {
|
|
353
|
+
let previousNode = null;
|
|
354
|
+
let previousPin = null;
|
|
355
|
+
const graph = new graphlib_1.Graph({
|
|
548
356
|
directed: false,
|
|
549
357
|
compound: true,
|
|
550
358
|
});
|
|
551
|
-
|
|
552
359
|
this.print('sequence length:', sequence.length);
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
const baseRenderFrame = new RenderFrame(new Frame(-1));
|
|
557
|
-
|
|
558
|
-
const frameStack: RenderFrame[] = [baseRenderFrame];
|
|
559
|
-
const containerFrames: RenderFrame[] = [baseRenderFrame];
|
|
560
|
-
|
|
561
|
-
// Based on the sequence steps create all the graph connections first and
|
|
562
|
-
// determine the size of all items
|
|
360
|
+
const baseRenderFrame = new RenderFrame(new Frame_js_1.Frame(-1));
|
|
361
|
+
const frameStack = [baseRenderFrame];
|
|
362
|
+
const containerFrames = [baseRenderFrame];
|
|
563
363
|
for (let i = 0; i < sequence.length; i++) {
|
|
564
|
-
|
|
565
364
|
const action = sequence[i][0];
|
|
566
|
-
let tmpComponent
|
|
567
|
-
|
|
568
|
-
// Component related actions
|
|
569
|
-
if (action === SequenceAction.At || action === SequenceAction.To) {
|
|
365
|
+
let tmpComponent;
|
|
366
|
+
if (action === ExecutionScope_js_1.SequenceAction.At || action === ExecutionScope_js_1.SequenceAction.To) {
|
|
570
367
|
this.print(...sequence[i]);
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
const component = sequence[i][1] as ClassComponent;
|
|
574
|
-
const pin = sequence[i][2] as number;
|
|
575
|
-
|
|
368
|
+
const component = sequence[i][1];
|
|
369
|
+
const pin = sequence[i][2];
|
|
576
370
|
const tmpInstanceName = component.instanceName;
|
|
577
|
-
|
|
578
371
|
if (!graph.hasNode(tmpInstanceName)) {
|
|
579
372
|
this.print('create instance', tmpInstanceName);
|
|
580
|
-
|
|
581
|
-
let
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
let tmpSymbol: SymbolGraphic;
|
|
585
|
-
|
|
586
|
-
// If it is a gnd net, then use the gnd symbol
|
|
587
|
-
if (displayProp === null &&
|
|
588
|
-
component.parameters.get(ParamKeys.net_name) === GlobalNames.gnd) {
|
|
589
|
-
|
|
373
|
+
let { displayProp = null, widthProp = null, typeProp = null } = component;
|
|
374
|
+
let tmpSymbol;
|
|
375
|
+
if (displayProp === null &&
|
|
376
|
+
component.parameters.get(globals_js_1.ParamKeys.net_name) === globals_js_1.GlobalNames.gnd) {
|
|
590
377
|
displayProp = 'gnd';
|
|
591
378
|
}
|
|
592
|
-
|
|
593
379
|
if (displayProp !== null) {
|
|
594
|
-
if (displayProp instanceof SymbolDrawing){
|
|
595
|
-
tmpSymbol = new SymbolPlaceholder(displayProp);
|
|
380
|
+
if (displayProp instanceof draw_symbols_js_1.SymbolDrawing) {
|
|
381
|
+
tmpSymbol = new draw_symbols_js_1.SymbolPlaceholder(displayProp);
|
|
596
382
|
tmpSymbol.drawing.logger = this.logger;
|
|
597
|
-
|
|
598
|
-
} else if (typeof displayProp === "string"){
|
|
599
|
-
tmpSymbol = SymbolFactory(displayProp);
|
|
600
383
|
}
|
|
601
|
-
|
|
384
|
+
else if (typeof displayProp === "string") {
|
|
385
|
+
tmpSymbol = (0, draw_symbols_js_1.SymbolFactory)(displayProp);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
602
389
|
const symbolPinDefinitions = generateLayoutPinDefinition(component);
|
|
603
|
-
tmpSymbol = new SymbolCustom(symbolPinDefinitions);
|
|
390
|
+
tmpSymbol = new draw_symbols_js_1.SymbolCustom(symbolPinDefinitions);
|
|
604
391
|
}
|
|
605
|
-
|
|
606
392
|
applyComponentParamsToSymbol(typeProp, component, tmpSymbol);
|
|
607
|
-
|
|
608
|
-
// Set rotation of object
|
|
609
393
|
let didSetAngle = false;
|
|
610
|
-
|
|
611
394
|
if (component.parameters.has('angle')) {
|
|
612
395
|
didSetAngle = true;
|
|
613
|
-
tmpSymbol.angle = component.parameters.get('angle')
|
|
396
|
+
tmpSymbol.angle = component.parameters.get('angle');
|
|
397
|
+
}
|
|
398
|
+
if (component.parameters.has('flipX')) {
|
|
399
|
+
tmpSymbol.flipX =
|
|
400
|
+
component.parameters.get('flipX');
|
|
401
|
+
}
|
|
402
|
+
if (component.parameters.has('flipY')) {
|
|
403
|
+
tmpSymbol.flipY =
|
|
404
|
+
component.parameters.get('flipY');
|
|
614
405
|
}
|
|
615
|
-
|
|
616
|
-
if (tmpSymbol instanceof SymbolCustom && widthProp){
|
|
406
|
+
if (tmpSymbol instanceof draw_symbols_js_1.SymbolCustom && widthProp) {
|
|
617
407
|
tmpSymbol.bodyWidth = widthProp;
|
|
618
408
|
}
|
|
619
|
-
|
|
620
|
-
if (!didSetAngle && component.parameters.has('_addDirection')){
|
|
621
|
-
// If there is an _addDirection specified, then the angle
|
|
622
|
-
// must be updated accordingly. If angle is already set,
|
|
623
|
-
// then skip this.
|
|
409
|
+
if (!didSetAngle && component.parameters.has('_addDirection')) {
|
|
624
410
|
tmpSymbol.refreshDrawing(false);
|
|
625
|
-
|
|
626
|
-
tmpSymbol.angle = calculateSymbolAngle(
|
|
627
|
-
tmpSymbol,
|
|
628
|
-
component.parameters.get('_addPin') as number,
|
|
629
|
-
component.parameters.get('_addDirection') as string,
|
|
630
|
-
);
|
|
411
|
+
tmpSymbol.angle = calculateSymbolAngle(tmpSymbol, component.parameters.get('_addPin'), component.parameters.get('_addDirection'));
|
|
631
412
|
}
|
|
632
|
-
|
|
633
|
-
// Draw symbol in memory to determine the size/bounds.
|
|
634
413
|
tmpSymbol.refreshDrawing();
|
|
635
|
-
|
|
636
414
|
const { width: useWidth, height: useHeight } = tmpSymbol.size();
|
|
637
|
-
|
|
638
415
|
tmpComponent = new RenderComponent(component, useWidth, useHeight);
|
|
639
416
|
tmpComponent.symbol = tmpSymbol;
|
|
640
|
-
|
|
641
|
-
// Record the sequence number to determine priority
|
|
642
417
|
graph.setNode(tmpInstanceName, [RenderItemType.Component, tmpComponent, i]);
|
|
643
|
-
|
|
644
|
-
// All components must belong within a frame.
|
|
645
|
-
const currentFrame = frameStack[frameStack.length-1];
|
|
418
|
+
const currentFrame = frameStack[frameStack.length - 1];
|
|
646
419
|
currentFrame && currentFrame.innerItems.push(tmpComponent);
|
|
647
420
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
this.setGraphEdge(graph, previousNode, tmpInstanceName,
|
|
651
|
-
makeEdgeValue(previousNode, previousPin, tmpInstanceName, pin, i));
|
|
421
|
+
if (action === ExecutionScope_js_1.SequenceAction.To) {
|
|
422
|
+
this.setGraphEdge(graph, previousNode, tmpInstanceName, makeEdgeValue(previousNode, previousPin, tmpInstanceName, pin, i));
|
|
652
423
|
}
|
|
653
|
-
|
|
654
|
-
previousNode = tmpInstanceName
|
|
424
|
+
previousNode = tmpInstanceName;
|
|
655
425
|
previousPin = pin;
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
const [, wireId, wireSegments] =
|
|
660
|
-
sequence[i] as [SequenceAction.Wire, number, WireSegment[]];
|
|
661
|
-
|
|
426
|
+
}
|
|
427
|
+
else if (action === ExecutionScope_js_1.SequenceAction.Wire) {
|
|
428
|
+
const [, wireId, wireSegments] = sequence[i];
|
|
662
429
|
const wire = new RenderWire(0, 0, wireSegments);
|
|
663
430
|
wire.id = wireId;
|
|
664
431
|
let useNetName = null;
|
|
665
|
-
|
|
666
432
|
if (previousNode !== null) {
|
|
667
433
|
const [prevNodeType, prevNodeItem] = graph.node(previousNode);
|
|
668
434
|
if (prevNodeType === RenderItemType.Component) {
|
|
669
|
-
// Find the net of the wire
|
|
670
435
|
const matchingItem = nets.find(([comp, pin]) => {
|
|
671
436
|
return comp.instanceName === previousNode && pin === previousPin;
|
|
672
437
|
});
|
|
673
|
-
|
|
674
438
|
useNetName = matchingItem !== undefined ? matchingItem[2].name : null;
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
useNetName =
|
|
439
|
+
}
|
|
440
|
+
else if (prevNodeType === RenderItemType.Wire) {
|
|
441
|
+
useNetName = prevNodeItem.netName;
|
|
678
442
|
}
|
|
679
443
|
}
|
|
680
|
-
|
|
681
444
|
wire.netName = useNetName;
|
|
682
445
|
const wireName = getWireName(wire.id);
|
|
683
|
-
|
|
684
|
-
// Record the sequence number to determine priority
|
|
685
446
|
graph.setNode(wireName, [RenderItemType.Wire, wire, i]);
|
|
686
|
-
|
|
687
|
-
// Connect previous node to pin:0 of the wire
|
|
688
|
-
this.setGraphEdge(graph, previousNode, wireName,
|
|
689
|
-
makeEdgeValue(previousNode, previousPin, wireName, 0, i));
|
|
690
|
-
|
|
447
|
+
this.setGraphEdge(graph, previousNode, wireName, makeEdgeValue(previousNode, previousPin, wireName, 0, i));
|
|
691
448
|
previousNode = wireName;
|
|
692
449
|
previousPin = 1;
|
|
693
|
-
|
|
694
450
|
const wireSegmentsInfo = wireSegments.map(item => {
|
|
695
|
-
const tmp
|
|
696
|
-
direction: string,
|
|
697
|
-
value: number,
|
|
698
|
-
valueXY?: [x: number, y: number],
|
|
699
|
-
until?: [instanceName: string, pin: number]
|
|
700
|
-
} = {
|
|
451
|
+
const tmp = {
|
|
701
452
|
direction: item.direction,
|
|
702
453
|
value: item.value,
|
|
703
454
|
};
|
|
704
|
-
|
|
705
455
|
if (item.valueXY) {
|
|
706
456
|
tmp.valueXY = item.valueXY;
|
|
707
457
|
}
|
|
708
|
-
|
|
709
458
|
if (item.until) {
|
|
710
459
|
tmp.until = [item.until[0].toString(), item.until[1]];
|
|
711
460
|
}
|
|
712
|
-
|
|
713
461
|
return tmp;
|
|
714
462
|
});
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
} else if (action === SequenceAction.WireJump) {
|
|
463
|
+
this.print(ExecutionScope_js_1.SequenceAction.Wire, wireId, JSON.stringify(wireSegmentsInfo));
|
|
464
|
+
}
|
|
465
|
+
else if (action === ExecutionScope_js_1.SequenceAction.WireJump) {
|
|
720
466
|
this.print(...sequence[i]);
|
|
721
|
-
const wireId = sequence[i][1]
|
|
467
|
+
const wireId = sequence[i][1];
|
|
722
468
|
const wireName = getWireName(wireId);
|
|
723
|
-
|
|
724
469
|
let wirePin = 1;
|
|
725
|
-
|
|
726
470
|
if (sequence[i].length === 3) {
|
|
727
|
-
wirePin = sequence[i][2]
|
|
471
|
+
wirePin = sequence[i][2];
|
|
728
472
|
}
|
|
729
|
-
|
|
730
473
|
previousNode = wireName;
|
|
731
|
-
previousPin = wirePin;
|
|
732
|
-
}
|
|
474
|
+
previousPin = wirePin;
|
|
475
|
+
}
|
|
476
|
+
else if (action === ExecutionScope_js_1.SequenceAction.Frame) {
|
|
733
477
|
const [, frameObject, frameAction] = sequence[i];
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
const prevFrame = frameStack[frameStack.length-1];
|
|
737
|
-
|
|
478
|
+
if (frameAction === ExecutionScope_js_1.FrameAction.Enter) {
|
|
479
|
+
const prevFrame = frameStack[frameStack.length - 1];
|
|
738
480
|
const newFrame = new RenderFrame(frameObject);
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
frameObject.parameters.get(FrameParamKeys.Direction);
|
|
481
|
+
if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Direction)) {
|
|
482
|
+
newFrame.direction =
|
|
483
|
+
frameObject.parameters.get(Frame_js_1.FrameParamKeys.Direction);
|
|
743
484
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
frameObject.parameters.get(FrameParamKeys.Padding);
|
|
485
|
+
if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Padding)) {
|
|
486
|
+
newFrame.padding =
|
|
487
|
+
frameObject.parameters.get(Frame_js_1.FrameParamKeys.Padding);
|
|
748
488
|
}
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
frameObject.parameters.get(FrameParamKeys.Border);
|
|
489
|
+
if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Border)) {
|
|
490
|
+
newFrame.borderWidth =
|
|
491
|
+
frameObject.parameters.get(Frame_js_1.FrameParamKeys.Border);
|
|
753
492
|
}
|
|
754
|
-
|
|
755
493
|
containerFrames.push(newFrame);
|
|
756
494
|
frameStack.push(newFrame);
|
|
757
|
-
|
|
758
|
-
// If the previous frame exists, then add the new frame
|
|
759
|
-
// into the inner items of the previous frame. This allows
|
|
760
|
-
// the frame hierarchy to be tracked.
|
|
761
495
|
prevFrame && prevFrame.innerItems.push(newFrame);
|
|
762
|
-
|
|
763
|
-
|
|
496
|
+
}
|
|
497
|
+
else if (frameAction === ExecutionScope_js_1.FrameAction.Exit) {
|
|
764
498
|
frameStack.pop();
|
|
765
499
|
}
|
|
766
500
|
}
|
|
767
501
|
}
|
|
768
|
-
|
|
769
502
|
return {
|
|
770
503
|
graph,
|
|
771
504
|
containerFrames,
|
|
772
|
-
}
|
|
505
|
+
};
|
|
773
506
|
}
|
|
774
|
-
|
|
775
|
-
setGraphEdge(graph: graphlib.Graph, node1: string, node2: string,
|
|
776
|
-
edgeValue: EdgeValue): void {
|
|
507
|
+
setGraphEdge(graph, node1, node2, edgeValue) {
|
|
777
508
|
graph.setEdge(node1, node2, edgeValue);
|
|
778
509
|
}
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
// Layouts out all nodes within a subgraph and determines the size
|
|
783
|
-
// of the subgraph.
|
|
784
|
-
|
|
785
|
-
const subGraphs = graphlib.alg.components(graph);
|
|
510
|
+
sizeSubGraphs(graph) {
|
|
511
|
+
const subGraphs = graphlib_1.alg.components(graph);
|
|
786
512
|
const subGraphsStarts = [];
|
|
787
|
-
|
|
788
513
|
this.print('===== placing subgraphs =====');
|
|
789
514
|
this.print('number of subgraphs: ', subGraphs.length);
|
|
790
|
-
|
|
791
|
-
const subgraphInfo: SubGraphInfo[] = [];
|
|
792
|
-
|
|
793
|
-
// Find the starting point of the graph
|
|
515
|
+
const subgraphInfo = [];
|
|
794
516
|
subGraphs.forEach(innerGraph => {
|
|
795
|
-
// Find node with the lowest sequence number and used
|
|
796
|
-
// as the starting node
|
|
797
|
-
|
|
798
517
|
let smallestNodeIdLevel = Number.POSITIVE_INFINITY;
|
|
799
|
-
let smallestNodeId
|
|
800
|
-
|
|
518
|
+
let smallestNodeId = null;
|
|
801
519
|
innerGraph.forEach(nodeId => {
|
|
802
520
|
const [, , sequenceId] = graph.node(nodeId);
|
|
803
|
-
|
|
804
521
|
if (sequenceId < smallestNodeIdLevel) {
|
|
805
522
|
smallestNodeIdLevel = sequenceId;
|
|
806
523
|
smallestNodeId = nodeId;
|
|
807
524
|
}
|
|
808
525
|
});
|
|
809
|
-
|
|
810
526
|
subGraphsStarts.push(smallestNodeId);
|
|
811
527
|
});
|
|
812
|
-
|
|
813
|
-
|
|
814
528
|
subGraphsStarts.forEach((nodeId, index) => {
|
|
815
529
|
const innerGraph = subGraphs[index];
|
|
816
|
-
|
|
817
530
|
this.print('walk and place nodes in subgraph at index', index);
|
|
818
531
|
this.print('starting node', nodeId);
|
|
819
|
-
|
|
820
532
|
this.walkAndPlaceGraph(graph, nodeId, innerGraph);
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
const renderItems: (RenderComponent | RenderText)[] = [];
|
|
824
|
-
|
|
825
|
-
const wires: RenderWire[] = [];
|
|
826
|
-
|
|
533
|
+
const renderItems = [];
|
|
534
|
+
const wires = [];
|
|
827
535
|
innerGraph.forEach(nodeId => {
|
|
828
536
|
const [nodeType, item,] = graph.node(nodeId);
|
|
829
537
|
if (nodeType === RenderItemType.Component) {
|
|
830
538
|
renderItems.push(item);
|
|
831
|
-
}
|
|
539
|
+
}
|
|
540
|
+
else if (nodeType === RenderItemType.Wire) {
|
|
832
541
|
wires.push(item);
|
|
833
542
|
}
|
|
834
543
|
});
|
|
835
|
-
|
|
836
|
-
// Get the existing bounds
|
|
837
544
|
const bounds = getBounds(renderItems, wires, [], []);
|
|
838
|
-
|
|
839
545
|
subgraphInfo.push({
|
|
840
546
|
firstNodeId: nodeId,
|
|
841
547
|
components: innerGraph,
|
|
842
548
|
bounds,
|
|
843
549
|
});
|
|
844
550
|
});
|
|
845
|
-
|
|
846
|
-
// For each subgraph, find the bounds of the subgraph
|
|
847
551
|
return subgraphInfo;
|
|
848
552
|
}
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
walkAndPlaceGraph(graph: graphlib.Graph, firstNodeId: string,
|
|
852
|
-
subgraphNodes: string[]): void {
|
|
853
|
-
// Go through all edges in the main graph and for each edge that contains
|
|
854
|
-
// nodes within the subgraph, then try and place the nodes in the subgraph.
|
|
855
|
-
|
|
553
|
+
walkAndPlaceGraph(graph, firstNodeId, subgraphNodes) {
|
|
856
554
|
const allEdges = graph.edges();
|
|
857
|
-
|
|
858
555
|
const subgraphEdges = allEdges.reduce((accum, edge) => {
|
|
859
556
|
const { v } = edge;
|
|
860
|
-
// If the subgraph nodes v, then the edge is within the subgraph.
|
|
861
|
-
// No need to check w, since w must also be in the subgraph.
|
|
862
557
|
if (subgraphNodes.indexOf(v) !== -1) {
|
|
863
558
|
accum.push(edge);
|
|
864
559
|
}
|
|
865
560
|
return accum;
|
|
866
|
-
}, []
|
|
867
|
-
|
|
868
|
-
if (this.placeSubgraphVersion === 1){
|
|
561
|
+
}, []);
|
|
562
|
+
if (this.placeSubgraphVersion === 1) {
|
|
869
563
|
this.placeSubgraph(graph, firstNodeId, subgraphEdges);
|
|
870
|
-
}
|
|
564
|
+
}
|
|
565
|
+
else if (this.placeSubgraphVersion === 2) {
|
|
871
566
|
this.placeSubgraphV2(graph, firstNodeId, subgraphEdges);
|
|
872
567
|
}
|
|
873
568
|
}
|
|
874
|
-
|
|
875
|
-
placeSubgraphV2(graph:graphlib.Graph, firstNodeId: string,
|
|
876
|
-
subgraphEdges: graphlib.Edge[]): void {
|
|
877
|
-
|
|
569
|
+
placeSubgraphV2(graph, firstNodeId, subgraphEdges) {
|
|
878
570
|
let firstNodePlaced = false;
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
// that share the same origin node. When group of nodes of overlap, they
|
|
883
|
-
// are merged together and will have the same origin node.
|
|
884
|
-
|
|
885
|
-
// Stores origin nodes. The earlier the node in this list, the
|
|
886
|
-
// higher the priority it has to be merged.
|
|
887
|
-
const originNodes: RenderItem[] = [];
|
|
888
|
-
|
|
889
|
-
// Stores the nodes that are linked to the node origin. The map key is
|
|
890
|
-
// the instance name of the origin node.
|
|
891
|
-
const originNodeGroups: Map<string, RenderItem[]> = new Map();
|
|
892
|
-
|
|
893
|
-
function findOriginNode(node: RenderItem): string | null {
|
|
571
|
+
const originNodes = [];
|
|
572
|
+
const originNodeGroups = new Map();
|
|
573
|
+
function findOriginNode(node) {
|
|
894
574
|
const keys = Array.from(originNodeGroups.keys());
|
|
895
|
-
|
|
896
575
|
for (let i = 0; i < keys.length; i++) {
|
|
897
576
|
const nodesLinkedToOrigin = originNodeGroups.get(keys[i]);
|
|
898
577
|
if (nodesLinkedToOrigin.indexOf(node) !== -1) {
|
|
899
578
|
return keys[i];
|
|
900
579
|
}
|
|
901
580
|
}
|
|
902
|
-
|
|
903
581
|
return null;
|
|
904
582
|
}
|
|
905
|
-
|
|
906
583
|
if (subgraphEdges.length === 0) {
|
|
907
|
-
|
|
908
|
-
// will not be any edges. Align the component to the grid first
|
|
909
|
-
const [, node1]: [string, RenderItem] = graph.node(firstNodeId);
|
|
910
|
-
|
|
911
|
-
// By default align pin 1 to the grid
|
|
584
|
+
const [, node1] = graph.node(firstNodeId);
|
|
912
585
|
this.placeNodeAtPosition(0, 0, node1, 1);
|
|
913
586
|
return;
|
|
914
587
|
}
|
|
915
|
-
|
|
916
588
|
subgraphEdges.forEach(edge => {
|
|
917
|
-
const [nodeId1, pin1, nodeId2, pin2]
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
const [, node1]: [string, RenderItem] = graph.node(nodeId1);
|
|
921
|
-
const [, node2]: [string, RenderItem] = graph.node(nodeId2);
|
|
922
|
-
|
|
589
|
+
const [nodeId1, pin1, nodeId2, pin2] = graph.edge(edge);
|
|
590
|
+
const [, node1] = graph.node(nodeId1);
|
|
591
|
+
const [, node2] = graph.node(nodeId2);
|
|
923
592
|
if (nodeId1 === firstNodeId && !firstNodePlaced) {
|
|
924
593
|
this.print('first node placed at origin');
|
|
925
594
|
this.placeNodeAtPosition(0, 0, node1, pin1);
|
|
926
595
|
firstNodePlaced = true;
|
|
927
596
|
node1.isFloating = false;
|
|
928
|
-
|
|
929
597
|
originNodes.push(node1);
|
|
930
598
|
originNodeGroups.set(node1.toString(), [node1]);
|
|
931
599
|
}
|
|
932
|
-
|
|
933
|
-
let
|
|
934
|
-
let
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
let floatingNodePin: number;
|
|
938
|
-
|
|
939
|
-
this.print('edge:', '[', node1, pin1, node1.isFloating, ']',
|
|
940
|
-
'[', node2, pin2, node2.isFloating, ']');
|
|
941
|
-
|
|
600
|
+
let fixedNode;
|
|
601
|
+
let fixedNodePin;
|
|
602
|
+
let floatingNode;
|
|
603
|
+
let floatingNodePin;
|
|
604
|
+
this.print('edge:', '[', node1, pin1, node1.isFloating, ']', '[', node2, pin2, node2.isFloating, ']');
|
|
942
605
|
if (!node1.isFloating && node2.isFloating) {
|
|
943
606
|
fixedNode = node1;
|
|
944
607
|
fixedNodePin = pin1;
|
|
945
|
-
|
|
946
608
|
floatingNode = node2;
|
|
947
609
|
floatingNodePin = pin2;
|
|
948
|
-
|
|
949
|
-
|
|
610
|
+
}
|
|
611
|
+
else if (node1.isFloating && !node2.isFloating) {
|
|
950
612
|
fixedNode = node2;
|
|
951
613
|
fixedNodePin = pin2;
|
|
952
|
-
|
|
953
614
|
floatingNode = node1;
|
|
954
615
|
floatingNodePin = pin1;
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
// If both nodes are floating, then set node1 as an origin node
|
|
958
|
-
// and set it as not floating.
|
|
616
|
+
}
|
|
617
|
+
else if (node1.isFloating && node2.isFloating) {
|
|
959
618
|
originNodes.push(node1);
|
|
960
619
|
originNodeGroups.set(node1.toString(), [node1]);
|
|
961
620
|
this.print('creating new origin node at', node1);
|
|
962
|
-
|
|
963
621
|
this.placeNodeAtPosition(0, 0, node1, pin1);
|
|
964
622
|
node1.isFloating = false;
|
|
965
|
-
|
|
966
623
|
fixedNode = node1;
|
|
967
624
|
fixedNodePin = pin1;
|
|
968
|
-
|
|
969
625
|
floatingNode = node2;
|
|
970
626
|
floatingNodePin = pin2;
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
// If both nodes are fixed, then check how to merge them
|
|
627
|
+
}
|
|
628
|
+
else if (!node1.isFloating && !node2.isFloating) {
|
|
974
629
|
const originNode1 = findOriginNode(node1);
|
|
975
630
|
const originNode2 = findOriginNode(node2);
|
|
976
|
-
|
|
977
631
|
this.print('both nodes are already placed, comparing origin nodes:', originNode1, originNode2);
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
this.mergeOriginNodes(
|
|
983
|
-
node1, pin1, node2, pin2,
|
|
984
|
-
originNode1, originNode2, originNodes,
|
|
985
|
-
originNodeGroups,
|
|
986
|
-
);
|
|
987
|
-
} else {
|
|
988
|
-
// If have same node, then compare their position
|
|
632
|
+
if (originNode1 !== originNode2) {
|
|
633
|
+
this.mergeOriginNodes(node1, pin1, node2, pin2, originNode1, originNode2, originNodes, originNodeGroups);
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
989
636
|
const [x1, y1] = getNodePositionAtPin(node1, pin1);
|
|
990
637
|
const [x2, y2] = getNodePositionAtPin(node2, pin2);
|
|
991
638
|
if (x1 !== x2 && y1 !== y2) {
|
|
992
639
|
if (node1 instanceof RenderWire &&
|
|
993
640
|
node2 instanceof RenderComponent) {
|
|
994
|
-
|
|
995
641
|
const refdes = node2.component.assignedRefDes;
|
|
996
642
|
this.layoutWarnings.push(`component ${refdes} may not be placed correctly`);
|
|
997
643
|
}
|
|
998
644
|
}
|
|
999
645
|
}
|
|
1000
646
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
this.print('place floating node', floatingNode, 'pin', floatingNodePin,
|
|
1004
|
-
'to', fixedNode, 'pin', fixedNodePin);
|
|
1005
|
-
|
|
647
|
+
if (fixedNode && floatingNode) {
|
|
648
|
+
this.print('place floating node', floatingNode, 'pin', floatingNodePin, 'to', fixedNode, 'pin', fixedNodePin);
|
|
1006
649
|
const [x, y] = getNodePositionAtPin(fixedNode, fixedNodePin);
|
|
1007
650
|
this.placeNodeAtPosition(x, y, floatingNode, floatingNodePin);
|
|
1008
651
|
floatingNode.isFloating = false;
|
|
1009
|
-
|
|
1010
652
|
this.print('set node as not floating:', floatingNode);
|
|
1011
|
-
|
|
1012
|
-
// Find origin of the fixed node and add the floating node
|
|
1013
|
-
// into the node origin tree.
|
|
1014
653
|
const originNode = findOriginNode(fixedNode);
|
|
1015
654
|
originNodeGroups.get(originNode).push(floatingNode);
|
|
1016
655
|
this.print('linking node', floatingNode, 'to origin node', originNode);
|
|
1017
656
|
}
|
|
1018
|
-
|
|
1019
657
|
[node1, node2].forEach(item => {
|
|
1020
|
-
if (item instanceof RenderWire && item.isEndAutoLength()){
|
|
658
|
+
if (item instanceof RenderWire && item.isEndAutoLength()) {
|
|
1021
659
|
this.print('auto length wire', item);
|
|
1022
|
-
|
|
1023
660
|
const [instance, pin] = item.getEndAuto();
|
|
1024
|
-
const [, targetNode]
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
if (targetNode.isFloating){
|
|
1028
|
-
throw "Cannot create auto wire with floating node! Wire id: " + item.id + " to node " + instance + " pin "+ pin;
|
|
661
|
+
const [, targetNode] = graph.node(instance.instanceName);
|
|
662
|
+
if (targetNode.isFloating) {
|
|
663
|
+
throw "Cannot create auto wire with floating node! Wire id: " + item.id + " to node " + instance + " pin " + pin;
|
|
1029
664
|
}
|
|
1030
|
-
|
|
1031
665
|
const [untilX, untilY] = getNodePositionAtPin(targetNode, pin);
|
|
1032
666
|
item.setEndAuto(untilX, untilY);
|
|
1033
667
|
}
|
|
1034
668
|
});
|
|
1035
|
-
|
|
1036
669
|
});
|
|
1037
670
|
}
|
|
1038
|
-
|
|
1039
|
-
mergeOriginNodes(node1: RenderItem, pin1: number,
|
|
1040
|
-
node2: RenderItem, pin2: number,
|
|
1041
|
-
originNode1: string, originNode2: string,
|
|
1042
|
-
originNodes: RenderItem[],
|
|
1043
|
-
originNodeGroups: Map<string, RenderItem[]>): void {
|
|
1044
|
-
|
|
1045
|
-
// Determine the priority of the merge
|
|
671
|
+
mergeOriginNodes(node1, pin1, node2, pin2, originNode1, originNode2, originNodes, originNodeGroups) {
|
|
1046
672
|
const originNode1Index = originNodes.findIndex(item => {
|
|
1047
673
|
return item.toString() === originNode1;
|
|
1048
674
|
});
|
|
1049
|
-
|
|
1050
675
|
const originNode2Index = originNodes.findIndex(item => {
|
|
1051
676
|
return item.toString() === originNode2;
|
|
1052
677
|
});
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
let
|
|
1057
|
-
let
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
let fixedNodePin: number;
|
|
1061
|
-
|
|
1062
|
-
let mergedNode: RenderItem;
|
|
1063
|
-
let mergedNodePin: number;
|
|
1064
|
-
|
|
1065
|
-
if (originNode1Index < originNode2Index){
|
|
678
|
+
let keepOriginNode;
|
|
679
|
+
let otherOriginNode;
|
|
680
|
+
let fixedNode;
|
|
681
|
+
let fixedNodePin;
|
|
682
|
+
let mergedNode;
|
|
683
|
+
let mergedNodePin;
|
|
684
|
+
if (originNode1Index < originNode2Index) {
|
|
1066
685
|
keepOriginNode = originNode1;
|
|
1067
686
|
otherOriginNode = originNode2;
|
|
1068
|
-
|
|
1069
687
|
fixedNode = node1;
|
|
1070
688
|
fixedNodePin = pin1;
|
|
1071
|
-
|
|
1072
689
|
mergedNode = node2;
|
|
1073
690
|
mergedNodePin = pin2;
|
|
1074
|
-
|
|
1075
|
-
|
|
691
|
+
}
|
|
692
|
+
else {
|
|
1076
693
|
keepOriginNode = originNode2;
|
|
1077
694
|
otherOriginNode = originNode1;
|
|
1078
|
-
|
|
1079
695
|
fixedNode = node2;
|
|
1080
696
|
fixedNodePin = pin2;
|
|
1081
|
-
|
|
1082
697
|
mergedNode = node1;
|
|
1083
698
|
mergedNodePin = pin1;
|
|
1084
699
|
}
|
|
1085
|
-
|
|
1086
|
-
this.print('merging origin node groups, fixed:', keepOriginNode,
|
|
1087
|
-
', other:', otherOriginNode);
|
|
1088
|
-
|
|
1089
|
-
// Find position at pin of the fixed node, at the node origin
|
|
1090
|
-
// that remains.
|
|
700
|
+
this.print('merging origin node groups, fixed:', keepOriginNode, ', other:', otherOriginNode);
|
|
1091
701
|
const [x, y] = getNodePositionAtPin(fixedNode, fixedNodePin);
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
// point. This returns the offset to the node origin.
|
|
1095
|
-
const [otherNodeOriginX, otherNodeOriginY] =
|
|
1096
|
-
getNodePositionAtPin(mergedNode, mergedNodePin);
|
|
1097
|
-
|
|
1098
|
-
const offsetX = x - otherNodeOriginX
|
|
702
|
+
const [otherNodeOriginX, otherNodeOriginY] = getNodePositionAtPin(mergedNode, mergedNodePin);
|
|
703
|
+
const offsetX = x - otherNodeOriginX;
|
|
1099
704
|
const offsetY = y - otherNodeOriginY;
|
|
1100
|
-
|
|
1101
705
|
this.print('offset of other origin:', offsetX, offsetY);
|
|
1102
|
-
|
|
1103
706
|
const otherItemsLinkedToOriginNode = originNodeGroups.get(otherOriginNode);
|
|
1104
|
-
this.print('nodes in other origin:'
|
|
1105
|
-
|
|
707
|
+
this.print('nodes in other origin:', otherItemsLinkedToOriginNode);
|
|
1106
708
|
otherItemsLinkedToOriginNode.forEach(item => {
|
|
1107
709
|
this.translateNodeBy(offsetX, offsetY, item);
|
|
1108
|
-
});
|
|
1109
|
-
|
|
1110
|
-
// Merge the list of items in other node origin into the node origin
|
|
1111
|
-
// that is kept.
|
|
710
|
+
});
|
|
1112
711
|
const newList = originNodeGroups.get(keepOriginNode)
|
|
1113
712
|
.concat(otherItemsLinkedToOriginNode);
|
|
1114
|
-
|
|
1115
713
|
originNodeGroups.set(keepOriginNode, newList);
|
|
1116
|
-
|
|
1117
|
-
// Remove other node origin as a key
|
|
1118
714
|
originNodeGroups.delete(otherOriginNode);
|
|
1119
|
-
|
|
1120
715
|
this.print('removed other origin');
|
|
1121
716
|
this.print('merge completed');
|
|
1122
717
|
}
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
placeSubgraph(graph: graphlib.Graph, firstNodeId: string,
|
|
1126
|
-
subgraphEdges: graphlib.Edge[]): void {
|
|
1127
|
-
|
|
718
|
+
placeSubgraph(graph, firstNodeId, subgraphEdges) {
|
|
1128
719
|
let firstNodePlaced = false;
|
|
1129
|
-
|
|
1130
720
|
subgraphEdges.forEach(edge => {
|
|
1131
|
-
const [nodeId1, pin1, nodeId2, pin2]
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
const [, node1]: [string, RenderItem] = graph.node(nodeId1);
|
|
1135
|
-
const [, node2]: [string, RenderItem] = graph.node(nodeId2);
|
|
1136
|
-
|
|
721
|
+
const [nodeId1, pin1, nodeId2, pin2] = graph.edge(edge);
|
|
722
|
+
const [, node1] = graph.node(nodeId1);
|
|
723
|
+
const [, node2] = graph.node(nodeId2);
|
|
1137
724
|
if (nodeId1 === firstNodeId && !firstNodePlaced) {
|
|
1138
725
|
this.print('first node placed at origin');
|
|
1139
726
|
this.placeNodeAtPosition(0, 0, node1, pin1);
|
|
1140
727
|
firstNodePlaced = true;
|
|
1141
728
|
node1.isFloating = false;
|
|
1142
729
|
}
|
|
1143
|
-
|
|
1144
|
-
let
|
|
1145
|
-
let
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
let floatingNodePin: number;
|
|
1149
|
-
|
|
1150
|
-
this.print('edge:', '[', node1, pin1, node1.isFloating, ']',
|
|
1151
|
-
'[', node2, pin2, node2.isFloating, ']');
|
|
1152
|
-
|
|
730
|
+
let fixedNode;
|
|
731
|
+
let fixedNodePin;
|
|
732
|
+
let floatingNode;
|
|
733
|
+
let floatingNodePin;
|
|
734
|
+
this.print('edge:', '[', node1, pin1, node1.isFloating, ']', '[', node2, pin2, node2.isFloating, ']');
|
|
1153
735
|
if (!node1.isFloating && node2.isFloating) {
|
|
1154
736
|
fixedNode = node1;
|
|
1155
737
|
fixedNodePin = pin1;
|
|
1156
|
-
|
|
1157
738
|
floatingNode = node2;
|
|
1158
739
|
floatingNodePin = pin2;
|
|
1159
|
-
|
|
1160
|
-
|
|
740
|
+
}
|
|
741
|
+
else if (node1.isFloating && !node2.isFloating) {
|
|
1161
742
|
fixedNode = node2;
|
|
1162
743
|
fixedNodePin = pin2;
|
|
1163
|
-
|
|
1164
744
|
floatingNode = node1;
|
|
1165
745
|
floatingNodePin = pin1;
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
this.print('both nodes are floating', node1, 'pin', pin1,
|
|
1169
|
-
'and', node2, 'pin', pin2);
|
|
746
|
+
}
|
|
747
|
+
else if (node1.isFloating && node2.isFloating) {
|
|
748
|
+
this.print('both nodes are floating', node1, 'pin', pin1, 'and', node2, 'pin', pin2);
|
|
1170
749
|
node1.floatingRelativeTo.push([pin1, nodeId2, pin2]);
|
|
1171
750
|
node2.floatingRelativeTo.push([pin2, nodeId1, pin1]);
|
|
1172
751
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
this.print('place floating node', floatingNode, 'pin', floatingNodePin,
|
|
1176
|
-
'to', fixedNode, 'pin', fixedNodePin);
|
|
1177
|
-
|
|
752
|
+
if (fixedNode && floatingNode) {
|
|
753
|
+
this.print('place floating node', floatingNode, 'pin', floatingNodePin, 'to', fixedNode, 'pin', fixedNodePin);
|
|
1178
754
|
const [x, y] = getNodePositionAtPin(fixedNode, fixedNodePin);
|
|
1179
755
|
this.placeNodeAtPosition(x, y, floatingNode, floatingNodePin);
|
|
1180
756
|
floatingNode.isFloating = false;
|
|
1181
|
-
|
|
1182
757
|
this.placeFloatingItems(graph, floatingNode);
|
|
1183
758
|
}
|
|
1184
|
-
|
|
1185
759
|
[node1, node2].forEach(item => {
|
|
1186
|
-
if (item instanceof RenderWire){
|
|
1187
|
-
|
|
1188
|
-
if (item.isEndAutoLength()){
|
|
760
|
+
if (item instanceof RenderWire) {
|
|
761
|
+
if (item.isEndAutoLength()) {
|
|
1189
762
|
const [instance, pin] = item.getEndAuto();
|
|
1190
|
-
const [, targetNode]
|
|
1191
|
-
graph.node(instance.instanceName);
|
|
1192
|
-
|
|
763
|
+
const [, targetNode] = graph.node(instance.instanceName);
|
|
1193
764
|
const [untilX, untilY] = getNodePositionAtPin(targetNode, pin);
|
|
1194
765
|
item.setEndAuto(untilX, untilY);
|
|
1195
766
|
}
|
|
1196
|
-
}
|
|
767
|
+
}
|
|
1197
768
|
});
|
|
1198
769
|
});
|
|
1199
770
|
}
|
|
1200
|
-
|
|
1201
|
-
translateNodeBy(offsetX: number, offsetY: number, item: RenderItem): void {
|
|
771
|
+
translateNodeBy(offsetX, offsetY, item) {
|
|
1202
772
|
item.x += offsetX;
|
|
1203
773
|
item.y += offsetY;
|
|
1204
774
|
}
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
if (item instanceof RenderComponent){
|
|
775
|
+
placeNodeAtPosition(fromX, fromY, item, pin, depth = 0) {
|
|
776
|
+
if (item instanceof RenderComponent) {
|
|
1208
777
|
const pinPosition = item.symbol.pinPosition(pin);
|
|
1209
778
|
item.x = fromX - pinPosition.x;
|
|
1210
|
-
item.y = fromY - pinPosition.y;
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
if (pin === 0) {
|
|
779
|
+
item.y = fromY - pinPosition.y;
|
|
780
|
+
}
|
|
781
|
+
else if (item instanceof RenderWire) {
|
|
782
|
+
if (pin === 0) {
|
|
1214
783
|
item.x = fromX;
|
|
1215
784
|
item.y = fromY;
|
|
1216
|
-
}
|
|
785
|
+
}
|
|
786
|
+
else {
|
|
1217
787
|
const wireEnd = item.getWireEnd();
|
|
1218
788
|
item.x = fromX - wireEnd.x;
|
|
1219
789
|
item.y = fromY - wireEnd.y;
|
|
1220
790
|
}
|
|
1221
791
|
}
|
|
1222
|
-
|
|
1223
792
|
this.print(this.padLevel(depth), 'place', item, 'pin', pin, 'at', item.x, item.y);
|
|
1224
793
|
}
|
|
1225
|
-
|
|
1226
|
-
placeFloatingItems(graph: graphlib.Graph, item: RenderItem, depth = 0): void {
|
|
1227
|
-
// Assume that item already has a fixed position
|
|
1228
|
-
|
|
794
|
+
placeFloatingItems(graph, item, depth = 0) {
|
|
1229
795
|
if (depth > 100) {
|
|
1230
796
|
throw "Too many levels when placing floating items";
|
|
1231
797
|
}
|
|
1232
|
-
|
|
1233
798
|
const { floatingRelativeTo = [] } = item;
|
|
1234
|
-
|
|
1235
|
-
if (floatingRelativeTo.length > 0){
|
|
1236
|
-
|
|
799
|
+
if (floatingRelativeTo.length > 0) {
|
|
1237
800
|
this.print(this.padLevel(depth), 'place relative to', item);
|
|
1238
|
-
this.print(this.padLevel(depth), 'relative to',
|
|
1239
|
-
JSON.stringify(floatingRelativeTo));
|
|
1240
|
-
|
|
801
|
+
this.print(this.padLevel(depth), 'relative to', JSON.stringify(floatingRelativeTo));
|
|
1241
802
|
floatingRelativeTo.forEach(entry => {
|
|
1242
803
|
const [selfPin, nodeId, pin] = entry;
|
|
1243
804
|
const [, tmpNode] = graph.node(nodeId);
|
|
1244
|
-
|
|
1245
805
|
if (tmpNode.isFloating) {
|
|
1246
806
|
const [x, y] = getNodePositionAtPin(item, selfPin);
|
|
1247
807
|
this.placeNodeAtPosition(x, y, tmpNode, pin, depth);
|
|
1248
808
|
tmpNode.isFloating = false;
|
|
1249
|
-
|
|
1250
809
|
this.placeFloatingItems(graph, tmpNode, depth + 1);
|
|
1251
|
-
}
|
|
810
|
+
}
|
|
811
|
+
else {
|
|
1252
812
|
this.print(this.padLevel(depth), 'skipping', tmpNode, 'as it is not floating');
|
|
1253
813
|
}
|
|
1254
814
|
});
|
|
1255
|
-
|
|
1256
815
|
this.print(this.padLevel(depth), '<<< done traversing floating nodes');
|
|
1257
|
-
}
|
|
816
|
+
}
|
|
817
|
+
else {
|
|
1258
818
|
this.print(this.padLevel(depth), 'no nodes floating relative to', item);
|
|
1259
819
|
}
|
|
1260
820
|
}
|
|
1261
|
-
|
|
1262
|
-
printWarnings(): void {
|
|
821
|
+
printWarnings() {
|
|
1263
822
|
this.layoutWarnings.forEach(message => {
|
|
1264
823
|
console.log('Warning: ' + message);
|
|
1265
824
|
});
|
|
1266
825
|
}
|
|
1267
826
|
}
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
if (item instanceof RenderComponent){
|
|
827
|
+
exports.LayoutEngine = LayoutEngine;
|
|
828
|
+
function getNodePositionAtPin(item, pin) {
|
|
829
|
+
if (item instanceof RenderComponent) {
|
|
1272
830
|
const pinPosition = item.symbol.pinPosition(pin);
|
|
1273
831
|
return [
|
|
1274
832
|
item.x + pinPosition.x,
|
|
1275
833
|
item.y + pinPosition.y
|
|
1276
834
|
];
|
|
1277
|
-
}
|
|
1278
|
-
|
|
835
|
+
}
|
|
836
|
+
else if (item instanceof RenderWire) {
|
|
837
|
+
if (pin === 0) {
|
|
1279
838
|
return [item.x, item.y];
|
|
1280
|
-
}
|
|
839
|
+
}
|
|
840
|
+
else {
|
|
1281
841
|
const wireEnd = item.getWireEnd();
|
|
1282
|
-
|
|
1283
842
|
return [
|
|
1284
843
|
item.x + wireEnd.x,
|
|
1285
844
|
item.y + wireEnd.y
|
|
1286
|
-
]
|
|
845
|
+
];
|
|
1287
846
|
}
|
|
1288
847
|
}
|
|
1289
848
|
}
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
function getNeighbours(graph: graphlib.Graph, nodeIds: string[]): [from: string, to: string][] {
|
|
1293
|
-
|
|
849
|
+
function getNeighbours(graph, nodeIds) {
|
|
1294
850
|
return nodeIds.reduce((accum, nodeId) => {
|
|
1295
851
|
const tmp = graph.neighbors(nodeId);
|
|
1296
852
|
if (tmp) {
|
|
@@ -1299,57 +855,40 @@ function getNeighbours(graph: graphlib.Graph, nodeIds: string[]): [from: string,
|
|
|
1299
855
|
});
|
|
1300
856
|
}
|
|
1301
857
|
return accum;
|
|
1302
|
-
}, []
|
|
858
|
+
}, []);
|
|
1303
859
|
}
|
|
1304
|
-
|
|
1305
|
-
type EdgeValue = [instance1: string, instancePin1: number,
|
|
1306
|
-
instance2: string, instancePin2: number, priority: number];
|
|
1307
|
-
|
|
1308
|
-
function makeEdgeValue(instanceName1: string, instancePin1: number,
|
|
1309
|
-
instanceName2: string, instancePin2: number, priority: number)
|
|
1310
|
-
: EdgeValue {
|
|
860
|
+
function makeEdgeValue(instanceName1, instancePin1, instanceName2, instancePin2, priority) {
|
|
1311
861
|
return [instanceName1, instancePin1, instanceName2, instancePin2, priority];
|
|
1312
|
-
// return `${instanceName1}:pin:${instancePin1} -- ${instanceName2}:pin:${instancePin2}`;
|
|
1313
862
|
}
|
|
1314
|
-
|
|
1315
|
-
function getWireName(wireId: number): string {
|
|
863
|
+
function getWireName(wireId) {
|
|
1316
864
|
return 'wire:' + wireId;
|
|
1317
865
|
}
|
|
1318
|
-
|
|
1319
|
-
type RenderItem = RenderComponent | RenderWire | RenderText;
|
|
1320
|
-
|
|
1321
|
-
function generateLayoutPinDefinition(component: ClassComponent): SymbolPinDefintion[] {
|
|
866
|
+
function generateLayoutPinDefinition(component) {
|
|
1322
867
|
const pins = component.pins;
|
|
1323
|
-
const symbolPinDefinitions
|
|
868
|
+
const symbolPinDefinitions = [];
|
|
1324
869
|
const existingPinIds = Array.from(pins.keys());
|
|
1325
|
-
|
|
1326
870
|
if (component.arrangeProps === null) {
|
|
1327
|
-
// Automatically split pins
|
|
1328
871
|
for (let i = 0; i < existingPinIds.length; i++) {
|
|
1329
|
-
const pinPosition = Math.floor(i/2);
|
|
1330
|
-
|
|
872
|
+
const pinPosition = Math.floor(i / 2);
|
|
1331
873
|
symbolPinDefinitions.push({
|
|
1332
874
|
side: (i % 2 === 0) ? "left" : "right",
|
|
1333
875
|
pinId: existingPinIds[i],
|
|
1334
876
|
text: pins.get(existingPinIds[i]).name,
|
|
1335
877
|
position: pinPosition,
|
|
1336
|
-
})
|
|
878
|
+
});
|
|
1337
879
|
}
|
|
1338
|
-
}
|
|
880
|
+
}
|
|
881
|
+
else {
|
|
1339
882
|
const addedPins = [];
|
|
1340
|
-
|
|
1341
883
|
for (const [key, items] of component.arrangeProps) {
|
|
1342
|
-
|
|
1343
884
|
let useItems;
|
|
1344
|
-
if (!Array.isArray(items)){
|
|
885
|
+
if (!Array.isArray(items)) {
|
|
1345
886
|
useItems = [items];
|
|
1346
|
-
}
|
|
1347
|
-
|
|
887
|
+
}
|
|
888
|
+
else {
|
|
1348
889
|
useItems = [...items];
|
|
1349
890
|
}
|
|
1350
|
-
|
|
1351
891
|
useItems.forEach(pinId => {
|
|
1352
|
-
// Only use the pin if it exists!
|
|
1353
892
|
if (existingPinIds.indexOf(pinId) !== -1) {
|
|
1354
893
|
symbolPinDefinitions.push({
|
|
1355
894
|
side: key,
|
|
@@ -1361,55 +900,42 @@ function generateLayoutPinDefinition(component: ClassComponent): SymbolPinDefint
|
|
|
1361
900
|
}
|
|
1362
901
|
});
|
|
1363
902
|
}
|
|
1364
|
-
|
|
1365
|
-
// Make sure all existing pins are added, otherwise throw an error
|
|
1366
903
|
const unplacedPins = [];
|
|
1367
904
|
existingPinIds.forEach(item => {
|
|
1368
|
-
if (addedPins.indexOf(item) === -1){
|
|
905
|
+
if (addedPins.indexOf(item) === -1) {
|
|
1369
906
|
unplacedPins.push(item);
|
|
1370
907
|
}
|
|
1371
908
|
});
|
|
1372
|
-
|
|
1373
|
-
if (unplacedPins.length > 0){
|
|
909
|
+
if (unplacedPins.length > 0) {
|
|
1374
910
|
throw "'arrange' property is defined, but not all pins are specified: " + unplacedPins.join(",");
|
|
1375
911
|
}
|
|
1376
912
|
}
|
|
1377
|
-
|
|
1378
913
|
return symbolPinDefinitions;
|
|
1379
914
|
}
|
|
1380
|
-
|
|
1381
|
-
function applyComponentParamsToSymbol(typeProp: string,
|
|
1382
|
-
component: ClassComponent, symbol: SymbolGraphic): void {
|
|
1383
|
-
|
|
915
|
+
function applyComponentParamsToSymbol(typeProp, component, symbol) {
|
|
1384
916
|
if (typeProp === 'net') {
|
|
1385
|
-
symbol.setLabelValue("net_name",
|
|
1386
|
-
component.parameters.get(ParamKeys.net_name) as string);
|
|
917
|
+
symbol.setLabelValue("net_name", component.parameters.get(globals_js_1.ParamKeys.net_name));
|
|
1387
918
|
}
|
|
1388
|
-
|
|
1389
|
-
if (component.assignedRefDes !== null){
|
|
919
|
+
if (component.assignedRefDes !== null) {
|
|
1390
920
|
symbol.setLabelValue("refdes", component.assignedRefDes);
|
|
1391
921
|
}
|
|
1392
|
-
|
|
1393
922
|
for (const [key, value] of component.parameters) {
|
|
1394
923
|
if (key !== 'refdes' && key !== 'net_name') {
|
|
1395
|
-
let useValue
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
924
|
+
let useValue;
|
|
925
|
+
if (typeof value == 'object' && (value instanceof ParamDefinition_js_1.NumericValue)) {
|
|
926
|
+
useValue = value.toDisplayString();
|
|
927
|
+
}
|
|
928
|
+
else if (typeof value === 'number') {
|
|
1400
929
|
useValue = value.toString();
|
|
1401
|
-
}
|
|
930
|
+
}
|
|
931
|
+
else if (typeof value === 'string') {
|
|
1402
932
|
useValue = value;
|
|
1403
933
|
}
|
|
1404
|
-
|
|
1405
934
|
symbol.setLabelValue(key, useValue);
|
|
1406
935
|
}
|
|
1407
936
|
}
|
|
1408
937
|
}
|
|
1409
|
-
|
|
1410
|
-
function calculateSymbolAngle(symbol: SymbolGraphic,
|
|
1411
|
-
pin: number, direction: string): number {
|
|
1412
|
-
|
|
938
|
+
function calculateSymbolAngle(symbol, pin, direction) {
|
|
1413
939
|
let directionVector = 0;
|
|
1414
940
|
switch (direction) {
|
|
1415
941
|
case 'right':
|
|
@@ -1425,118 +951,89 @@ function calculateSymbolAngle(symbol: SymbolGraphic,
|
|
|
1425
951
|
directionVector = 270;
|
|
1426
952
|
break;
|
|
1427
953
|
}
|
|
1428
|
-
|
|
1429
954
|
const { angle: pinVector } = symbol.pinPosition(pin);
|
|
1430
955
|
const useAngle = directionVector - (pinVector % 360);
|
|
1431
|
-
|
|
1432
956
|
return useAngle;
|
|
1433
957
|
}
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
components: (RenderComponent|RenderText)[],
|
|
1437
|
-
wires: RenderWire[], junctions: RenderJunction[], frames: RenderFrame[]): BoundBox{
|
|
1438
|
-
|
|
1439
|
-
const points = [];
|
|
1440
|
-
|
|
958
|
+
function getBounds(components, wires, junctions, frames) {
|
|
959
|
+
const points = [];
|
|
1441
960
|
components.forEach(item => {
|
|
1442
961
|
const bbox = item.symbol.drawing.getBoundingBox();
|
|
1443
|
-
|
|
1444
962
|
const [x1, y1] = bbox.start;
|
|
1445
963
|
const [x2, y2] = bbox.end;
|
|
1446
|
-
|
|
1447
964
|
points.push([x1 + item.x, y1 + item.y]);
|
|
1448
965
|
points.push([x2 + item.x, y2 + item.y]);
|
|
1449
966
|
});
|
|
1450
|
-
|
|
1451
967
|
wires.forEach(wire => {
|
|
1452
968
|
wire.points.forEach(point => {
|
|
1453
969
|
points.push([wire.x + point.x, wire.y + point.y]);
|
|
1454
970
|
});
|
|
1455
971
|
});
|
|
1456
|
-
|
|
1457
972
|
junctions.forEach(item => {
|
|
1458
973
|
points.push([item.x, item.y]);
|
|
1459
974
|
});
|
|
1460
|
-
|
|
1461
975
|
frames.forEach(item => {
|
|
1462
|
-
const {width, height} = getBoundsSize(item.bounds);
|
|
976
|
+
const { width, height } = (0, utils_js_1.getBoundsSize)(item.bounds);
|
|
1463
977
|
points.push([item.x, item.y]);
|
|
1464
978
|
points.push([item.x + width, item.y + height]);
|
|
1465
|
-
})
|
|
1466
|
-
|
|
979
|
+
});
|
|
1467
980
|
return getBoundsFromPoints(points);
|
|
1468
981
|
}
|
|
1469
|
-
|
|
1470
|
-
function getBoundsFromPoints(points
|
|
982
|
+
exports.getBounds = getBounds;
|
|
983
|
+
function getBoundsFromPoints(points) {
|
|
1471
984
|
const xValues = points.map(item => item[0]);
|
|
1472
985
|
const yValues = points.map(item => item[1]);
|
|
1473
|
-
|
|
1474
986
|
const xmin = Math.min(...xValues);
|
|
1475
987
|
const xmax = Math.max(...xValues);
|
|
1476
|
-
|
|
1477
988
|
const ymin = Math.min(...yValues);
|
|
1478
989
|
const ymax = Math.max(...yValues);
|
|
1479
|
-
|
|
1480
990
|
return {
|
|
1481
991
|
xmin, xmax, ymin, ymax,
|
|
1482
|
-
}
|
|
992
|
+
};
|
|
1483
993
|
}
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
994
|
+
class RenderObject {
|
|
995
|
+
constructor() {
|
|
996
|
+
this.x = -1;
|
|
997
|
+
this.y = -1;
|
|
998
|
+
this.isFloating = true;
|
|
999
|
+
this.floatingRelativeTo = [];
|
|
1000
|
+
}
|
|
1491
1001
|
}
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
id: number;
|
|
1496
|
-
segments: WireSegment[] = [];
|
|
1497
|
-
points:{x: number, y:number}[] = [];
|
|
1498
|
-
|
|
1499
|
-
// Net name is used to determine if wires
|
|
1500
|
-
// can overlap
|
|
1501
|
-
netName: string;
|
|
1502
|
-
|
|
1503
|
-
constructor(x: number, y: number, segments: WireSegment[]) {
|
|
1002
|
+
exports.RenderObject = RenderObject;
|
|
1003
|
+
class RenderWire extends RenderObject {
|
|
1004
|
+
constructor(x, y, segments) {
|
|
1504
1005
|
super();
|
|
1006
|
+
this.segments = [];
|
|
1007
|
+
this.points = [];
|
|
1505
1008
|
this.x = x;
|
|
1506
1009
|
this.y = y;
|
|
1507
1010
|
this.segments = segments;
|
|
1508
|
-
|
|
1509
1011
|
this.refreshPoints();
|
|
1510
1012
|
}
|
|
1511
|
-
|
|
1512
|
-
refreshPoints(): void {
|
|
1013
|
+
refreshPoints() {
|
|
1513
1014
|
let tmpX = 0;
|
|
1514
1015
|
let tmpY = 0;
|
|
1515
|
-
|
|
1516
1016
|
const points = [{ x: tmpX, y: tmpY }];
|
|
1517
|
-
|
|
1518
1017
|
this.segments.forEach(segment => {
|
|
1519
1018
|
const { direction, value } = segment;
|
|
1520
|
-
|
|
1521
1019
|
let didAddPoint = false;
|
|
1522
|
-
|
|
1523
1020
|
if (direction === 'down') {
|
|
1524
1021
|
tmpY += value;
|
|
1525
|
-
}
|
|
1022
|
+
}
|
|
1023
|
+
else if (direction === 'up') {
|
|
1526
1024
|
tmpY -= value;
|
|
1527
|
-
}
|
|
1025
|
+
}
|
|
1026
|
+
else if (direction === 'left') {
|
|
1528
1027
|
tmpX -= value;
|
|
1529
|
-
}
|
|
1028
|
+
}
|
|
1029
|
+
else if (direction === 'right') {
|
|
1530
1030
|
tmpX += value;
|
|
1531
|
-
}
|
|
1532
|
-
|
|
1533
|
-
// uses the alternative path to the target.
|
|
1031
|
+
}
|
|
1032
|
+
else if (direction === 'auto' || direction === "auto_") {
|
|
1534
1033
|
const { valueXY = [0, 0] } = segment;
|
|
1535
|
-
|
|
1536
1034
|
const tmpPoints = this.getAutoPoints(valueXY, direction);
|
|
1537
|
-
|
|
1538
1035
|
tmpPoints.forEach(point => {
|
|
1539
|
-
if (point[0] !== 0 || point[1] !== 0){
|
|
1036
|
+
if (point[0] !== 0 || point[1] !== 0) {
|
|
1540
1037
|
tmpX += point[0];
|
|
1541
1038
|
tmpY += point[1];
|
|
1542
1039
|
points.push({ x: tmpX, y: tmpY });
|
|
@@ -1544,20 +1041,15 @@ export class RenderWire extends RenderObject {
|
|
|
1544
1041
|
});
|
|
1545
1042
|
didAddPoint = true;
|
|
1546
1043
|
}
|
|
1547
|
-
|
|
1548
|
-
if(!didAddPoint){
|
|
1044
|
+
if (!didAddPoint) {
|
|
1549
1045
|
points.push({ x: tmpX, y: tmpY });
|
|
1550
1046
|
}
|
|
1551
1047
|
});
|
|
1552
|
-
|
|
1553
1048
|
this.points = points;
|
|
1554
1049
|
}
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
const inQuadrant = Geometry.getQuadrant(value[0], value[1]);
|
|
1050
|
+
getAutoPoints(value, direction) {
|
|
1051
|
+
const inQuadrant = geometry_js_1.Geometry.getQuadrant(value[0], value[1]);
|
|
1558
1052
|
const [dx, dy] = value;
|
|
1559
|
-
|
|
1560
|
-
// Clockwise direction
|
|
1561
1053
|
if (direction === 'auto') {
|
|
1562
1054
|
switch (inQuadrant) {
|
|
1563
1055
|
case 0:
|
|
@@ -1567,7 +1059,8 @@ export class RenderWire extends RenderObject {
|
|
|
1567
1059
|
case 3:
|
|
1568
1060
|
return [[0, dy], [dx, 0]];
|
|
1569
1061
|
}
|
|
1570
|
-
}
|
|
1062
|
+
}
|
|
1063
|
+
else if (direction === 'auto_') {
|
|
1571
1064
|
switch (inQuadrant) {
|
|
1572
1065
|
case 0:
|
|
1573
1066
|
case 2:
|
|
@@ -1577,60 +1070,48 @@ export class RenderWire extends RenderObject {
|
|
|
1577
1070
|
return [[dx, 0], [0, dy]];
|
|
1578
1071
|
}
|
|
1579
1072
|
}
|
|
1580
|
-
|
|
1581
1073
|
return [[0, 0]];
|
|
1582
1074
|
}
|
|
1583
|
-
|
|
1584
|
-
getWireEnd(): { x: number, y: number } {
|
|
1075
|
+
getWireEnd() {
|
|
1585
1076
|
return this.points[this.points.length - 1];
|
|
1586
1077
|
}
|
|
1587
|
-
|
|
1588
|
-
isEndAutoLength(): boolean {
|
|
1078
|
+
isEndAutoLength() {
|
|
1589
1079
|
if (this.segments.length > 0) {
|
|
1590
|
-
// If only direction, then it is an auto length
|
|
1591
1080
|
return this.segments[this.segments.length - 1].value === null;
|
|
1592
1081
|
}
|
|
1593
|
-
|
|
1594
1082
|
return false;
|
|
1595
1083
|
}
|
|
1596
|
-
|
|
1597
|
-
getEndAuto(): [instance: ClassComponent, pin: number] {
|
|
1084
|
+
getEndAuto() {
|
|
1598
1085
|
if (this.segments.length > 0) {
|
|
1599
1086
|
return this.segments[this.segments.length - 1].until;
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1087
|
+
}
|
|
1088
|
+
else {
|
|
1089
|
+
throw "No segments in wire!";
|
|
1602
1090
|
}
|
|
1603
1091
|
}
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
// Find the last accumulated position up to the last item
|
|
1608
|
-
const excludeLastSegment = this.segments.slice(0, this.segments.length-1);
|
|
1609
|
-
|
|
1092
|
+
setEndAuto(untilX, untilY) {
|
|
1093
|
+
const excludeLastSegment = this.segments.slice(0, this.segments.length - 1);
|
|
1610
1094
|
let tmpX = this.x;
|
|
1611
1095
|
let tmpY = this.y;
|
|
1612
|
-
|
|
1613
1096
|
excludeLastSegment.forEach(segment => {
|
|
1614
1097
|
const { direction, value } = segment;
|
|
1615
1098
|
if (direction === 'down') {
|
|
1616
1099
|
tmpY += value;
|
|
1617
|
-
}
|
|
1100
|
+
}
|
|
1101
|
+
else if (direction === 'up') {
|
|
1618
1102
|
tmpY -= value;
|
|
1619
|
-
}
|
|
1103
|
+
}
|
|
1104
|
+
else if (direction === 'left') {
|
|
1620
1105
|
tmpX -= value;
|
|
1621
|
-
}
|
|
1106
|
+
}
|
|
1107
|
+
else if (direction === 'right') {
|
|
1622
1108
|
tmpX += value;
|
|
1623
1109
|
}
|
|
1624
1110
|
});
|
|
1625
|
-
|
|
1626
|
-
// Based on the last segment direction, determine the
|
|
1627
|
-
// value. Since value is set, then the segment will no longer
|
|
1628
|
-
// be considered as an 'auto length' segment.
|
|
1629
1111
|
let useValue = null;
|
|
1630
1112
|
let valueXY = null;
|
|
1631
|
-
const lastSegment = this.segments[this.segments.length-1];
|
|
1632
|
-
|
|
1633
|
-
switch(lastSegment.direction){
|
|
1113
|
+
const lastSegment = this.segments[this.segments.length - 1];
|
|
1114
|
+
switch (lastSegment.direction) {
|
|
1634
1115
|
case 'left':
|
|
1635
1116
|
useValue = tmpX - untilX;
|
|
1636
1117
|
break;
|
|
@@ -1643,174 +1124,112 @@ export class RenderWire extends RenderObject {
|
|
|
1643
1124
|
case 'down':
|
|
1644
1125
|
useValue = tmpY - untilY;
|
|
1645
1126
|
break;
|
|
1646
|
-
|
|
1647
1127
|
case 'auto':
|
|
1648
1128
|
case 'auto_':
|
|
1649
|
-
// Always assume positive values
|
|
1650
1129
|
valueXY = [
|
|
1651
1130
|
untilX - tmpX,
|
|
1652
1131
|
untilY - tmpY,
|
|
1653
1132
|
];
|
|
1654
|
-
|
|
1655
|
-
// Set to 0, to mark that auto length
|
|
1656
|
-
// calculation has already been done.
|
|
1657
1133
|
useValue = 0;
|
|
1658
1134
|
break;
|
|
1659
1135
|
}
|
|
1660
|
-
|
|
1661
1136
|
lastSegment.value = useValue;
|
|
1662
1137
|
lastSegment.valueXY = valueXY !== null ? valueXY : null;
|
|
1663
|
-
|
|
1664
1138
|
this.refreshPoints();
|
|
1665
1139
|
}
|
|
1666
|
-
|
|
1667
|
-
toString(): string {
|
|
1140
|
+
toString() {
|
|
1668
1141
|
return getWireName(this.id);
|
|
1669
1142
|
}
|
|
1670
1143
|
}
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
segments: [x: number, y:number][][],
|
|
1675
|
-
intersectPoints: [x: number, y: number, count: number][],
|
|
1676
|
-
}
|
|
1677
|
-
|
|
1678
|
-
export class RenderComponent extends RenderObject {
|
|
1679
|
-
// Holds the render information of the component (position)
|
|
1680
|
-
|
|
1681
|
-
component: ClassComponent;
|
|
1682
|
-
symbol: SymbolGraphic;
|
|
1683
|
-
|
|
1684
|
-
width: number;
|
|
1685
|
-
height: number;
|
|
1686
|
-
|
|
1687
|
-
displaySymbol: string | null = null;
|
|
1688
|
-
|
|
1689
|
-
constructor(component: ClassComponent, width: number, height: number) {
|
|
1144
|
+
exports.RenderWire = RenderWire;
|
|
1145
|
+
class RenderComponent extends RenderObject {
|
|
1146
|
+
constructor(component, width, height) {
|
|
1690
1147
|
super();
|
|
1148
|
+
this.displaySymbol = null;
|
|
1691
1149
|
this.component = component;
|
|
1692
1150
|
this.width = width;
|
|
1693
1151
|
this.height = height;
|
|
1694
1152
|
}
|
|
1695
|
-
|
|
1696
|
-
doesOverlap(other: RenderComponent): boolean {
|
|
1153
|
+
doesOverlap(other) {
|
|
1697
1154
|
const condition1 = isPointOverlap(this.x, this.y, other);
|
|
1698
1155
|
const condition2 = isPointOverlap(this.x + this.width, this.y, other);
|
|
1699
1156
|
const condition3 = isPointOverlap(this.x + this.width, this.y + this.height, other);
|
|
1700
1157
|
const condition4 = isPointOverlap(this.x, this.y + this.height, other);
|
|
1701
|
-
|
|
1702
|
-
return condition1 || condition2 || condition3 || condition4;
|
|
1158
|
+
return condition1 || condition2 || condition3 || condition4;
|
|
1703
1159
|
}
|
|
1704
|
-
|
|
1705
|
-
toString(): string {
|
|
1160
|
+
toString() {
|
|
1706
1161
|
return "component:" + this.component.instanceName;
|
|
1707
1162
|
}
|
|
1708
1163
|
}
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
_fontSize = 12;
|
|
1714
|
-
_fontWeight = 'regular';
|
|
1715
|
-
|
|
1716
|
-
get fontSize (): number {
|
|
1164
|
+
exports.RenderComponent = RenderComponent;
|
|
1165
|
+
class RenderText extends RenderObject {
|
|
1166
|
+
get fontSize() {
|
|
1717
1167
|
return this._fontSize;
|
|
1718
1168
|
}
|
|
1719
|
-
|
|
1720
|
-
set fontSize(value: number) {
|
|
1169
|
+
set fontSize(value) {
|
|
1721
1170
|
this._fontSize = value;
|
|
1722
1171
|
this.symbol.fontSize = value;
|
|
1723
1172
|
}
|
|
1724
|
-
|
|
1725
|
-
get fontWeight(): string {
|
|
1173
|
+
get fontWeight() {
|
|
1726
1174
|
return this._fontWeight;
|
|
1727
1175
|
}
|
|
1728
|
-
|
|
1729
|
-
set fontWeight(value: string) {
|
|
1176
|
+
set fontWeight(value) {
|
|
1730
1177
|
this._fontWeight = value;
|
|
1731
1178
|
this.symbol.fontWeight = value;
|
|
1732
1179
|
}
|
|
1733
|
-
|
|
1734
|
-
constructor(text: string) {
|
|
1180
|
+
constructor(text) {
|
|
1735
1181
|
super();
|
|
1736
|
-
this.
|
|
1182
|
+
this._fontSize = 12;
|
|
1183
|
+
this._fontWeight = 'regular';
|
|
1184
|
+
this.symbol = new draw_symbols_js_1.SymbolText(text);
|
|
1737
1185
|
}
|
|
1738
1186
|
}
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
frame: Frame;
|
|
1743
|
-
|
|
1744
|
-
// Store all items in the same array so that the order of frames
|
|
1745
|
-
// can be identified.
|
|
1746
|
-
innerItems: (RenderComponent | RenderFrame | RenderText)[] = [];
|
|
1747
|
-
|
|
1748
|
-
translateX = 0;
|
|
1749
|
-
translateY = 0;
|
|
1750
|
-
|
|
1751
|
-
padding = 20; // Inner frame padding
|
|
1752
|
-
|
|
1753
|
-
gap = 20; // Spacing between inner frames
|
|
1754
|
-
|
|
1755
|
-
direction = FramePlotDirection.Column;
|
|
1756
|
-
|
|
1757
|
-
borderWidth = 1;
|
|
1758
|
-
|
|
1759
|
-
subgraphId = "";
|
|
1760
|
-
|
|
1761
|
-
type: RenderFrameType;
|
|
1762
|
-
|
|
1763
|
-
// If true, then frame only contains text for frame title.
|
|
1764
|
-
containsTitle = false;
|
|
1765
|
-
|
|
1766
|
-
constructor(frame: Frame, type: RenderFrameType = RenderFrameType.Container) {
|
|
1187
|
+
exports.RenderText = RenderText;
|
|
1188
|
+
class RenderFrame extends RenderObject {
|
|
1189
|
+
constructor(frame, type = RenderFrameType.Container) {
|
|
1767
1190
|
super();
|
|
1191
|
+
this.bounds = null;
|
|
1192
|
+
this.innerItems = [];
|
|
1193
|
+
this.translateX = 0;
|
|
1194
|
+
this.translateY = 0;
|
|
1195
|
+
this.padding = 20;
|
|
1196
|
+
this.gap = 20;
|
|
1197
|
+
this.direction = Frame_js_1.FramePlotDirection.Column;
|
|
1198
|
+
this.borderWidth = 1;
|
|
1199
|
+
this.subgraphId = "";
|
|
1200
|
+
this.containsTitle = false;
|
|
1768
1201
|
this.frame = frame;
|
|
1769
1202
|
this.type = type;
|
|
1770
1203
|
}
|
|
1771
|
-
|
|
1772
|
-
toString(): string {
|
|
1204
|
+
toString() {
|
|
1773
1205
|
let name = "";
|
|
1774
1206
|
if (this.type === RenderFrameType.Container) {
|
|
1775
1207
|
name = 'container_' + this.frame.frameId;
|
|
1776
|
-
}
|
|
1208
|
+
}
|
|
1209
|
+
else if (this.type === RenderFrameType.Elements) {
|
|
1777
1210
|
name = 'elements_' + this.subgraphId;
|
|
1778
1211
|
}
|
|
1779
|
-
|
|
1780
|
-
return name + ": " + this.x + "," + this.y + " bounds:" + printBounds(this.bounds);
|
|
1212
|
+
return name + ": " + this.x + "," + this.y + " bounds:" + (0, utils_js_1.printBounds)(this.bounds);
|
|
1781
1213
|
}
|
|
1782
1214
|
}
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
x
|
|
1791
|
-
y: number;
|
|
1792
|
-
|
|
1793
|
-
constructor(x: number, y: number){
|
|
1215
|
+
exports.RenderFrame = RenderFrame;
|
|
1216
|
+
var RenderFrameType;
|
|
1217
|
+
(function (RenderFrameType) {
|
|
1218
|
+
RenderFrameType[RenderFrameType["Container"] = 1] = "Container";
|
|
1219
|
+
RenderFrameType[RenderFrameType["Elements"] = 2] = "Elements";
|
|
1220
|
+
})(RenderFrameType || (exports.RenderFrameType = RenderFrameType = {}));
|
|
1221
|
+
class RenderJunction {
|
|
1222
|
+
constructor(x, y) {
|
|
1794
1223
|
this.x = x;
|
|
1795
1224
|
this.y = y;
|
|
1796
1225
|
}
|
|
1797
1226
|
}
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
function isPointOverlap(x: number, y: number, other: RenderComponent): boolean {
|
|
1227
|
+
exports.RenderJunction = RenderJunction;
|
|
1228
|
+
function isPointOverlap(x, y, other) {
|
|
1802
1229
|
return (x >= other.x && y >= other.y && x <= (other.x + other.width) && y <= (other.y + other.height));
|
|
1803
1230
|
}
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
Wire =
|
|
1807
|
-
Component =
|
|
1808
|
-
}
|
|
1809
|
-
|
|
1810
|
-
type SubGraphInfo = {
|
|
1811
|
-
firstNodeId: string;
|
|
1812
|
-
components: string[];
|
|
1813
|
-
bounds: BoundBox;
|
|
1814
|
-
}
|
|
1815
|
-
|
|
1816
|
-
export { BoundBox };
|
|
1231
|
+
var RenderItemType;
|
|
1232
|
+
(function (RenderItemType) {
|
|
1233
|
+
RenderItemType["Wire"] = "wire";
|
|
1234
|
+
RenderItemType["Component"] = "component";
|
|
1235
|
+
})(RenderItemType || (RenderItemType = {}));
|