@packtrack/layout 1.0.13 → 1.2.0
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/.built/device/channel.d.ts +1 -1
- package/.built/device/index.d.ts +11 -0
- package/.built/device/index.js +20 -0
- package/.built/district.d.ts +2 -0
- package/.built/district.js +4 -3
- package/.built/index.d.ts +8 -2
- package/.built/index.js +8 -2
- package/.built/layout.d.ts +7 -1
- package/.built/layout.js +61 -12
- package/.built/monitor.d.ts +9 -0
- package/.built/monitor.js +15 -0
- package/.built/position.d.ts +3 -1
- package/.built/position.js +16 -0
- package/.built/positioner/point.d.ts +1 -1
- package/.built/power-district/activator.d.ts +7 -0
- package/.built/power-district/activator.js +8 -0
- package/.built/power-district/index.d.ts +14 -0
- package/.built/power-district/index.js +17 -0
- package/.built/power-district/monitor.d.ts +7 -0
- package/.built/power-district/monitor.js +8 -0
- package/.built/power-district/reverser.d.ts +7 -0
- package/.built/power-district/reverser.js +8 -0
- package/.built/span.d.ts +12 -0
- package/.built/span.js +77 -0
- package/.built/throttle.d.ts +9 -0
- package/.built/throttle.js +15 -0
- package/package.json +1 -1
- package/source/device/channel.ts +2 -2
- package/source/district.ts +21 -18
- package/source/index.ts +9 -2
- package/source/layout.ts +148 -82
- package/source/monitor.ts +19 -0
- package/source/position.ts +52 -32
- package/source/power-district/activator.ts +9 -0
- package/source/power-district/index.ts +24 -0
- package/source/power-district/monitor.ts +9 -0
- package/source/power-district/reverser.ts +9 -0
- package/source/span.ts +88 -0
- package/source/throttle.ts +19 -0
- package/source/power-district.ts +0 -16
- /package/source/device/{device.ts → index.ts} +0 -0
package/source/district.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { Layout } from "./layout";
|
|
2
|
+
import { Monitor } from "./monitor";
|
|
2
3
|
import { PowerDistrict } from "./power-district";
|
|
3
4
|
import { Router } from "./router";
|
|
4
5
|
import { Section } from "./section";
|
|
5
6
|
|
|
6
7
|
export class District {
|
|
7
8
|
children: District[] = [];
|
|
8
|
-
|
|
9
|
+
|
|
9
10
|
powerDistricts: PowerDistrict[] = [];
|
|
10
11
|
sections: Section[] = [];
|
|
11
12
|
routers: Router[] = [];
|
|
12
|
-
|
|
13
|
+
|
|
14
|
+
monitors: Monitor[] = [];
|
|
15
|
+
|
|
13
16
|
constructor(
|
|
14
17
|
public name: string,
|
|
15
18
|
public parent: District | Layout
|
|
@@ -22,65 +25,65 @@ export class District {
|
|
|
22
25
|
|
|
23
26
|
return `${this.name}.${this.parent.domainName}`;
|
|
24
27
|
}
|
|
25
|
-
|
|
28
|
+
|
|
26
29
|
dump() {
|
|
27
30
|
console.group(`District ${this.domainName}`);
|
|
28
|
-
|
|
31
|
+
|
|
29
32
|
if (this.powerDistricts.length) {
|
|
30
33
|
console.group('power districts');
|
|
31
|
-
|
|
34
|
+
|
|
32
35
|
for (let district of this.powerDistricts) {
|
|
33
36
|
district.dump();
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
console.groupEnd();
|
|
37
40
|
}
|
|
38
|
-
|
|
41
|
+
|
|
39
42
|
if (this.sections.length) {
|
|
40
43
|
console.group('sections');
|
|
41
|
-
|
|
44
|
+
|
|
42
45
|
for (let section of this.sections) {
|
|
43
46
|
section.dump();
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
console.groupEnd();
|
|
47
50
|
}
|
|
48
|
-
|
|
51
|
+
|
|
49
52
|
if (this.children.length) {
|
|
50
53
|
console.group('children');
|
|
51
|
-
|
|
54
|
+
|
|
52
55
|
for (let district of this.children) {
|
|
53
56
|
district.dump();
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
console.groupEnd();
|
|
57
60
|
}
|
|
58
|
-
|
|
61
|
+
|
|
59
62
|
console.groupEnd();
|
|
60
63
|
}
|
|
61
|
-
|
|
64
|
+
|
|
62
65
|
toDotReference() {
|
|
63
66
|
return `cluster_${this.name.replace(/-/g, '_')}${this.parent instanceof District ? this.parent.toDotReference() : ''}`;
|
|
64
67
|
}
|
|
65
|
-
|
|
68
|
+
|
|
66
69
|
toDotDefinition() {
|
|
67
70
|
return `
|
|
68
71
|
subgraph ${this.toDotReference()} {
|
|
69
72
|
label = ${JSON.stringify(this.name)}
|
|
70
|
-
|
|
73
|
+
|
|
71
74
|
${this.sections.map(section => section.toDotDefinition()).join('')}
|
|
72
75
|
${this.routers.map(router => router.toDotDefinition()).join('')}
|
|
73
|
-
|
|
76
|
+
|
|
74
77
|
${this.children.map(child => child.toDotDefinition()).join('')}
|
|
75
78
|
}
|
|
76
79
|
`;
|
|
77
80
|
}
|
|
78
|
-
|
|
81
|
+
|
|
79
82
|
toDotConnection() {
|
|
80
83
|
return `
|
|
81
84
|
${this.sections.map(section => section.toDotConnection()).join('')}
|
|
82
85
|
${this.routers.map(router => router.toDotConnection()).join('')}
|
|
83
|
-
|
|
86
|
+
|
|
84
87
|
${this.children.map(child => child.toDotConnection()).join('')}
|
|
85
88
|
`;
|
|
86
89
|
}
|
|
@@ -97,8 +100,8 @@ export class District {
|
|
|
97
100
|
|
|
98
101
|
findSVGPositions() {
|
|
99
102
|
return [
|
|
100
|
-
...this.sections.map(section => section.findSVGPositions()),
|
|
103
|
+
...this.sections.map(section => section.findSVGPositions()),
|
|
101
104
|
...this.children.map(child => child.findSVGPositions())
|
|
102
105
|
];
|
|
103
106
|
}
|
|
104
|
-
}
|
|
107
|
+
}
|
package/source/index.ts
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
export * from './district';
|
|
2
2
|
export * from './layout';
|
|
3
3
|
export * from './position';
|
|
4
|
-
export * from './power-district';
|
|
5
4
|
export * from './route';
|
|
6
5
|
export * from './router';
|
|
7
6
|
export * from './section';
|
|
7
|
+
export * from './span';
|
|
8
8
|
export * from './tile';
|
|
9
9
|
export * from './track';
|
|
10
|
+
export * from './monitor';
|
|
11
|
+
export * from './throttle';
|
|
12
|
+
|
|
13
|
+
export * from './power-district/index';
|
|
14
|
+
export * from './power-district/activator';
|
|
15
|
+
export * from './power-district/monitor';
|
|
16
|
+
export * from './power-district/reverser';
|
|
10
17
|
|
|
11
18
|
export * from './positioner/index';
|
|
12
19
|
export * from './positioner/point';
|
|
13
20
|
export * from './positioner/responder-type';
|
|
14
21
|
|
|
15
|
-
export * from './device/
|
|
22
|
+
export * from './device/index';
|
|
16
23
|
export * from './device/channel';
|
package/source/layout.ts
CHANGED
|
@@ -5,19 +5,27 @@ import { Router } from "./router";
|
|
|
5
5
|
import { Section } from "./section";
|
|
6
6
|
import { TilePattern, Tile } from "./tile";
|
|
7
7
|
import { Track } from "./track";
|
|
8
|
-
import { Device } from "./device/
|
|
8
|
+
import { Device } from "./device/index";
|
|
9
9
|
import { ResponderType } from "./positioner/responder-type";
|
|
10
10
|
import { Channel } from "./device/channel";
|
|
11
11
|
import { PointPositioner } from "./positioner/point";
|
|
12
|
+
import { PowerDistrictActivator } from "./power-district/activator";
|
|
13
|
+
import { PowerDistrictReverser } from "./power-district/reverser";
|
|
14
|
+
import { PowerDistrictMonitor } from "./power-district/monitor";
|
|
15
|
+
import { Monitor } from "./monitor";
|
|
16
|
+
import { Throttle } from "./throttle";
|
|
12
17
|
|
|
13
18
|
export class Layout {
|
|
14
19
|
name: string;
|
|
15
|
-
|
|
20
|
+
|
|
16
21
|
districts: District[] = [];
|
|
17
|
-
|
|
22
|
+
|
|
18
23
|
devices: Device[] = [];
|
|
19
24
|
responderType: ResponderType[] = [];
|
|
20
25
|
|
|
26
|
+
monitors: Monitor[] = [];
|
|
27
|
+
throttles: Throttle[] = [];
|
|
28
|
+
|
|
21
29
|
get allDistricts() {
|
|
22
30
|
const districts: District[] = [];
|
|
23
31
|
|
|
@@ -43,120 +51,144 @@ export class Layout {
|
|
|
43
51
|
layout.name = railway.getAttribute('name');
|
|
44
52
|
|
|
45
53
|
const version = railway.getAttribute('version');
|
|
46
|
-
|
|
54
|
+
|
|
47
55
|
if (version == '1') {
|
|
48
|
-
let
|
|
49
|
-
|
|
50
|
-
while (
|
|
51
|
-
if (
|
|
52
|
-
layout.districts.push(layout.loadDistrict(
|
|
56
|
+
let child = railway.firstChild;
|
|
57
|
+
|
|
58
|
+
while (child) {
|
|
59
|
+
if (child.tagName == 'district') {
|
|
60
|
+
layout.districts.push(layout.loadDistrict(child, layout));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (child.tagName == 'monitor') {
|
|
64
|
+
layout.monitors.push(layout.loadMonitor(child, layout));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (child.tagName == 'throttle') {
|
|
68
|
+
layout.throttles.push(layout.loadThrottle(child, layout));
|
|
53
69
|
}
|
|
54
|
-
|
|
55
|
-
|
|
70
|
+
|
|
71
|
+
child = child.nextSibling;
|
|
56
72
|
}
|
|
57
|
-
|
|
58
|
-
|
|
73
|
+
|
|
74
|
+
child = railway.firstChild;
|
|
59
75
|
let index = 0;
|
|
60
|
-
|
|
61
|
-
while (
|
|
62
|
-
if (
|
|
63
|
-
layout.linkDistrict(
|
|
64
|
-
|
|
76
|
+
|
|
77
|
+
while (child) {
|
|
78
|
+
if (child.tagName == 'district') {
|
|
79
|
+
layout.linkDistrict(child, layout.districts[index]);
|
|
80
|
+
|
|
65
81
|
index++;
|
|
66
82
|
}
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
|
|
84
|
+
child = child.nextSibling;
|
|
69
85
|
}
|
|
70
86
|
} else {
|
|
71
|
-
throw new Error(`
|
|
87
|
+
throw new Error(`Unsupported railway definition file version '${version}'`);
|
|
72
88
|
}
|
|
73
89
|
|
|
74
90
|
return layout;
|
|
75
91
|
}
|
|
76
|
-
|
|
92
|
+
|
|
93
|
+
loadMonitor(source, parent: District | Layout) {
|
|
94
|
+
const montior = new Monitor(this.findDevice(source.getAttribute('device')), parent);
|
|
95
|
+
|
|
96
|
+
return montior;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
loadThrottle(source, parent: District | Layout) {
|
|
100
|
+
const throttle = new Throttle(this.findDevice(source.getAttribute('device')), parent);
|
|
101
|
+
|
|
102
|
+
return throttle;
|
|
103
|
+
}
|
|
104
|
+
|
|
77
105
|
loadDistrict(source, parent: District | Layout) {
|
|
78
106
|
const district = new District(source.getAttribute('name'), parent);
|
|
79
|
-
|
|
107
|
+
|
|
80
108
|
let child = source.firstChild;
|
|
81
|
-
|
|
109
|
+
|
|
82
110
|
while (child) {
|
|
83
111
|
if (child.tagName == 'power-districts') {
|
|
84
112
|
let powerDistrict = child.firstChild;
|
|
85
|
-
|
|
113
|
+
|
|
86
114
|
while (powerDistrict) {
|
|
87
115
|
if (powerDistrict.tagName == 'power-district') {
|
|
88
116
|
district.powerDistricts.push(this.loadPowerDistrict(powerDistrict, district));
|
|
89
117
|
}
|
|
90
|
-
|
|
118
|
+
|
|
91
119
|
powerDistrict = powerDistrict.nextSibling;
|
|
92
120
|
}
|
|
93
121
|
}
|
|
94
|
-
|
|
122
|
+
|
|
95
123
|
if (child.tagName == 'section') {
|
|
96
124
|
this.loadSection(child, district);
|
|
97
125
|
}
|
|
98
|
-
|
|
126
|
+
|
|
99
127
|
if (child.tagName == 'router') {
|
|
100
128
|
district.routers.push(this.loadRouter(child, district));
|
|
101
129
|
}
|
|
102
|
-
|
|
130
|
+
|
|
103
131
|
if (child.tagName == 'district') {
|
|
104
132
|
district.children.push(this.loadDistrict(child, district));
|
|
105
133
|
}
|
|
106
|
-
|
|
134
|
+
|
|
135
|
+
if (child.tagName == 'monitor') {
|
|
136
|
+
district.monitors.push(this.loadMonitor(child, district));
|
|
137
|
+
}
|
|
138
|
+
|
|
107
139
|
child = child.nextSibling;
|
|
108
140
|
}
|
|
109
|
-
|
|
141
|
+
|
|
110
142
|
return district;
|
|
111
143
|
}
|
|
112
|
-
|
|
144
|
+
|
|
113
145
|
linkDistrict(source, district: District) {
|
|
114
146
|
let child = source.firstChild;
|
|
115
|
-
|
|
147
|
+
|
|
116
148
|
let sectionIndex = 0;
|
|
117
149
|
let childIndex = 0;
|
|
118
|
-
|
|
150
|
+
|
|
119
151
|
while (child) {
|
|
120
152
|
if (child.tagName == 'section') {
|
|
121
153
|
this.linkSection(child, district.sections[sectionIndex]);
|
|
122
|
-
|
|
154
|
+
|
|
123
155
|
sectionIndex++;
|
|
124
156
|
}
|
|
125
|
-
|
|
157
|
+
|
|
126
158
|
if (child.tagName == 'router') {
|
|
127
159
|
this.linkRouter(child, district.routers.find(router => router.name == child.getAttribute('name'))!);
|
|
128
160
|
}
|
|
129
|
-
|
|
161
|
+
|
|
130
162
|
if (child.tagName == 'district') {
|
|
131
163
|
this.linkDistrict(child, district.children[childIndex]);
|
|
132
|
-
|
|
164
|
+
|
|
133
165
|
childIndex++;
|
|
134
166
|
}
|
|
135
|
-
|
|
167
|
+
|
|
136
168
|
child = child.nextSibling;
|
|
137
169
|
}
|
|
138
170
|
}
|
|
139
|
-
|
|
171
|
+
|
|
140
172
|
loadSection(source, district: District) {
|
|
141
173
|
const section = new Section(source.getAttribute('name'), district);
|
|
142
174
|
district.sections.push(section);
|
|
143
|
-
|
|
175
|
+
|
|
144
176
|
let child = source.firstChild;
|
|
145
|
-
|
|
177
|
+
|
|
146
178
|
while (child) {
|
|
147
179
|
if (child.tagName == 'tracks') {
|
|
148
180
|
let trackNode = child.firstChild;
|
|
149
|
-
|
|
181
|
+
|
|
150
182
|
while (trackNode) {
|
|
151
183
|
if (trackNode.tagName == 'track') {
|
|
152
184
|
const track = new Track(
|
|
153
|
-
section,
|
|
154
|
-
+trackNode.getAttribute('length'),
|
|
185
|
+
section,
|
|
186
|
+
+trackNode.getAttribute('length'),
|
|
155
187
|
trackNode.getAttribute('path')
|
|
156
188
|
);
|
|
157
189
|
|
|
158
190
|
section.tracks.push(track);
|
|
159
|
-
|
|
191
|
+
|
|
160
192
|
let trackChild = trackNode.firstChild;
|
|
161
193
|
|
|
162
194
|
while (trackChild) {
|
|
@@ -170,7 +202,7 @@ export class Layout {
|
|
|
170
202
|
const responderType = this.findResponderType(positioner.getAttribute('responder'));
|
|
171
203
|
|
|
172
204
|
track.positioners.push(new PointPositioner(
|
|
173
|
-
track,
|
|
205
|
+
track,
|
|
174
206
|
+positioner.getAttribute('offset'),
|
|
175
207
|
channel,
|
|
176
208
|
responderType
|
|
@@ -184,7 +216,7 @@ export class Layout {
|
|
|
184
216
|
trackChild = trackChild.nextSibling;
|
|
185
217
|
}
|
|
186
218
|
}
|
|
187
|
-
|
|
219
|
+
|
|
188
220
|
trackNode = trackNode.nextSibling;
|
|
189
221
|
}
|
|
190
222
|
}
|
|
@@ -198,7 +230,7 @@ export class Layout {
|
|
|
198
230
|
|
|
199
231
|
section.tiles.push(new Tile(section, +child.getAttribute('x'), +child.getAttribute('y'), TilePattern.patterns[pattern]))
|
|
200
232
|
}
|
|
201
|
-
|
|
233
|
+
|
|
202
234
|
child = child.nextSibling;
|
|
203
235
|
}
|
|
204
236
|
}
|
|
@@ -241,111 +273,145 @@ export class Layout {
|
|
|
241
273
|
|
|
242
274
|
return type;
|
|
243
275
|
}
|
|
244
|
-
|
|
276
|
+
|
|
245
277
|
linkSection(source, section: Section) {
|
|
246
278
|
let child = source.firstChild;
|
|
247
|
-
|
|
279
|
+
|
|
248
280
|
while (child) {
|
|
249
281
|
if (child.tagName == 'out') {
|
|
250
282
|
const out = this.findSection(child.getAttribute('section'), section.district);
|
|
251
|
-
|
|
283
|
+
|
|
252
284
|
section.out = out;
|
|
253
285
|
out.in = section;
|
|
254
286
|
}
|
|
255
|
-
|
|
287
|
+
|
|
256
288
|
child = child.nextSibling;
|
|
257
289
|
}
|
|
258
290
|
}
|
|
259
|
-
|
|
291
|
+
|
|
260
292
|
findSection(path: string, base: District, source = base) {
|
|
261
293
|
const parts = path.split('.');
|
|
262
|
-
|
|
294
|
+
|
|
263
295
|
if (parts.length == 0) {
|
|
264
296
|
throw `section '${path}' not found from '${source.name}': invalid name`;
|
|
265
297
|
}
|
|
266
|
-
|
|
298
|
+
|
|
267
299
|
if (parts.length == 1) {
|
|
268
300
|
const localSection = base.sections.find(section => section.name == parts[0]);
|
|
269
|
-
|
|
301
|
+
|
|
270
302
|
if (!localSection) {
|
|
271
303
|
throw new Error(`Section '${path}' not found from '${source.name}': section does not exist in '${base.name}'`);
|
|
272
304
|
}
|
|
273
|
-
|
|
305
|
+
|
|
274
306
|
return localSection;
|
|
275
307
|
}
|
|
276
|
-
|
|
308
|
+
|
|
277
309
|
const sectionName = parts.pop()!;
|
|
278
|
-
|
|
310
|
+
|
|
279
311
|
let pool: District | Layout = base;
|
|
280
|
-
|
|
312
|
+
|
|
281
313
|
for (let index = 0; index < parts.length; index++) {
|
|
282
314
|
if (pool instanceof Layout || !pool.parent) {
|
|
283
315
|
throw new Error(`Section '${path}' could not be found from '${source.name}': district '${pool.name}' does not have a parent`);
|
|
284
316
|
}
|
|
285
|
-
|
|
317
|
+
|
|
286
318
|
pool = pool.parent!;
|
|
287
319
|
}
|
|
288
|
-
|
|
320
|
+
|
|
289
321
|
for (let part of parts) {
|
|
290
322
|
const child = (pool instanceof District ? pool.children : pool.districts).find(child => child.name == part);
|
|
291
|
-
|
|
323
|
+
|
|
292
324
|
if (!child) {
|
|
293
325
|
throw new Error(`Section '${path}' could not be found from '${source.name}': district '${pool.name}' does not have a child named '${part}'`);
|
|
294
326
|
}
|
|
295
|
-
|
|
327
|
+
|
|
296
328
|
pool = child;
|
|
297
329
|
}
|
|
298
330
|
|
|
299
331
|
if (pool instanceof Layout) {
|
|
300
332
|
throw new Error(`Section '${path}' could not be found from '${source.name}': a layout cannot directly include a section`);
|
|
301
333
|
}
|
|
302
|
-
|
|
334
|
+
|
|
303
335
|
return this.findSection(sectionName, pool, source);
|
|
304
336
|
}
|
|
305
|
-
|
|
337
|
+
|
|
306
338
|
loadRouter(source, district: District) {
|
|
307
339
|
const router = new Router(source.getAttribute('name'), district);
|
|
308
|
-
|
|
340
|
+
|
|
309
341
|
return router;
|
|
310
342
|
}
|
|
311
|
-
|
|
343
|
+
|
|
312
344
|
linkRouter(source, router: Router) {
|
|
313
345
|
let child = source.firstChild;
|
|
314
|
-
|
|
346
|
+
let active: Route;
|
|
347
|
+
|
|
315
348
|
while (child) {
|
|
316
349
|
if (child.tagName == 'route') {
|
|
317
350
|
const route = new Route(child.getAttribute('name'), router);
|
|
318
|
-
|
|
351
|
+
|
|
319
352
|
route.in = this.findSection(child.getAttribute('in'), router.district);
|
|
320
353
|
route.in.out = router;
|
|
321
|
-
|
|
354
|
+
|
|
322
355
|
route.out = this.findSection(child.getAttribute('out'), router.district);
|
|
323
356
|
route.out.in = router;
|
|
324
|
-
|
|
357
|
+
|
|
358
|
+
if (child.hasAttribute('active')) {
|
|
359
|
+
if (active) {
|
|
360
|
+
throw new Error(`Router '${router.domainName}' has multiple active routes (${active.name}, ${route.name}).`);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
active = route;
|
|
364
|
+
}
|
|
365
|
+
|
|
325
366
|
router.routes.push(route);
|
|
326
367
|
}
|
|
327
|
-
|
|
368
|
+
|
|
328
369
|
child = child.nextSibling;
|
|
329
370
|
}
|
|
371
|
+
|
|
372
|
+
router.activeRoute = active;
|
|
330
373
|
}
|
|
331
|
-
|
|
374
|
+
|
|
332
375
|
loadPowerDistrict(source, district: District) {
|
|
333
376
|
const powerDistrict = new PowerDistrict(source.getAttribute('name'), district);
|
|
334
|
-
|
|
377
|
+
|
|
378
|
+
let actor = source.firstChild;
|
|
379
|
+
|
|
380
|
+
while (actor) {
|
|
381
|
+
if (actor.tagName == 'activator' || actor.tagName == 'reverser' || actor.tagName == 'monitor') {
|
|
382
|
+
const device = this.findDevice(actor.getAttribute('device'));
|
|
383
|
+
const channel = this.findChannel(device, actor.getAttribute('channel'));
|
|
384
|
+
|
|
385
|
+
if (actor.tagName == 'activator') {
|
|
386
|
+
powerDistrict.activator = new PowerDistrictActivator(device, channel);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (actor.tagName == 'reverser') {
|
|
390
|
+
powerDistrict.reverser = new PowerDistrictReverser(device, channel);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (actor.tagName == 'monitor') {
|
|
394
|
+
powerDistrict.monitor = new PowerDistrictMonitor(device, channel);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
actor = actor.nextSibling;
|
|
399
|
+
}
|
|
400
|
+
|
|
335
401
|
return powerDistrict;
|
|
336
402
|
}
|
|
337
403
|
|
|
338
404
|
toDot() {
|
|
339
405
|
let dot = 'digraph G {';
|
|
340
|
-
|
|
406
|
+
|
|
341
407
|
for (let district of this.districts) {
|
|
342
408
|
dot += district.toDotDefinition();
|
|
343
409
|
}
|
|
344
|
-
|
|
410
|
+
|
|
345
411
|
for (let district of this.districts) {
|
|
346
412
|
dot += district.toDotConnection();
|
|
347
413
|
}
|
|
348
|
-
|
|
414
|
+
|
|
349
415
|
return `${dot}}`;
|
|
350
416
|
}
|
|
351
417
|
|
|
@@ -366,11 +432,11 @@ export class Layout {
|
|
|
366
432
|
|
|
367
433
|
</style>
|
|
368
434
|
`;
|
|
369
|
-
|
|
435
|
+
|
|
370
436
|
for (let district of this.districts) {
|
|
371
437
|
svg += district.toSVG();
|
|
372
438
|
}
|
|
373
|
-
|
|
439
|
+
|
|
374
440
|
return `${svg}${inject}</svg>`;
|
|
375
441
|
}
|
|
376
442
|
|
|
@@ -396,4 +462,4 @@ export class Layout {
|
|
|
396
462
|
|
|
397
463
|
console.groupEnd();
|
|
398
464
|
}
|
|
399
|
-
}
|
|
465
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Device } from "./device";
|
|
2
|
+
import { District } from "./district";
|
|
3
|
+
import { Layout } from "./layout";
|
|
4
|
+
|
|
5
|
+
export class Monitor {
|
|
6
|
+
constructor(
|
|
7
|
+
public device: Device,
|
|
8
|
+
public scope: District | Layout
|
|
9
|
+
) { }
|
|
10
|
+
|
|
11
|
+
dump() {
|
|
12
|
+
console.group('Monitor');
|
|
13
|
+
console.log('scope:', this.scope instanceof Layout ? '*' : this.scope.domainName);
|
|
14
|
+
|
|
15
|
+
this.device.dump();
|
|
16
|
+
|
|
17
|
+
console.groupEnd();
|
|
18
|
+
}
|
|
19
|
+
}
|
package/source/position.ts
CHANGED
|
@@ -1,35 +1,55 @@
|
|
|
1
1
|
import { Section } from './section.js';
|
|
2
2
|
|
|
3
3
|
export class SectionPosition {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
4
|
+
constructor(
|
|
5
|
+
public section: Section,
|
|
6
|
+
public offset: number,
|
|
7
|
+
public reversed: boolean
|
|
8
|
+
) {
|
|
9
|
+
if (offset > section.length || offset < 0) {
|
|
10
|
+
throw new Error(`Offset ${offset} out of range for section '${section.domainName}' (0 - ${section.length})`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// returns the absolute position of the point inside the section
|
|
15
|
+
// regardless of direction
|
|
16
|
+
get absolutePosition() {
|
|
17
|
+
if (this.reversed) {
|
|
18
|
+
return this.section.length - this.offset;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return this.offset;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// TODO verify reverse
|
|
25
|
+
advance(distance: number): SectionPosition {
|
|
26
|
+
if (distance < 0) {
|
|
27
|
+
return this.invert().advance(-distance).invert();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (this.offset + distance > this.section.length) {
|
|
31
|
+
const next = this.section.next(this.reversed);
|
|
32
|
+
|
|
33
|
+
if (!next) {
|
|
34
|
+
throw new Error(`Illegal advancement ${this} + ${distance}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return new SectionPosition(next, 0, this.reversed).advance(this.offset + distance - this.section.length);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return new SectionPosition(this.section, this.offset + distance, this.reversed);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// reverse direction
|
|
44
|
+
private invert() {
|
|
45
|
+
return new SectionPosition(this.section, this.section.length - this.offset, !this.reversed);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
toString() {
|
|
49
|
+
return `${this.section.name} @ ${this.offset.toFixed(1)} ${this.reversed ? 'backward' : 'forward'}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
toPackTrackValue() {
|
|
53
|
+
return `${this.section.domainName}@${this.offset}${this.reversed ? 'R' : 'F'}`;
|
|
54
|
+
}
|
|
55
|
+
}
|