Added a frame for extended signals parsing
+Added SignalElements class parsing and storing extended information about signals +Added support for standard and dwarf EHA/ERI signals extended parsing (excluding eha_top_l, eha_top_r, eha_ps_k and eri_ps_k prefabs) (signs are not being parsed yet) +Added SignalElementsEnums const that will help to translate different signal types into one unified structure
This commit is contained in:
parent
480d838e61
commit
422c038cfa
10
public/assets/signal-test-new.svg
Normal file
10
public/assets/signal-test-new.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="100mm" height="330mm" version="1.1" viewBox="0 0 100 330" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<circle cx="50" cy="28" r="16" fill="none" stroke="#808080" stroke-linejoin="round" stroke-width="8"/>
|
||||||
|
<circle cx="50" cy="60" r="16" fill="none" stroke="#808080" stroke-linejoin="round" stroke-width="8"/>
|
||||||
|
<circle cx="50" cy="92" r="16" fill="none" stroke="#808080" stroke-linejoin="round" stroke-width="8"/>
|
||||||
|
<circle cx="50" cy="124" r="16" fill="none" stroke="#808080" stroke-linejoin="round" stroke-width="8"/>
|
||||||
|
<circle cx="50" cy="156" r="16" fill="none" stroke="#808080" stroke-linejoin="round" stroke-width="8"/>
|
||||||
|
<path d="m50 170.67v143.33" fill="none" stroke="#808080" stroke-linejoin="round" stroke-width="8"/>
|
||||||
|
<path d="m38 318h24" fill="none" stroke="#808080" stroke-linecap="round" stroke-linejoin="round" stroke-width="8"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 892 B |
@ -36,6 +36,8 @@ const Constants = {
|
|||||||
electrificationMissingRouteTracks: true,
|
electrificationMissingRouteTracks: true,
|
||||||
electrificationResolverError: true,
|
electrificationResolverError: true,
|
||||||
electrificationResolverWarnings: true,
|
electrificationResolverWarnings: true,
|
||||||
|
signalElemsUnknownPrefab: true,
|
||||||
|
signalElemsRecognizedUnknownPrefab: true,
|
||||||
},
|
},
|
||||||
errors: {
|
errors: {
|
||||||
invalidSceneryInfo: true
|
invalidSceneryInfo: true
|
||||||
|
|||||||
39
src/model/signal_elements/enums.js
Normal file
39
src/model/signal_elements/enums.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
const SignalElementsEnums = {
|
||||||
|
Type: {
|
||||||
|
UNKNOWN: 0,
|
||||||
|
STANDARD: 1,
|
||||||
|
DWARF: 2,
|
||||||
|
TOP: 4,
|
||||||
|
},
|
||||||
|
HeadPosition: {
|
||||||
|
UNKNOWN: 0,
|
||||||
|
STANDARD: 1,
|
||||||
|
RIGHT: 2,
|
||||||
|
LEFT: 3,
|
||||||
|
},
|
||||||
|
UnitType: {
|
||||||
|
UNKNOWN: 0,
|
||||||
|
WHITE: 1,
|
||||||
|
RED: 2,
|
||||||
|
BLUE: 3,
|
||||||
|
YELLOW_UPPER: 4,
|
||||||
|
YELLOW_LOWER: 5,
|
||||||
|
DWARF_YELLOW_S13: 6,
|
||||||
|
INNER: 7,
|
||||||
|
DWARF_W24: 8,
|
||||||
|
GREEN: 9,
|
||||||
|
OLD_GREEN: 10,
|
||||||
|
UNUSED: 11,
|
||||||
|
BROKEN: 12,
|
||||||
|
NONE: 13,
|
||||||
|
},
|
||||||
|
BarType: {
|
||||||
|
UNKNOWN: 0,
|
||||||
|
NONE: 1,
|
||||||
|
YELLOW: 2,
|
||||||
|
GREEN: 3,
|
||||||
|
YELLOW_GREEN: 4,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SignalElementsEnums;
|
||||||
15
src/model/signal_elements/parsers-list.js
Normal file
15
src/model/signal_elements/parsers-list.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import SignalElementsParserEhaEriDwarf from "./parsers/eha-eri-dwarf";
|
||||||
|
import SignalElementsParserEhaEriStandard from "./parsers/eha-eri-standard";
|
||||||
|
|
||||||
|
const SignalElementsParsersList = {
|
||||||
|
'eha-eri': {
|
||||||
|
name: 'EHA/ERI',
|
||||||
|
regex: /^(eha_|eri_)/,
|
||||||
|
subtypes: [
|
||||||
|
SignalElementsParserEhaEriStandard,
|
||||||
|
SignalElementsParserEhaEriDwarf
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SignalElementsParsersList;
|
||||||
94
src/model/signal_elements/parsers/common.js
Normal file
94
src/model/signal_elements/parsers/common.js
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import SignalElementsEnums from '../enums';
|
||||||
|
|
||||||
|
export default class SignalElementsParserCommon {
|
||||||
|
static getAfterLastUnderscoreNoVersion(entry) {
|
||||||
|
entry = entry?.trim();
|
||||||
|
entry = entry?.replace(/_(old|new)$/, '');
|
||||||
|
const afterLastUnderscore = entry?.lastIndexOf('_') + 1;
|
||||||
|
return entry?.substring(afterLastUnderscore) || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getHeadPosition(poleString) {
|
||||||
|
const headPosition = this.getAfterLastUnderscoreNoVersion(poleString);
|
||||||
|
if (!headPosition) return SignalElementsEnums.HeadPosition.UNKNOWN;
|
||||||
|
|
||||||
|
switch (headPosition) {
|
||||||
|
case 'p':
|
||||||
|
return SignalElementsEnums.HeadPosition.STANDARD;
|
||||||
|
case 'r':
|
||||||
|
return SignalElementsEnums.HeadPosition.RIGHT;
|
||||||
|
case 'l':
|
||||||
|
return SignalElementsEnums.HeadPosition.LEFT;
|
||||||
|
default:
|
||||||
|
return SignalElementsEnums.HeadPosition.UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getUnitTypeFromTypeString(typeString) {
|
||||||
|
typeString = typeString?.trim();
|
||||||
|
if(!typeString) return SignalElementsEnums.UnitType.NONE;
|
||||||
|
|
||||||
|
switch (typeString) {
|
||||||
|
case 'b':
|
||||||
|
return SignalElementsEnums.UnitType.WHITE;
|
||||||
|
case 'c':
|
||||||
|
return SignalElementsEnums.UnitType.RED;
|
||||||
|
case 'n':
|
||||||
|
return SignalElementsEnums.UnitType.BLUE;
|
||||||
|
case 'p1':
|
||||||
|
return SignalElementsEnums.UnitType.YELLOW_UPPER;
|
||||||
|
case 'p2':
|
||||||
|
return SignalElementsEnums.UnitType.YELLOW_LOWER;
|
||||||
|
case 'p3':
|
||||||
|
return SignalElementsEnums.UnitType.DWARF_YELLOW_S13;
|
||||||
|
case 'wew':
|
||||||
|
return SignalElementsEnums.UnitType.INNER;
|
||||||
|
case 'w24':
|
||||||
|
return SignalElementsEnums.UnitType.DWARF_W24;
|
||||||
|
case 'z':
|
||||||
|
return SignalElementsEnums.UnitType.GREEN;
|
||||||
|
case 'z2':
|
||||||
|
return SignalElementsEnums.UnitType.OLD_GREEN;
|
||||||
|
case 'zas':
|
||||||
|
return SignalElementsEnums.UnitType.UNUSED;
|
||||||
|
case 'zb':
|
||||||
|
return SignalElementsEnums.UnitType.BROKEN;
|
||||||
|
default:
|
||||||
|
return SignalElementsEnums.UnitType.UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getUnits(entries, start, count, step) {
|
||||||
|
const units = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
const index = start + i * step;
|
||||||
|
if (index >= entries.length) break;
|
||||||
|
const typeString = this.getAfterLastUnderscoreNoVersion(entries[index]);
|
||||||
|
const type = this.getUnitTypeFromTypeString(typeString);
|
||||||
|
|
||||||
|
units[i] = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (units.length > 0 && units[units.length - 1] === SignalElementsEnums.UnitType.NONE) {
|
||||||
|
units.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return units;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getBarType(barString) {
|
||||||
|
const typeString = this.getAfterLastUnderscoreNoVersion(barString);
|
||||||
|
|
||||||
|
switch (typeString) {
|
||||||
|
case 'p':
|
||||||
|
return SignalElementsEnums.BarType.YELLOW;
|
||||||
|
case 'z':
|
||||||
|
return SignalElementsEnums.BarType.GREEN;
|
||||||
|
case 'pz':
|
||||||
|
return SignalElementsEnums.BarType.YELLOW_GREEN;
|
||||||
|
default:
|
||||||
|
return SignalElementsEnums.BarType.UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/model/signal_elements/parsers/eha-eri-dwarf.js
Normal file
24
src/model/signal_elements/parsers/eha-eri-dwarf.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import SignalElementsEnums from "../enums";
|
||||||
|
import SignalElements from "../signal-elements";
|
||||||
|
import SignalElementsParserCommon from "./common";
|
||||||
|
|
||||||
|
export default class SignalElementsParserEhaEriDwarf {
|
||||||
|
static parsers = [];
|
||||||
|
|
||||||
|
static isAppliable(prefabName) {
|
||||||
|
const regex = /^(eha|eri)_(sp|tm|to)_k$/;
|
||||||
|
return regex.test(prefabName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromPrefabText(id, text) {
|
||||||
|
const entries = text.split(",");
|
||||||
|
|
||||||
|
return new SignalElements(
|
||||||
|
SignalElementsEnums.Type.DWARF,
|
||||||
|
SignalElementsEnums.HeadPosition.STANDARD,
|
||||||
|
SignalElementsParserCommon.getUnits(entries, 2, 3, 2),
|
||||||
|
SignalElementsEnums.BarType.NONE,
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/model/signal_elements/parsers/eha-eri-standard.js
Normal file
24
src/model/signal_elements/parsers/eha-eri-standard.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import SignalElementsEnums from "../enums";
|
||||||
|
import SignalElements from "../signal-elements";
|
||||||
|
import SignalElementsParserCommon from "./common";
|
||||||
|
|
||||||
|
export default class SignalElementsParserEhaEriStandard {
|
||||||
|
static parsers = [];
|
||||||
|
|
||||||
|
static isAppliable(prefabName) {
|
||||||
|
const regex = /^(eha|eri)_(ps|sbl|sp|tm|to)_(p|r|l)$/;
|
||||||
|
return regex.test(prefabName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromPrefabText(id, text) {
|
||||||
|
const entries = text.split(",");
|
||||||
|
|
||||||
|
return new SignalElements(
|
||||||
|
SignalElementsEnums.Type.STANDARD,
|
||||||
|
SignalElementsParserCommon.getHeadPosition(entries[1]),
|
||||||
|
SignalElementsParserCommon.getUnits(entries, 6, 6, 1),
|
||||||
|
SignalElementsParserCommon.getBarType(entries[12]),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/model/signal_elements/signal-elements.js
Normal file
41
src/model/signal_elements/signal-elements.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import SceneryParserLog from "../scenery-parser-log";
|
||||||
|
import SignalElementsEnums from "./enums";
|
||||||
|
import SignalElementsParsersList from "./parsers-list";
|
||||||
|
|
||||||
|
export default class SignalElements {
|
||||||
|
type = SignalElementsEnums.Type.UNKNOWN;
|
||||||
|
headPosition = SignalElementsEnums.HeadPosition.UNKNOWN;
|
||||||
|
units = [];
|
||||||
|
bar;
|
||||||
|
signs = [];
|
||||||
|
|
||||||
|
constructor(type, headPosition, units = [], bar = null, signs = []) {
|
||||||
|
Object.assign(this, {
|
||||||
|
type,
|
||||||
|
headPosition,
|
||||||
|
units,
|
||||||
|
bar,
|
||||||
|
signs
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromPrefabText(id, text) {
|
||||||
|
const prefabName = text.split(",", 2)[0].trim();
|
||||||
|
|
||||||
|
for(const parser of Object.values(SignalElementsParsersList)) {
|
||||||
|
if (!parser.regex.test(prefabName)) continue;
|
||||||
|
|
||||||
|
for(const subtype of parser.subtypes) {
|
||||||
|
if (subtype.isAppliable(prefabName)) {
|
||||||
|
return subtype.fromPrefabText(id, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneryParserLog.warn('signalElemsRecognizedUnknownPrefab', `Signal ${id} recognized as ${parser.name} but has unknown prefab name: ${prefabName}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneryParserLog.warn('signalElemsUnknownPrefab', `Signal ${id} has unknown prefab name: ${prefabName}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,21 +2,24 @@ import SceneryParserLog from "../scenery-parser-log";
|
|||||||
import SpawnInfo from "../spawn-info";
|
import SpawnInfo from "../spawn-info";
|
||||||
import TrackObject from "./track-object";
|
import TrackObject from "./track-object";
|
||||||
import Vector3 from "../vector3";
|
import Vector3 from "../vector3";
|
||||||
|
import SignalElements from "../signal_elements/signal-elements";
|
||||||
|
|
||||||
export default class Signal extends TrackObject {
|
export default class Signal extends TrackObject {
|
||||||
is_spawn;
|
is_spawn;
|
||||||
spawn_info;
|
spawn_info;
|
||||||
signal_name;
|
signal_name;
|
||||||
|
signal_elements;
|
||||||
type = "Signal";
|
type = "Signal";
|
||||||
applied = false;
|
applied = false;
|
||||||
|
|
||||||
constructor(id, prefab_name, pos, rot, track_id, name, is_spawn, spawn_info, signal_name) {
|
constructor(id, prefab_name, pos, rot, track_id, name, is_spawn, spawn_info, signal_name, signal_elements) {
|
||||||
super(id, prefab_name, pos, rot, track_id, name);
|
super(id, prefab_name, pos, rot, track_id, name);
|
||||||
|
|
||||||
Object.assign(this, {
|
Object.assign(this, {
|
||||||
is_spawn,
|
is_spawn,
|
||||||
spawn_info: is_spawn ? spawn_info : null,
|
spawn_info: is_spawn ? spawn_info : null,
|
||||||
signal_name
|
signal_name,
|
||||||
|
signal_elements
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.is_spawn && !this.spawn_info) {
|
if (this.is_spawn && !this.spawn_info) {
|
||||||
@ -75,7 +78,8 @@ export default class Signal extends TrackObject {
|
|||||||
values[11], // name,
|
values[11], // name,
|
||||||
values[12] === "Spawn Signal", // is_spawn
|
values[12] === "Spawn Signal", // is_spawn
|
||||||
SpawnInfo.fromText(values[15]), // spawn_info
|
SpawnInfo.fromText(values[15]), // spawn_info
|
||||||
values[29]
|
values[29],
|
||||||
|
SignalElements.fromPrefabText(values[1], values[2]) // signal_elements
|
||||||
);
|
);
|
||||||
|
|
||||||
return signal;
|
return signal;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user