circuitscript 0.0.22 → 0.0.24
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/antlr/CircuitScriptLexer.js +288 -0
- package/dist/cjs/antlr/CircuitScriptParser.js +4905 -0
- package/dist/cjs/antlr/CircuitScriptVisitor.js +6 -0
- package/{src/draw_symbols.ts → dist/cjs/draw_symbols.js} +303 -614
- package/dist/cjs/execute.js +780 -0
- package/{src/export.ts → dist/cjs/export.js} +34 -56
- package/dist/cjs/fonts.js +4 -0
- package/dist/cjs/geometry.js +430 -0
- package/dist/cjs/globals.js +60 -0
- package/dist/cjs/helpers.js +99 -0
- package/dist/cjs/index.js +29 -0
- package/{src/layout.ts → dist/cjs/layout.js} +413 -1002
- package/dist/cjs/lexer.js +114 -0
- package/dist/cjs/logger.js +17 -0
- package/dist/cjs/main.js +87 -0
- package/dist/cjs/objects/ClassComponent.js +142 -0
- package/dist/cjs/objects/ExecutionScope.js +134 -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 +9 -0
- package/dist/cjs/parser.js +299 -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/{src/visitor.ts → dist/cjs/visitor.js} +392 -948
- package/{build/src/antlr/CircuitScriptLexer.js → dist/esm/antlr/CircuitScriptLexer.mjs} +90 -91
- package/{build/src/antlr/CircuitScriptParser.js → dist/esm/antlr/CircuitScriptParser.mjs} +138 -136
- package/{build/src/draw_symbols.js → dist/esm/draw_symbols.mjs} +11 -11
- package/{build/src/execute.js → dist/esm/execute.mjs} +9 -8
- package/{build/src/export.js → dist/esm/export.mjs} +2 -2
- package/{build/src/geometry.js → dist/esm/geometry.mjs} +3 -7
- package/{build/src/helpers.js → dist/esm/helpers.mjs} +27 -7
- package/dist/esm/index.mjs +13 -0
- package/{build/src/layout.js → dist/esm/layout.mjs} +11 -11
- package/{build/src/lexer.js → dist/esm/lexer.mjs} +2 -2
- package/{build/src/main.js → dist/esm/main.mjs} +5 -5
- package/{build/src/objects/ClassComponent.js → dist/esm/objects/ClassComponent.mjs} +3 -3
- package/{build/src/objects/PinDefinition.js → dist/esm/objects/PinDefinition.mjs} +1 -1
- package/dist/esm/parser.mjs +269 -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/{build/src/visitor.js → dist/esm/visitor.mjs} +10 -29
- package/{build/src → dist/types}/antlr/CircuitScriptLexer.d.ts +23 -23
- package/{build/src → dist/types}/antlr/CircuitScriptParser.d.ts +24 -23
- package/{build/src → dist/types}/draw_symbols.d.ts +2 -2
- package/{build/src → dist/types}/execute.d.ts +2 -2
- package/{build/src → dist/types}/geometry.d.ts +1 -1
- package/dist/types/helpers.d.ts +9 -0
- package/dist/types/index.d.ts +13 -0
- package/{build/src → dist/types}/layout.d.ts +10 -10
- package/{build/src → dist/types}/objects/ClassComponent.d.ts +2 -2
- package/{build/src → dist/types}/objects/PinDefinition.d.ts +1 -1
- package/dist/types/parser.d.ts +38 -0
- package/{build/src → dist/types}/render.d.ts +1 -1
- package/{build/src → dist/types}/sizing.d.ts +3 -1
- package/{build/src → dist/types}/visitor.d.ts +5 -3
- package/package.json +30 -12
- 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/helpers.d.ts +0 -1
- package/build/src/parser.js +0 -69
- 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/fonts/Inter-Bold.ttf +0 -0
- package/fonts/Inter-Regular.ttf +0 -0
- package/fonts/OpenSans-Regular.ttf +0 -0
- package/fonts/Roboto-Regular.ttf +0 -0
- package/jest.config.js +0 -23
- package/libs/lib.cst +0 -185
- 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/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/main.ts +0 -105
- 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/tsconfig.json +0 -27
- package/tsconfig.release.json +0 -8
- /package/{build/src/antlr/CircuitScriptVisitor.js → dist/esm/antlr/CircuitScriptVisitor.mjs} +0 -0
- /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/ExecutionScope.js → dist/esm/objects/ExecutionScope.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/objects/types.js → dist/esm/objects/types.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}/antlr/CircuitScriptVisitor.d.ts +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}/lexer.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/ExecutionScope.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}/objects/types.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,509 @@ 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');
|
|
614
397
|
}
|
|
615
|
-
|
|
616
|
-
if (tmpSymbol instanceof SymbolCustom && widthProp){
|
|
398
|
+
if (tmpSymbol instanceof draw_symbols_js_1.SymbolCustom && widthProp) {
|
|
617
399
|
tmpSymbol.bodyWidth = widthProp;
|
|
618
400
|
}
|
|
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.
|
|
401
|
+
if (!didSetAngle && component.parameters.has('_addDirection')) {
|
|
624
402
|
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
|
-
);
|
|
403
|
+
tmpSymbol.angle = calculateSymbolAngle(tmpSymbol, component.parameters.get('_addPin'), component.parameters.get('_addDirection'));
|
|
631
404
|
}
|
|
632
|
-
|
|
633
|
-
// Draw symbol in memory to determine the size/bounds.
|
|
634
405
|
tmpSymbol.refreshDrawing();
|
|
635
|
-
|
|
636
406
|
const { width: useWidth, height: useHeight } = tmpSymbol.size();
|
|
637
|
-
|
|
638
407
|
tmpComponent = new RenderComponent(component, useWidth, useHeight);
|
|
639
408
|
tmpComponent.symbol = tmpSymbol;
|
|
640
|
-
|
|
641
|
-
// Record the sequence number to determine priority
|
|
642
409
|
graph.setNode(tmpInstanceName, [RenderItemType.Component, tmpComponent, i]);
|
|
643
|
-
|
|
644
|
-
// All components must belong within a frame.
|
|
645
|
-
const currentFrame = frameStack[frameStack.length-1];
|
|
410
|
+
const currentFrame = frameStack[frameStack.length - 1];
|
|
646
411
|
currentFrame && currentFrame.innerItems.push(tmpComponent);
|
|
647
412
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
this.setGraphEdge(graph, previousNode, tmpInstanceName,
|
|
651
|
-
makeEdgeValue(previousNode, previousPin, tmpInstanceName, pin, i));
|
|
413
|
+
if (action === ExecutionScope_js_1.SequenceAction.To) {
|
|
414
|
+
this.setGraphEdge(graph, previousNode, tmpInstanceName, makeEdgeValue(previousNode, previousPin, tmpInstanceName, pin, i));
|
|
652
415
|
}
|
|
653
|
-
|
|
654
|
-
previousNode = tmpInstanceName
|
|
416
|
+
previousNode = tmpInstanceName;
|
|
655
417
|
previousPin = pin;
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
const [, wireId, wireSegments] =
|
|
660
|
-
sequence[i] as [SequenceAction.Wire, number, WireSegment[]];
|
|
661
|
-
|
|
418
|
+
}
|
|
419
|
+
else if (action === ExecutionScope_js_1.SequenceAction.Wire) {
|
|
420
|
+
const [, wireId, wireSegments] = sequence[i];
|
|
662
421
|
const wire = new RenderWire(0, 0, wireSegments);
|
|
663
422
|
wire.id = wireId;
|
|
664
423
|
let useNetName = null;
|
|
665
|
-
|
|
666
424
|
if (previousNode !== null) {
|
|
667
425
|
const [prevNodeType, prevNodeItem] = graph.node(previousNode);
|
|
668
426
|
if (prevNodeType === RenderItemType.Component) {
|
|
669
|
-
// Find the net of the wire
|
|
670
427
|
const matchingItem = nets.find(([comp, pin]) => {
|
|
671
428
|
return comp.instanceName === previousNode && pin === previousPin;
|
|
672
429
|
});
|
|
673
|
-
|
|
674
430
|
useNetName = matchingItem !== undefined ? matchingItem[2].name : null;
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
useNetName =
|
|
431
|
+
}
|
|
432
|
+
else if (prevNodeType === RenderItemType.Wire) {
|
|
433
|
+
useNetName = prevNodeItem.netName;
|
|
678
434
|
}
|
|
679
435
|
}
|
|
680
|
-
|
|
681
436
|
wire.netName = useNetName;
|
|
682
437
|
const wireName = getWireName(wire.id);
|
|
683
|
-
|
|
684
|
-
// Record the sequence number to determine priority
|
|
685
438
|
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
|
-
|
|
439
|
+
this.setGraphEdge(graph, previousNode, wireName, makeEdgeValue(previousNode, previousPin, wireName, 0, i));
|
|
691
440
|
previousNode = wireName;
|
|
692
441
|
previousPin = 1;
|
|
693
|
-
|
|
694
442
|
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
|
-
} = {
|
|
443
|
+
const tmp = {
|
|
701
444
|
direction: item.direction,
|
|
702
445
|
value: item.value,
|
|
703
446
|
};
|
|
704
|
-
|
|
705
447
|
if (item.valueXY) {
|
|
706
448
|
tmp.valueXY = item.valueXY;
|
|
707
449
|
}
|
|
708
|
-
|
|
709
450
|
if (item.until) {
|
|
710
451
|
tmp.until = [item.until[0].toString(), item.until[1]];
|
|
711
452
|
}
|
|
712
|
-
|
|
713
453
|
return tmp;
|
|
714
454
|
});
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
} else if (action === SequenceAction.WireJump) {
|
|
455
|
+
this.print(ExecutionScope_js_1.SequenceAction.Wire, wireId, JSON.stringify(wireSegmentsInfo));
|
|
456
|
+
}
|
|
457
|
+
else if (action === ExecutionScope_js_1.SequenceAction.WireJump) {
|
|
720
458
|
this.print(...sequence[i]);
|
|
721
|
-
const wireId = sequence[i][1]
|
|
459
|
+
const wireId = sequence[i][1];
|
|
722
460
|
const wireName = getWireName(wireId);
|
|
723
|
-
|
|
724
461
|
let wirePin = 1;
|
|
725
|
-
|
|
726
462
|
if (sequence[i].length === 3) {
|
|
727
|
-
wirePin = sequence[i][2]
|
|
463
|
+
wirePin = sequence[i][2];
|
|
728
464
|
}
|
|
729
|
-
|
|
730
465
|
previousNode = wireName;
|
|
731
|
-
previousPin = wirePin;
|
|
732
|
-
}
|
|
466
|
+
previousPin = wirePin;
|
|
467
|
+
}
|
|
468
|
+
else if (action === ExecutionScope_js_1.SequenceAction.Frame) {
|
|
733
469
|
const [, frameObject, frameAction] = sequence[i];
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
const prevFrame = frameStack[frameStack.length-1];
|
|
737
|
-
|
|
470
|
+
if (frameAction === ExecutionScope_js_1.FrameAction.Enter) {
|
|
471
|
+
const prevFrame = frameStack[frameStack.length - 1];
|
|
738
472
|
const newFrame = new RenderFrame(frameObject);
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
frameObject.parameters.get(FrameParamKeys.Direction);
|
|
473
|
+
if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Direction)) {
|
|
474
|
+
newFrame.direction =
|
|
475
|
+
frameObject.parameters.get(Frame_js_1.FrameParamKeys.Direction);
|
|
743
476
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
frameObject.parameters.get(FrameParamKeys.Padding);
|
|
477
|
+
if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Padding)) {
|
|
478
|
+
newFrame.padding =
|
|
479
|
+
frameObject.parameters.get(Frame_js_1.FrameParamKeys.Padding);
|
|
748
480
|
}
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
frameObject.parameters.get(FrameParamKeys.Border);
|
|
481
|
+
if (frameObject.parameters.has(Frame_js_1.FrameParamKeys.Border)) {
|
|
482
|
+
newFrame.borderWidth =
|
|
483
|
+
frameObject.parameters.get(Frame_js_1.FrameParamKeys.Border);
|
|
753
484
|
}
|
|
754
|
-
|
|
755
485
|
containerFrames.push(newFrame);
|
|
756
486
|
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
487
|
prevFrame && prevFrame.innerItems.push(newFrame);
|
|
762
|
-
|
|
763
|
-
|
|
488
|
+
}
|
|
489
|
+
else if (frameAction === ExecutionScope_js_1.FrameAction.Exit) {
|
|
764
490
|
frameStack.pop();
|
|
765
491
|
}
|
|
766
492
|
}
|
|
767
493
|
}
|
|
768
|
-
|
|
769
494
|
return {
|
|
770
495
|
graph,
|
|
771
496
|
containerFrames,
|
|
772
|
-
}
|
|
497
|
+
};
|
|
773
498
|
}
|
|
774
|
-
|
|
775
|
-
setGraphEdge(graph: graphlib.Graph, node1: string, node2: string,
|
|
776
|
-
edgeValue: EdgeValue): void {
|
|
499
|
+
setGraphEdge(graph, node1, node2, edgeValue) {
|
|
777
500
|
graph.setEdge(node1, node2, edgeValue);
|
|
778
501
|
}
|
|
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);
|
|
502
|
+
sizeSubGraphs(graph) {
|
|
503
|
+
const subGraphs = graphlib_1.alg.components(graph);
|
|
786
504
|
const subGraphsStarts = [];
|
|
787
|
-
|
|
788
505
|
this.print('===== placing subgraphs =====');
|
|
789
506
|
this.print('number of subgraphs: ', subGraphs.length);
|
|
790
|
-
|
|
791
|
-
const subgraphInfo: SubGraphInfo[] = [];
|
|
792
|
-
|
|
793
|
-
// Find the starting point of the graph
|
|
507
|
+
const subgraphInfo = [];
|
|
794
508
|
subGraphs.forEach(innerGraph => {
|
|
795
|
-
// Find node with the lowest sequence number and used
|
|
796
|
-
// as the starting node
|
|
797
|
-
|
|
798
509
|
let smallestNodeIdLevel = Number.POSITIVE_INFINITY;
|
|
799
|
-
let smallestNodeId
|
|
800
|
-
|
|
510
|
+
let smallestNodeId = null;
|
|
801
511
|
innerGraph.forEach(nodeId => {
|
|
802
512
|
const [, , sequenceId] = graph.node(nodeId);
|
|
803
|
-
|
|
804
513
|
if (sequenceId < smallestNodeIdLevel) {
|
|
805
514
|
smallestNodeIdLevel = sequenceId;
|
|
806
515
|
smallestNodeId = nodeId;
|
|
807
516
|
}
|
|
808
517
|
});
|
|
809
|
-
|
|
810
518
|
subGraphsStarts.push(smallestNodeId);
|
|
811
519
|
});
|
|
812
|
-
|
|
813
|
-
|
|
814
520
|
subGraphsStarts.forEach((nodeId, index) => {
|
|
815
521
|
const innerGraph = subGraphs[index];
|
|
816
|
-
|
|
817
522
|
this.print('walk and place nodes in subgraph at index', index);
|
|
818
523
|
this.print('starting node', nodeId);
|
|
819
|
-
|
|
820
524
|
this.walkAndPlaceGraph(graph, nodeId, innerGraph);
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
const renderItems: (RenderComponent | RenderText)[] = [];
|
|
824
|
-
|
|
825
|
-
const wires: RenderWire[] = [];
|
|
826
|
-
|
|
525
|
+
const renderItems = [];
|
|
526
|
+
const wires = [];
|
|
827
527
|
innerGraph.forEach(nodeId => {
|
|
828
528
|
const [nodeType, item,] = graph.node(nodeId);
|
|
829
529
|
if (nodeType === RenderItemType.Component) {
|
|
830
530
|
renderItems.push(item);
|
|
831
|
-
}
|
|
531
|
+
}
|
|
532
|
+
else if (nodeType === RenderItemType.Wire) {
|
|
832
533
|
wires.push(item);
|
|
833
534
|
}
|
|
834
535
|
});
|
|
835
|
-
|
|
836
|
-
// Get the existing bounds
|
|
837
536
|
const bounds = getBounds(renderItems, wires, [], []);
|
|
838
|
-
|
|
839
537
|
subgraphInfo.push({
|
|
840
538
|
firstNodeId: nodeId,
|
|
841
539
|
components: innerGraph,
|
|
842
540
|
bounds,
|
|
843
541
|
});
|
|
844
542
|
});
|
|
845
|
-
|
|
846
|
-
// For each subgraph, find the bounds of the subgraph
|
|
847
543
|
return subgraphInfo;
|
|
848
544
|
}
|
|
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
|
-
|
|
545
|
+
walkAndPlaceGraph(graph, firstNodeId, subgraphNodes) {
|
|
856
546
|
const allEdges = graph.edges();
|
|
857
|
-
|
|
858
547
|
const subgraphEdges = allEdges.reduce((accum, edge) => {
|
|
859
548
|
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
549
|
if (subgraphNodes.indexOf(v) !== -1) {
|
|
863
550
|
accum.push(edge);
|
|
864
551
|
}
|
|
865
552
|
return accum;
|
|
866
|
-
}, []
|
|
867
|
-
|
|
868
|
-
if (this.placeSubgraphVersion === 1){
|
|
553
|
+
}, []);
|
|
554
|
+
if (this.placeSubgraphVersion === 1) {
|
|
869
555
|
this.placeSubgraph(graph, firstNodeId, subgraphEdges);
|
|
870
|
-
}
|
|
556
|
+
}
|
|
557
|
+
else if (this.placeSubgraphVersion === 2) {
|
|
871
558
|
this.placeSubgraphV2(graph, firstNodeId, subgraphEdges);
|
|
872
559
|
}
|
|
873
560
|
}
|
|
874
|
-
|
|
875
|
-
placeSubgraphV2(graph:graphlib.Graph, firstNodeId: string,
|
|
876
|
-
subgraphEdges: graphlib.Edge[]): void {
|
|
877
|
-
|
|
561
|
+
placeSubgraphV2(graph, firstNodeId, subgraphEdges) {
|
|
878
562
|
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 {
|
|
563
|
+
const originNodes = [];
|
|
564
|
+
const originNodeGroups = new Map();
|
|
565
|
+
function findOriginNode(node) {
|
|
894
566
|
const keys = Array.from(originNodeGroups.keys());
|
|
895
|
-
|
|
896
567
|
for (let i = 0; i < keys.length; i++) {
|
|
897
568
|
const nodesLinkedToOrigin = originNodeGroups.get(keys[i]);
|
|
898
569
|
if (nodesLinkedToOrigin.indexOf(node) !== -1) {
|
|
899
570
|
return keys[i];
|
|
900
571
|
}
|
|
901
572
|
}
|
|
902
|
-
|
|
903
573
|
return null;
|
|
904
574
|
}
|
|
905
|
-
|
|
906
575
|
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
|
|
576
|
+
const [, node1] = graph.node(firstNodeId);
|
|
912
577
|
this.placeNodeAtPosition(0, 0, node1, 1);
|
|
913
578
|
return;
|
|
914
579
|
}
|
|
915
|
-
|
|
916
580
|
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
|
-
|
|
581
|
+
const [nodeId1, pin1, nodeId2, pin2] = graph.edge(edge);
|
|
582
|
+
const [, node1] = graph.node(nodeId1);
|
|
583
|
+
const [, node2] = graph.node(nodeId2);
|
|
923
584
|
if (nodeId1 === firstNodeId && !firstNodePlaced) {
|
|
924
585
|
this.print('first node placed at origin');
|
|
925
586
|
this.placeNodeAtPosition(0, 0, node1, pin1);
|
|
926
587
|
firstNodePlaced = true;
|
|
927
588
|
node1.isFloating = false;
|
|
928
|
-
|
|
929
589
|
originNodes.push(node1);
|
|
930
590
|
originNodeGroups.set(node1.toString(), [node1]);
|
|
931
591
|
}
|
|
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
|
-
|
|
592
|
+
let fixedNode;
|
|
593
|
+
let fixedNodePin;
|
|
594
|
+
let floatingNode;
|
|
595
|
+
let floatingNodePin;
|
|
596
|
+
this.print('edge:', '[', node1, pin1, node1.isFloating, ']', '[', node2, pin2, node2.isFloating, ']');
|
|
942
597
|
if (!node1.isFloating && node2.isFloating) {
|
|
943
598
|
fixedNode = node1;
|
|
944
599
|
fixedNodePin = pin1;
|
|
945
|
-
|
|
946
600
|
floatingNode = node2;
|
|
947
601
|
floatingNodePin = pin2;
|
|
948
|
-
|
|
949
|
-
|
|
602
|
+
}
|
|
603
|
+
else if (node1.isFloating && !node2.isFloating) {
|
|
950
604
|
fixedNode = node2;
|
|
951
605
|
fixedNodePin = pin2;
|
|
952
|
-
|
|
953
606
|
floatingNode = node1;
|
|
954
607
|
floatingNodePin = pin1;
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
// If both nodes are floating, then set node1 as an origin node
|
|
958
|
-
// and set it as not floating.
|
|
608
|
+
}
|
|
609
|
+
else if (node1.isFloating && node2.isFloating) {
|
|
959
610
|
originNodes.push(node1);
|
|
960
611
|
originNodeGroups.set(node1.toString(), [node1]);
|
|
961
612
|
this.print('creating new origin node at', node1);
|
|
962
|
-
|
|
963
613
|
this.placeNodeAtPosition(0, 0, node1, pin1);
|
|
964
614
|
node1.isFloating = false;
|
|
965
|
-
|
|
966
615
|
fixedNode = node1;
|
|
967
616
|
fixedNodePin = pin1;
|
|
968
|
-
|
|
969
617
|
floatingNode = node2;
|
|
970
618
|
floatingNodePin = pin2;
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
// If both nodes are fixed, then check how to merge them
|
|
619
|
+
}
|
|
620
|
+
else if (!node1.isFloating && !node2.isFloating) {
|
|
974
621
|
const originNode1 = findOriginNode(node1);
|
|
975
622
|
const originNode2 = findOriginNode(node2);
|
|
976
|
-
|
|
977
623
|
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
|
|
624
|
+
if (originNode1 !== originNode2) {
|
|
625
|
+
this.mergeOriginNodes(node1, pin1, node2, pin2, originNode1, originNode2, originNodes, originNodeGroups);
|
|
626
|
+
}
|
|
627
|
+
else {
|
|
989
628
|
const [x1, y1] = getNodePositionAtPin(node1, pin1);
|
|
990
629
|
const [x2, y2] = getNodePositionAtPin(node2, pin2);
|
|
991
630
|
if (x1 !== x2 && y1 !== y2) {
|
|
992
631
|
if (node1 instanceof RenderWire &&
|
|
993
632
|
node2 instanceof RenderComponent) {
|
|
994
|
-
|
|
995
633
|
const refdes = node2.component.assignedRefDes;
|
|
996
634
|
this.layoutWarnings.push(`component ${refdes} may not be placed correctly`);
|
|
997
635
|
}
|
|
998
636
|
}
|
|
999
637
|
}
|
|
1000
638
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
this.print('place floating node', floatingNode, 'pin', floatingNodePin,
|
|
1004
|
-
'to', fixedNode, 'pin', fixedNodePin);
|
|
1005
|
-
|
|
639
|
+
if (fixedNode && floatingNode) {
|
|
640
|
+
this.print('place floating node', floatingNode, 'pin', floatingNodePin, 'to', fixedNode, 'pin', fixedNodePin);
|
|
1006
641
|
const [x, y] = getNodePositionAtPin(fixedNode, fixedNodePin);
|
|
1007
642
|
this.placeNodeAtPosition(x, y, floatingNode, floatingNodePin);
|
|
1008
643
|
floatingNode.isFloating = false;
|
|
1009
|
-
|
|
1010
644
|
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
645
|
const originNode = findOriginNode(fixedNode);
|
|
1015
646
|
originNodeGroups.get(originNode).push(floatingNode);
|
|
1016
647
|
this.print('linking node', floatingNode, 'to origin node', originNode);
|
|
1017
648
|
}
|
|
1018
|
-
|
|
1019
649
|
[node1, node2].forEach(item => {
|
|
1020
|
-
if (item instanceof RenderWire && item.isEndAutoLength()){
|
|
650
|
+
if (item instanceof RenderWire && item.isEndAutoLength()) {
|
|
1021
651
|
this.print('auto length wire', item);
|
|
1022
|
-
|
|
1023
652
|
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;
|
|
653
|
+
const [, targetNode] = graph.node(instance.instanceName);
|
|
654
|
+
if (targetNode.isFloating) {
|
|
655
|
+
throw "Cannot create auto wire with floating node! Wire id: " + item.id + " to node " + instance + " pin " + pin;
|
|
1029
656
|
}
|
|
1030
|
-
|
|
1031
657
|
const [untilX, untilY] = getNodePositionAtPin(targetNode, pin);
|
|
1032
658
|
item.setEndAuto(untilX, untilY);
|
|
1033
659
|
}
|
|
1034
660
|
});
|
|
1035
|
-
|
|
1036
661
|
});
|
|
1037
662
|
}
|
|
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
|
|
663
|
+
mergeOriginNodes(node1, pin1, node2, pin2, originNode1, originNode2, originNodes, originNodeGroups) {
|
|
1046
664
|
const originNode1Index = originNodes.findIndex(item => {
|
|
1047
665
|
return item.toString() === originNode1;
|
|
1048
666
|
});
|
|
1049
|
-
|
|
1050
667
|
const originNode2Index = originNodes.findIndex(item => {
|
|
1051
668
|
return item.toString() === originNode2;
|
|
1052
669
|
});
|
|
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){
|
|
670
|
+
let keepOriginNode;
|
|
671
|
+
let otherOriginNode;
|
|
672
|
+
let fixedNode;
|
|
673
|
+
let fixedNodePin;
|
|
674
|
+
let mergedNode;
|
|
675
|
+
let mergedNodePin;
|
|
676
|
+
if (originNode1Index < originNode2Index) {
|
|
1066
677
|
keepOriginNode = originNode1;
|
|
1067
678
|
otherOriginNode = originNode2;
|
|
1068
|
-
|
|
1069
679
|
fixedNode = node1;
|
|
1070
680
|
fixedNodePin = pin1;
|
|
1071
|
-
|
|
1072
681
|
mergedNode = node2;
|
|
1073
682
|
mergedNodePin = pin2;
|
|
1074
|
-
|
|
1075
|
-
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
1076
685
|
keepOriginNode = originNode2;
|
|
1077
686
|
otherOriginNode = originNode1;
|
|
1078
|
-
|
|
1079
687
|
fixedNode = node2;
|
|
1080
688
|
fixedNodePin = pin2;
|
|
1081
|
-
|
|
1082
689
|
mergedNode = node1;
|
|
1083
690
|
mergedNodePin = pin1;
|
|
1084
691
|
}
|
|
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.
|
|
692
|
+
this.print('merging origin node groups, fixed:', keepOriginNode, ', other:', otherOriginNode);
|
|
1091
693
|
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
|
|
694
|
+
const [otherNodeOriginX, otherNodeOriginY] = getNodePositionAtPin(mergedNode, mergedNodePin);
|
|
695
|
+
const offsetX = x - otherNodeOriginX;
|
|
1099
696
|
const offsetY = y - otherNodeOriginY;
|
|
1100
|
-
|
|
1101
697
|
this.print('offset of other origin:', offsetX, offsetY);
|
|
1102
|
-
|
|
1103
698
|
const otherItemsLinkedToOriginNode = originNodeGroups.get(otherOriginNode);
|
|
1104
|
-
this.print('nodes in other origin:'
|
|
1105
|
-
|
|
699
|
+
this.print('nodes in other origin:', otherItemsLinkedToOriginNode);
|
|
1106
700
|
otherItemsLinkedToOriginNode.forEach(item => {
|
|
1107
701
|
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.
|
|
702
|
+
});
|
|
1112
703
|
const newList = originNodeGroups.get(keepOriginNode)
|
|
1113
704
|
.concat(otherItemsLinkedToOriginNode);
|
|
1114
|
-
|
|
1115
705
|
originNodeGroups.set(keepOriginNode, newList);
|
|
1116
|
-
|
|
1117
|
-
// Remove other node origin as a key
|
|
1118
706
|
originNodeGroups.delete(otherOriginNode);
|
|
1119
|
-
|
|
1120
707
|
this.print('removed other origin');
|
|
1121
708
|
this.print('merge completed');
|
|
1122
709
|
}
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
placeSubgraph(graph: graphlib.Graph, firstNodeId: string,
|
|
1126
|
-
subgraphEdges: graphlib.Edge[]): void {
|
|
1127
|
-
|
|
710
|
+
placeSubgraph(graph, firstNodeId, subgraphEdges) {
|
|
1128
711
|
let firstNodePlaced = false;
|
|
1129
|
-
|
|
1130
712
|
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
|
-
|
|
713
|
+
const [nodeId1, pin1, nodeId2, pin2] = graph.edge(edge);
|
|
714
|
+
const [, node1] = graph.node(nodeId1);
|
|
715
|
+
const [, node2] = graph.node(nodeId2);
|
|
1137
716
|
if (nodeId1 === firstNodeId && !firstNodePlaced) {
|
|
1138
717
|
this.print('first node placed at origin');
|
|
1139
718
|
this.placeNodeAtPosition(0, 0, node1, pin1);
|
|
1140
719
|
firstNodePlaced = true;
|
|
1141
720
|
node1.isFloating = false;
|
|
1142
721
|
}
|
|
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
|
-
|
|
722
|
+
let fixedNode;
|
|
723
|
+
let fixedNodePin;
|
|
724
|
+
let floatingNode;
|
|
725
|
+
let floatingNodePin;
|
|
726
|
+
this.print('edge:', '[', node1, pin1, node1.isFloating, ']', '[', node2, pin2, node2.isFloating, ']');
|
|
1153
727
|
if (!node1.isFloating && node2.isFloating) {
|
|
1154
728
|
fixedNode = node1;
|
|
1155
729
|
fixedNodePin = pin1;
|
|
1156
|
-
|
|
1157
730
|
floatingNode = node2;
|
|
1158
731
|
floatingNodePin = pin2;
|
|
1159
|
-
|
|
1160
|
-
|
|
732
|
+
}
|
|
733
|
+
else if (node1.isFloating && !node2.isFloating) {
|
|
1161
734
|
fixedNode = node2;
|
|
1162
735
|
fixedNodePin = pin2;
|
|
1163
|
-
|
|
1164
736
|
floatingNode = node1;
|
|
1165
737
|
floatingNodePin = pin1;
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
this.print('both nodes are floating', node1, 'pin', pin1,
|
|
1169
|
-
'and', node2, 'pin', pin2);
|
|
738
|
+
}
|
|
739
|
+
else if (node1.isFloating && node2.isFloating) {
|
|
740
|
+
this.print('both nodes are floating', node1, 'pin', pin1, 'and', node2, 'pin', pin2);
|
|
1170
741
|
node1.floatingRelativeTo.push([pin1, nodeId2, pin2]);
|
|
1171
742
|
node2.floatingRelativeTo.push([pin2, nodeId1, pin1]);
|
|
1172
743
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
this.print('place floating node', floatingNode, 'pin', floatingNodePin,
|
|
1176
|
-
'to', fixedNode, 'pin', fixedNodePin);
|
|
1177
|
-
|
|
744
|
+
if (fixedNode && floatingNode) {
|
|
745
|
+
this.print('place floating node', floatingNode, 'pin', floatingNodePin, 'to', fixedNode, 'pin', fixedNodePin);
|
|
1178
746
|
const [x, y] = getNodePositionAtPin(fixedNode, fixedNodePin);
|
|
1179
747
|
this.placeNodeAtPosition(x, y, floatingNode, floatingNodePin);
|
|
1180
748
|
floatingNode.isFloating = false;
|
|
1181
|
-
|
|
1182
749
|
this.placeFloatingItems(graph, floatingNode);
|
|
1183
750
|
}
|
|
1184
|
-
|
|
1185
751
|
[node1, node2].forEach(item => {
|
|
1186
|
-
if (item instanceof RenderWire){
|
|
1187
|
-
|
|
1188
|
-
if (item.isEndAutoLength()){
|
|
752
|
+
if (item instanceof RenderWire) {
|
|
753
|
+
if (item.isEndAutoLength()) {
|
|
1189
754
|
const [instance, pin] = item.getEndAuto();
|
|
1190
|
-
const [, targetNode]
|
|
1191
|
-
graph.node(instance.instanceName);
|
|
1192
|
-
|
|
755
|
+
const [, targetNode] = graph.node(instance.instanceName);
|
|
1193
756
|
const [untilX, untilY] = getNodePositionAtPin(targetNode, pin);
|
|
1194
757
|
item.setEndAuto(untilX, untilY);
|
|
1195
758
|
}
|
|
1196
|
-
}
|
|
759
|
+
}
|
|
1197
760
|
});
|
|
1198
761
|
});
|
|
1199
762
|
}
|
|
1200
|
-
|
|
1201
|
-
translateNodeBy(offsetX: number, offsetY: number, item: RenderItem): void {
|
|
763
|
+
translateNodeBy(offsetX, offsetY, item) {
|
|
1202
764
|
item.x += offsetX;
|
|
1203
765
|
item.y += offsetY;
|
|
1204
766
|
}
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
if (item instanceof RenderComponent){
|
|
767
|
+
placeNodeAtPosition(fromX, fromY, item, pin, depth = 0) {
|
|
768
|
+
if (item instanceof RenderComponent) {
|
|
1208
769
|
const pinPosition = item.symbol.pinPosition(pin);
|
|
1209
770
|
item.x = fromX - pinPosition.x;
|
|
1210
|
-
item.y = fromY - pinPosition.y;
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
if (pin === 0) {
|
|
771
|
+
item.y = fromY - pinPosition.y;
|
|
772
|
+
}
|
|
773
|
+
else if (item instanceof RenderWire) {
|
|
774
|
+
if (pin === 0) {
|
|
1214
775
|
item.x = fromX;
|
|
1215
776
|
item.y = fromY;
|
|
1216
|
-
}
|
|
777
|
+
}
|
|
778
|
+
else {
|
|
1217
779
|
const wireEnd = item.getWireEnd();
|
|
1218
780
|
item.x = fromX - wireEnd.x;
|
|
1219
781
|
item.y = fromY - wireEnd.y;
|
|
1220
782
|
}
|
|
1221
783
|
}
|
|
1222
|
-
|
|
1223
784
|
this.print(this.padLevel(depth), 'place', item, 'pin', pin, 'at', item.x, item.y);
|
|
1224
785
|
}
|
|
1225
|
-
|
|
1226
|
-
placeFloatingItems(graph: graphlib.Graph, item: RenderItem, depth = 0): void {
|
|
1227
|
-
// Assume that item already has a fixed position
|
|
1228
|
-
|
|
786
|
+
placeFloatingItems(graph, item, depth = 0) {
|
|
1229
787
|
if (depth > 100) {
|
|
1230
788
|
throw "Too many levels when placing floating items";
|
|
1231
789
|
}
|
|
1232
|
-
|
|
1233
790
|
const { floatingRelativeTo = [] } = item;
|
|
1234
|
-
|
|
1235
|
-
if (floatingRelativeTo.length > 0){
|
|
1236
|
-
|
|
791
|
+
if (floatingRelativeTo.length > 0) {
|
|
1237
792
|
this.print(this.padLevel(depth), 'place relative to', item);
|
|
1238
|
-
this.print(this.padLevel(depth), 'relative to',
|
|
1239
|
-
JSON.stringify(floatingRelativeTo));
|
|
1240
|
-
|
|
793
|
+
this.print(this.padLevel(depth), 'relative to', JSON.stringify(floatingRelativeTo));
|
|
1241
794
|
floatingRelativeTo.forEach(entry => {
|
|
1242
795
|
const [selfPin, nodeId, pin] = entry;
|
|
1243
796
|
const [, tmpNode] = graph.node(nodeId);
|
|
1244
|
-
|
|
1245
797
|
if (tmpNode.isFloating) {
|
|
1246
798
|
const [x, y] = getNodePositionAtPin(item, selfPin);
|
|
1247
799
|
this.placeNodeAtPosition(x, y, tmpNode, pin, depth);
|
|
1248
800
|
tmpNode.isFloating = false;
|
|
1249
|
-
|
|
1250
801
|
this.placeFloatingItems(graph, tmpNode, depth + 1);
|
|
1251
|
-
}
|
|
802
|
+
}
|
|
803
|
+
else {
|
|
1252
804
|
this.print(this.padLevel(depth), 'skipping', tmpNode, 'as it is not floating');
|
|
1253
805
|
}
|
|
1254
806
|
});
|
|
1255
|
-
|
|
1256
807
|
this.print(this.padLevel(depth), '<<< done traversing floating nodes');
|
|
1257
|
-
}
|
|
808
|
+
}
|
|
809
|
+
else {
|
|
1258
810
|
this.print(this.padLevel(depth), 'no nodes floating relative to', item);
|
|
1259
811
|
}
|
|
1260
812
|
}
|
|
1261
|
-
|
|
1262
|
-
printWarnings(): void {
|
|
813
|
+
printWarnings() {
|
|
1263
814
|
this.layoutWarnings.forEach(message => {
|
|
1264
815
|
console.log('Warning: ' + message);
|
|
1265
816
|
});
|
|
1266
817
|
}
|
|
1267
818
|
}
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
if (item instanceof RenderComponent){
|
|
819
|
+
exports.LayoutEngine = LayoutEngine;
|
|
820
|
+
function getNodePositionAtPin(item, pin) {
|
|
821
|
+
if (item instanceof RenderComponent) {
|
|
1272
822
|
const pinPosition = item.symbol.pinPosition(pin);
|
|
1273
823
|
return [
|
|
1274
824
|
item.x + pinPosition.x,
|
|
1275
825
|
item.y + pinPosition.y
|
|
1276
826
|
];
|
|
1277
|
-
}
|
|
1278
|
-
|
|
827
|
+
}
|
|
828
|
+
else if (item instanceof RenderWire) {
|
|
829
|
+
if (pin === 0) {
|
|
1279
830
|
return [item.x, item.y];
|
|
1280
|
-
}
|
|
831
|
+
}
|
|
832
|
+
else {
|
|
1281
833
|
const wireEnd = item.getWireEnd();
|
|
1282
|
-
|
|
1283
834
|
return [
|
|
1284
835
|
item.x + wireEnd.x,
|
|
1285
836
|
item.y + wireEnd.y
|
|
1286
|
-
]
|
|
837
|
+
];
|
|
1287
838
|
}
|
|
1288
839
|
}
|
|
1289
840
|
}
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
function getNeighbours(graph: graphlib.Graph, nodeIds: string[]): [from: string, to: string][] {
|
|
1293
|
-
|
|
841
|
+
function getNeighbours(graph, nodeIds) {
|
|
1294
842
|
return nodeIds.reduce((accum, nodeId) => {
|
|
1295
843
|
const tmp = graph.neighbors(nodeId);
|
|
1296
844
|
if (tmp) {
|
|
@@ -1299,57 +847,40 @@ function getNeighbours(graph: graphlib.Graph, nodeIds: string[]): [from: string,
|
|
|
1299
847
|
});
|
|
1300
848
|
}
|
|
1301
849
|
return accum;
|
|
1302
|
-
}, []
|
|
850
|
+
}, []);
|
|
1303
851
|
}
|
|
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 {
|
|
852
|
+
function makeEdgeValue(instanceName1, instancePin1, instanceName2, instancePin2, priority) {
|
|
1311
853
|
return [instanceName1, instancePin1, instanceName2, instancePin2, priority];
|
|
1312
|
-
// return `${instanceName1}:pin:${instancePin1} -- ${instanceName2}:pin:${instancePin2}`;
|
|
1313
854
|
}
|
|
1314
|
-
|
|
1315
|
-
function getWireName(wireId: number): string {
|
|
855
|
+
function getWireName(wireId) {
|
|
1316
856
|
return 'wire:' + wireId;
|
|
1317
857
|
}
|
|
1318
|
-
|
|
1319
|
-
type RenderItem = RenderComponent | RenderWire | RenderText;
|
|
1320
|
-
|
|
1321
|
-
function generateLayoutPinDefinition(component: ClassComponent): SymbolPinDefintion[] {
|
|
858
|
+
function generateLayoutPinDefinition(component) {
|
|
1322
859
|
const pins = component.pins;
|
|
1323
|
-
const symbolPinDefinitions
|
|
860
|
+
const symbolPinDefinitions = [];
|
|
1324
861
|
const existingPinIds = Array.from(pins.keys());
|
|
1325
|
-
|
|
1326
862
|
if (component.arrangeProps === null) {
|
|
1327
|
-
// Automatically split pins
|
|
1328
863
|
for (let i = 0; i < existingPinIds.length; i++) {
|
|
1329
|
-
const pinPosition = Math.floor(i/2);
|
|
1330
|
-
|
|
864
|
+
const pinPosition = Math.floor(i / 2);
|
|
1331
865
|
symbolPinDefinitions.push({
|
|
1332
866
|
side: (i % 2 === 0) ? "left" : "right",
|
|
1333
867
|
pinId: existingPinIds[i],
|
|
1334
868
|
text: pins.get(existingPinIds[i]).name,
|
|
1335
869
|
position: pinPosition,
|
|
1336
|
-
})
|
|
870
|
+
});
|
|
1337
871
|
}
|
|
1338
|
-
}
|
|
872
|
+
}
|
|
873
|
+
else {
|
|
1339
874
|
const addedPins = [];
|
|
1340
|
-
|
|
1341
875
|
for (const [key, items] of component.arrangeProps) {
|
|
1342
|
-
|
|
1343
876
|
let useItems;
|
|
1344
|
-
if (!Array.isArray(items)){
|
|
877
|
+
if (!Array.isArray(items)) {
|
|
1345
878
|
useItems = [items];
|
|
1346
|
-
}
|
|
1347
|
-
|
|
879
|
+
}
|
|
880
|
+
else {
|
|
1348
881
|
useItems = [...items];
|
|
1349
882
|
}
|
|
1350
|
-
|
|
1351
883
|
useItems.forEach(pinId => {
|
|
1352
|
-
// Only use the pin if it exists!
|
|
1353
884
|
if (existingPinIds.indexOf(pinId) !== -1) {
|
|
1354
885
|
symbolPinDefinitions.push({
|
|
1355
886
|
side: key,
|
|
@@ -1361,55 +892,42 @@ function generateLayoutPinDefinition(component: ClassComponent): SymbolPinDefint
|
|
|
1361
892
|
}
|
|
1362
893
|
});
|
|
1363
894
|
}
|
|
1364
|
-
|
|
1365
|
-
// Make sure all existing pins are added, otherwise throw an error
|
|
1366
895
|
const unplacedPins = [];
|
|
1367
896
|
existingPinIds.forEach(item => {
|
|
1368
|
-
if (addedPins.indexOf(item) === -1){
|
|
897
|
+
if (addedPins.indexOf(item) === -1) {
|
|
1369
898
|
unplacedPins.push(item);
|
|
1370
899
|
}
|
|
1371
900
|
});
|
|
1372
|
-
|
|
1373
|
-
if (unplacedPins.length > 0){
|
|
901
|
+
if (unplacedPins.length > 0) {
|
|
1374
902
|
throw "'arrange' property is defined, but not all pins are specified: " + unplacedPins.join(",");
|
|
1375
903
|
}
|
|
1376
904
|
}
|
|
1377
|
-
|
|
1378
905
|
return symbolPinDefinitions;
|
|
1379
906
|
}
|
|
1380
|
-
|
|
1381
|
-
function applyComponentParamsToSymbol(typeProp: string,
|
|
1382
|
-
component: ClassComponent, symbol: SymbolGraphic): void {
|
|
1383
|
-
|
|
907
|
+
function applyComponentParamsToSymbol(typeProp, component, symbol) {
|
|
1384
908
|
if (typeProp === 'net') {
|
|
1385
|
-
symbol.setLabelValue("net_name",
|
|
1386
|
-
component.parameters.get(ParamKeys.net_name) as string);
|
|
909
|
+
symbol.setLabelValue("net_name", component.parameters.get(globals_js_1.ParamKeys.net_name));
|
|
1387
910
|
}
|
|
1388
|
-
|
|
1389
|
-
if (component.assignedRefDes !== null){
|
|
911
|
+
if (component.assignedRefDes !== null) {
|
|
1390
912
|
symbol.setLabelValue("refdes", component.assignedRefDes);
|
|
1391
913
|
}
|
|
1392
|
-
|
|
1393
914
|
for (const [key, value] of component.parameters) {
|
|
1394
915
|
if (key !== 'refdes' && key !== 'net_name') {
|
|
1395
|
-
let useValue
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
916
|
+
let useValue;
|
|
917
|
+
if (typeof value == 'object' && (value instanceof ParamDefinition_js_1.NumericValue)) {
|
|
918
|
+
useValue = value.toDisplayString();
|
|
919
|
+
}
|
|
920
|
+
else if (typeof value === 'number') {
|
|
1400
921
|
useValue = value.toString();
|
|
1401
|
-
}
|
|
922
|
+
}
|
|
923
|
+
else if (typeof value === 'string') {
|
|
1402
924
|
useValue = value;
|
|
1403
925
|
}
|
|
1404
|
-
|
|
1405
926
|
symbol.setLabelValue(key, useValue);
|
|
1406
927
|
}
|
|
1407
928
|
}
|
|
1408
929
|
}
|
|
1409
|
-
|
|
1410
|
-
function calculateSymbolAngle(symbol: SymbolGraphic,
|
|
1411
|
-
pin: number, direction: string): number {
|
|
1412
|
-
|
|
930
|
+
function calculateSymbolAngle(symbol, pin, direction) {
|
|
1413
931
|
let directionVector = 0;
|
|
1414
932
|
switch (direction) {
|
|
1415
933
|
case 'right':
|
|
@@ -1425,118 +943,89 @@ function calculateSymbolAngle(symbol: SymbolGraphic,
|
|
|
1425
943
|
directionVector = 270;
|
|
1426
944
|
break;
|
|
1427
945
|
}
|
|
1428
|
-
|
|
1429
946
|
const { angle: pinVector } = symbol.pinPosition(pin);
|
|
1430
947
|
const useAngle = directionVector - (pinVector % 360);
|
|
1431
|
-
|
|
1432
948
|
return useAngle;
|
|
1433
949
|
}
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
components: (RenderComponent|RenderText)[],
|
|
1437
|
-
wires: RenderWire[], junctions: RenderJunction[], frames: RenderFrame[]): BoundBox{
|
|
1438
|
-
|
|
1439
|
-
const points = [];
|
|
1440
|
-
|
|
950
|
+
function getBounds(components, wires, junctions, frames) {
|
|
951
|
+
const points = [];
|
|
1441
952
|
components.forEach(item => {
|
|
1442
953
|
const bbox = item.symbol.drawing.getBoundingBox();
|
|
1443
|
-
|
|
1444
954
|
const [x1, y1] = bbox.start;
|
|
1445
955
|
const [x2, y2] = bbox.end;
|
|
1446
|
-
|
|
1447
956
|
points.push([x1 + item.x, y1 + item.y]);
|
|
1448
957
|
points.push([x2 + item.x, y2 + item.y]);
|
|
1449
958
|
});
|
|
1450
|
-
|
|
1451
959
|
wires.forEach(wire => {
|
|
1452
960
|
wire.points.forEach(point => {
|
|
1453
961
|
points.push([wire.x + point.x, wire.y + point.y]);
|
|
1454
962
|
});
|
|
1455
963
|
});
|
|
1456
|
-
|
|
1457
964
|
junctions.forEach(item => {
|
|
1458
965
|
points.push([item.x, item.y]);
|
|
1459
966
|
});
|
|
1460
|
-
|
|
1461
967
|
frames.forEach(item => {
|
|
1462
|
-
const {width, height} = getBoundsSize(item.bounds);
|
|
968
|
+
const { width, height } = (0, utils_js_1.getBoundsSize)(item.bounds);
|
|
1463
969
|
points.push([item.x, item.y]);
|
|
1464
970
|
points.push([item.x + width, item.y + height]);
|
|
1465
|
-
})
|
|
1466
|
-
|
|
971
|
+
});
|
|
1467
972
|
return getBoundsFromPoints(points);
|
|
1468
973
|
}
|
|
1469
|
-
|
|
1470
|
-
function getBoundsFromPoints(points
|
|
974
|
+
exports.getBounds = getBounds;
|
|
975
|
+
function getBoundsFromPoints(points) {
|
|
1471
976
|
const xValues = points.map(item => item[0]);
|
|
1472
977
|
const yValues = points.map(item => item[1]);
|
|
1473
|
-
|
|
1474
978
|
const xmin = Math.min(...xValues);
|
|
1475
979
|
const xmax = Math.max(...xValues);
|
|
1476
|
-
|
|
1477
980
|
const ymin = Math.min(...yValues);
|
|
1478
981
|
const ymax = Math.max(...yValues);
|
|
1479
|
-
|
|
1480
982
|
return {
|
|
1481
983
|
xmin, xmax, ymin, ymax,
|
|
1482
|
-
}
|
|
984
|
+
};
|
|
1483
985
|
}
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
986
|
+
class RenderObject {
|
|
987
|
+
constructor() {
|
|
988
|
+
this.x = -1;
|
|
989
|
+
this.y = -1;
|
|
990
|
+
this.isFloating = true;
|
|
991
|
+
this.floatingRelativeTo = [];
|
|
992
|
+
}
|
|
1491
993
|
}
|
|
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[]) {
|
|
994
|
+
exports.RenderObject = RenderObject;
|
|
995
|
+
class RenderWire extends RenderObject {
|
|
996
|
+
constructor(x, y, segments) {
|
|
1504
997
|
super();
|
|
998
|
+
this.segments = [];
|
|
999
|
+
this.points = [];
|
|
1505
1000
|
this.x = x;
|
|
1506
1001
|
this.y = y;
|
|
1507
1002
|
this.segments = segments;
|
|
1508
|
-
|
|
1509
1003
|
this.refreshPoints();
|
|
1510
1004
|
}
|
|
1511
|
-
|
|
1512
|
-
refreshPoints(): void {
|
|
1005
|
+
refreshPoints() {
|
|
1513
1006
|
let tmpX = 0;
|
|
1514
1007
|
let tmpY = 0;
|
|
1515
|
-
|
|
1516
1008
|
const points = [{ x: tmpX, y: tmpY }];
|
|
1517
|
-
|
|
1518
1009
|
this.segments.forEach(segment => {
|
|
1519
1010
|
const { direction, value } = segment;
|
|
1520
|
-
|
|
1521
1011
|
let didAddPoint = false;
|
|
1522
|
-
|
|
1523
1012
|
if (direction === 'down') {
|
|
1524
1013
|
tmpY += value;
|
|
1525
|
-
}
|
|
1014
|
+
}
|
|
1015
|
+
else if (direction === 'up') {
|
|
1526
1016
|
tmpY -= value;
|
|
1527
|
-
}
|
|
1017
|
+
}
|
|
1018
|
+
else if (direction === 'left') {
|
|
1528
1019
|
tmpX -= value;
|
|
1529
|
-
}
|
|
1020
|
+
}
|
|
1021
|
+
else if (direction === 'right') {
|
|
1530
1022
|
tmpX += value;
|
|
1531
|
-
}
|
|
1532
|
-
|
|
1533
|
-
// uses the alternative path to the target.
|
|
1023
|
+
}
|
|
1024
|
+
else if (direction === 'auto' || direction === "auto_") {
|
|
1534
1025
|
const { valueXY = [0, 0] } = segment;
|
|
1535
|
-
|
|
1536
1026
|
const tmpPoints = this.getAutoPoints(valueXY, direction);
|
|
1537
|
-
|
|
1538
1027
|
tmpPoints.forEach(point => {
|
|
1539
|
-
if (point[0] !== 0 || point[1] !== 0){
|
|
1028
|
+
if (point[0] !== 0 || point[1] !== 0) {
|
|
1540
1029
|
tmpX += point[0];
|
|
1541
1030
|
tmpY += point[1];
|
|
1542
1031
|
points.push({ x: tmpX, y: tmpY });
|
|
@@ -1544,20 +1033,15 @@ export class RenderWire extends RenderObject {
|
|
|
1544
1033
|
});
|
|
1545
1034
|
didAddPoint = true;
|
|
1546
1035
|
}
|
|
1547
|
-
|
|
1548
|
-
if(!didAddPoint){
|
|
1036
|
+
if (!didAddPoint) {
|
|
1549
1037
|
points.push({ x: tmpX, y: tmpY });
|
|
1550
1038
|
}
|
|
1551
1039
|
});
|
|
1552
|
-
|
|
1553
1040
|
this.points = points;
|
|
1554
1041
|
}
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
const inQuadrant = Geometry.getQuadrant(value[0], value[1]);
|
|
1042
|
+
getAutoPoints(value, direction) {
|
|
1043
|
+
const inQuadrant = geometry_js_1.Geometry.getQuadrant(value[0], value[1]);
|
|
1558
1044
|
const [dx, dy] = value;
|
|
1559
|
-
|
|
1560
|
-
// Clockwise direction
|
|
1561
1045
|
if (direction === 'auto') {
|
|
1562
1046
|
switch (inQuadrant) {
|
|
1563
1047
|
case 0:
|
|
@@ -1567,7 +1051,8 @@ export class RenderWire extends RenderObject {
|
|
|
1567
1051
|
case 3:
|
|
1568
1052
|
return [[0, dy], [dx, 0]];
|
|
1569
1053
|
}
|
|
1570
|
-
}
|
|
1054
|
+
}
|
|
1055
|
+
else if (direction === 'auto_') {
|
|
1571
1056
|
switch (inQuadrant) {
|
|
1572
1057
|
case 0:
|
|
1573
1058
|
case 2:
|
|
@@ -1577,60 +1062,48 @@ export class RenderWire extends RenderObject {
|
|
|
1577
1062
|
return [[dx, 0], [0, dy]];
|
|
1578
1063
|
}
|
|
1579
1064
|
}
|
|
1580
|
-
|
|
1581
1065
|
return [[0, 0]];
|
|
1582
1066
|
}
|
|
1583
|
-
|
|
1584
|
-
getWireEnd(): { x: number, y: number } {
|
|
1067
|
+
getWireEnd() {
|
|
1585
1068
|
return this.points[this.points.length - 1];
|
|
1586
1069
|
}
|
|
1587
|
-
|
|
1588
|
-
isEndAutoLength(): boolean {
|
|
1070
|
+
isEndAutoLength() {
|
|
1589
1071
|
if (this.segments.length > 0) {
|
|
1590
|
-
// If only direction, then it is an auto length
|
|
1591
1072
|
return this.segments[this.segments.length - 1].value === null;
|
|
1592
1073
|
}
|
|
1593
|
-
|
|
1594
1074
|
return false;
|
|
1595
1075
|
}
|
|
1596
|
-
|
|
1597
|
-
getEndAuto(): [instance: ClassComponent, pin: number] {
|
|
1076
|
+
getEndAuto() {
|
|
1598
1077
|
if (this.segments.length > 0) {
|
|
1599
1078
|
return this.segments[this.segments.length - 1].until;
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1079
|
+
}
|
|
1080
|
+
else {
|
|
1081
|
+
throw "No segments in wire!";
|
|
1602
1082
|
}
|
|
1603
1083
|
}
|
|
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
|
-
|
|
1084
|
+
setEndAuto(untilX, untilY) {
|
|
1085
|
+
const excludeLastSegment = this.segments.slice(0, this.segments.length - 1);
|
|
1610
1086
|
let tmpX = this.x;
|
|
1611
1087
|
let tmpY = this.y;
|
|
1612
|
-
|
|
1613
1088
|
excludeLastSegment.forEach(segment => {
|
|
1614
1089
|
const { direction, value } = segment;
|
|
1615
1090
|
if (direction === 'down') {
|
|
1616
1091
|
tmpY += value;
|
|
1617
|
-
}
|
|
1092
|
+
}
|
|
1093
|
+
else if (direction === 'up') {
|
|
1618
1094
|
tmpY -= value;
|
|
1619
|
-
}
|
|
1095
|
+
}
|
|
1096
|
+
else if (direction === 'left') {
|
|
1620
1097
|
tmpX -= value;
|
|
1621
|
-
}
|
|
1098
|
+
}
|
|
1099
|
+
else if (direction === 'right') {
|
|
1622
1100
|
tmpX += value;
|
|
1623
1101
|
}
|
|
1624
1102
|
});
|
|
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
1103
|
let useValue = null;
|
|
1630
1104
|
let valueXY = null;
|
|
1631
|
-
const lastSegment = this.segments[this.segments.length-1];
|
|
1632
|
-
|
|
1633
|
-
switch(lastSegment.direction){
|
|
1105
|
+
const lastSegment = this.segments[this.segments.length - 1];
|
|
1106
|
+
switch (lastSegment.direction) {
|
|
1634
1107
|
case 'left':
|
|
1635
1108
|
useValue = tmpX - untilX;
|
|
1636
1109
|
break;
|
|
@@ -1643,174 +1116,112 @@ export class RenderWire extends RenderObject {
|
|
|
1643
1116
|
case 'down':
|
|
1644
1117
|
useValue = tmpY - untilY;
|
|
1645
1118
|
break;
|
|
1646
|
-
|
|
1647
1119
|
case 'auto':
|
|
1648
1120
|
case 'auto_':
|
|
1649
|
-
// Always assume positive values
|
|
1650
1121
|
valueXY = [
|
|
1651
1122
|
untilX - tmpX,
|
|
1652
1123
|
untilY - tmpY,
|
|
1653
1124
|
];
|
|
1654
|
-
|
|
1655
|
-
// Set to 0, to mark that auto length
|
|
1656
|
-
// calculation has already been done.
|
|
1657
1125
|
useValue = 0;
|
|
1658
1126
|
break;
|
|
1659
1127
|
}
|
|
1660
|
-
|
|
1661
1128
|
lastSegment.value = useValue;
|
|
1662
1129
|
lastSegment.valueXY = valueXY !== null ? valueXY : null;
|
|
1663
|
-
|
|
1664
1130
|
this.refreshPoints();
|
|
1665
1131
|
}
|
|
1666
|
-
|
|
1667
|
-
toString(): string {
|
|
1132
|
+
toString() {
|
|
1668
1133
|
return getWireName(this.id);
|
|
1669
1134
|
}
|
|
1670
1135
|
}
|
|
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) {
|
|
1136
|
+
exports.RenderWire = RenderWire;
|
|
1137
|
+
class RenderComponent extends RenderObject {
|
|
1138
|
+
constructor(component, width, height) {
|
|
1690
1139
|
super();
|
|
1140
|
+
this.displaySymbol = null;
|
|
1691
1141
|
this.component = component;
|
|
1692
1142
|
this.width = width;
|
|
1693
1143
|
this.height = height;
|
|
1694
1144
|
}
|
|
1695
|
-
|
|
1696
|
-
doesOverlap(other: RenderComponent): boolean {
|
|
1145
|
+
doesOverlap(other) {
|
|
1697
1146
|
const condition1 = isPointOverlap(this.x, this.y, other);
|
|
1698
1147
|
const condition2 = isPointOverlap(this.x + this.width, this.y, other);
|
|
1699
1148
|
const condition3 = isPointOverlap(this.x + this.width, this.y + this.height, other);
|
|
1700
1149
|
const condition4 = isPointOverlap(this.x, this.y + this.height, other);
|
|
1701
|
-
|
|
1702
|
-
return condition1 || condition2 || condition3 || condition4;
|
|
1150
|
+
return condition1 || condition2 || condition3 || condition4;
|
|
1703
1151
|
}
|
|
1704
|
-
|
|
1705
|
-
toString(): string {
|
|
1152
|
+
toString() {
|
|
1706
1153
|
return "component:" + this.component.instanceName;
|
|
1707
1154
|
}
|
|
1708
1155
|
}
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
_fontSize = 12;
|
|
1714
|
-
_fontWeight = 'regular';
|
|
1715
|
-
|
|
1716
|
-
get fontSize (): number {
|
|
1156
|
+
exports.RenderComponent = RenderComponent;
|
|
1157
|
+
class RenderText extends RenderObject {
|
|
1158
|
+
get fontSize() {
|
|
1717
1159
|
return this._fontSize;
|
|
1718
1160
|
}
|
|
1719
|
-
|
|
1720
|
-
set fontSize(value: number) {
|
|
1161
|
+
set fontSize(value) {
|
|
1721
1162
|
this._fontSize = value;
|
|
1722
1163
|
this.symbol.fontSize = value;
|
|
1723
1164
|
}
|
|
1724
|
-
|
|
1725
|
-
get fontWeight(): string {
|
|
1165
|
+
get fontWeight() {
|
|
1726
1166
|
return this._fontWeight;
|
|
1727
1167
|
}
|
|
1728
|
-
|
|
1729
|
-
set fontWeight(value: string) {
|
|
1168
|
+
set fontWeight(value) {
|
|
1730
1169
|
this._fontWeight = value;
|
|
1731
1170
|
this.symbol.fontWeight = value;
|
|
1732
1171
|
}
|
|
1733
|
-
|
|
1734
|
-
constructor(text: string) {
|
|
1172
|
+
constructor(text) {
|
|
1735
1173
|
super();
|
|
1736
|
-
this.
|
|
1174
|
+
this._fontSize = 12;
|
|
1175
|
+
this._fontWeight = 'regular';
|
|
1176
|
+
this.symbol = new draw_symbols_js_1.SymbolText(text);
|
|
1737
1177
|
}
|
|
1738
1178
|
}
|
|
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) {
|
|
1179
|
+
exports.RenderText = RenderText;
|
|
1180
|
+
class RenderFrame extends RenderObject {
|
|
1181
|
+
constructor(frame, type = RenderFrameType.Container) {
|
|
1767
1182
|
super();
|
|
1183
|
+
this.bounds = null;
|
|
1184
|
+
this.innerItems = [];
|
|
1185
|
+
this.translateX = 0;
|
|
1186
|
+
this.translateY = 0;
|
|
1187
|
+
this.padding = 20;
|
|
1188
|
+
this.gap = 20;
|
|
1189
|
+
this.direction = Frame_js_1.FramePlotDirection.Column;
|
|
1190
|
+
this.borderWidth = 1;
|
|
1191
|
+
this.subgraphId = "";
|
|
1192
|
+
this.containsTitle = false;
|
|
1768
1193
|
this.frame = frame;
|
|
1769
1194
|
this.type = type;
|
|
1770
1195
|
}
|
|
1771
|
-
|
|
1772
|
-
toString(): string {
|
|
1196
|
+
toString() {
|
|
1773
1197
|
let name = "";
|
|
1774
1198
|
if (this.type === RenderFrameType.Container) {
|
|
1775
1199
|
name = 'container_' + this.frame.frameId;
|
|
1776
|
-
}
|
|
1200
|
+
}
|
|
1201
|
+
else if (this.type === RenderFrameType.Elements) {
|
|
1777
1202
|
name = 'elements_' + this.subgraphId;
|
|
1778
1203
|
}
|
|
1779
|
-
|
|
1780
|
-
return name + ": " + this.x + "," + this.y + " bounds:" + printBounds(this.bounds);
|
|
1204
|
+
return name + ": " + this.x + "," + this.y + " bounds:" + (0, utils_js_1.printBounds)(this.bounds);
|
|
1781
1205
|
}
|
|
1782
1206
|
}
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
x
|
|
1791
|
-
y: number;
|
|
1792
|
-
|
|
1793
|
-
constructor(x: number, y: number){
|
|
1207
|
+
exports.RenderFrame = RenderFrame;
|
|
1208
|
+
var RenderFrameType;
|
|
1209
|
+
(function (RenderFrameType) {
|
|
1210
|
+
RenderFrameType[RenderFrameType["Container"] = 1] = "Container";
|
|
1211
|
+
RenderFrameType[RenderFrameType["Elements"] = 2] = "Elements";
|
|
1212
|
+
})(RenderFrameType || (exports.RenderFrameType = RenderFrameType = {}));
|
|
1213
|
+
class RenderJunction {
|
|
1214
|
+
constructor(x, y) {
|
|
1794
1215
|
this.x = x;
|
|
1795
1216
|
this.y = y;
|
|
1796
1217
|
}
|
|
1797
1218
|
}
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
function isPointOverlap(x: number, y: number, other: RenderComponent): boolean {
|
|
1219
|
+
exports.RenderJunction = RenderJunction;
|
|
1220
|
+
function isPointOverlap(x, y, other) {
|
|
1802
1221
|
return (x >= other.x && y >= other.y && x <= (other.x + other.width) && y <= (other.y + other.height));
|
|
1803
1222
|
}
|
|
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 };
|
|
1223
|
+
var RenderItemType;
|
|
1224
|
+
(function (RenderItemType) {
|
|
1225
|
+
RenderItemType["Wire"] = "wire";
|
|
1226
|
+
RenderItemType["Component"] = "component";
|
|
1227
|
+
})(RenderItemType || (RenderItemType = {}));
|