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,
|
||||
electrificationResolverError: true,
|
||||
electrificationResolverWarnings: true,
|
||||
signalElemsUnknownPrefab: true,
|
||||
signalElemsRecognizedUnknownPrefab: true,
|
||||
},
|
||||
errors: {
|
||||
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 TrackObject from "./track-object";
|
||||
import Vector3 from "../vector3";
|
||||
import SignalElements from "../signal_elements/signal-elements";
|
||||
|
||||
export default class Signal extends TrackObject {
|
||||
is_spawn;
|
||||
spawn_info;
|
||||
signal_name;
|
||||
signal_elements;
|
||||
type = "Signal";
|
||||
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);
|
||||
|
||||
Object.assign(this, {
|
||||
is_spawn,
|
||||
spawn_info: is_spawn ? spawn_info : null,
|
||||
signal_name
|
||||
signal_name,
|
||||
signal_elements
|
||||
});
|
||||
|
||||
if (this.is_spawn && !this.spawn_info) {
|
||||
@ -75,7 +78,8 @@ export default class Signal extends TrackObject {
|
||||
values[11], // name,
|
||||
values[12] === "Spawn Signal", // is_spawn
|
||||
SpawnInfo.fromText(values[15]), // spawn_info
|
||||
values[29]
|
||||
values[29],
|
||||
SignalElements.fromPrefabText(values[1], values[2]) // signal_elements
|
||||
);
|
||||
|
||||
return signal;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user