1 using System; 2 using System.Collections.Generic; 3 using System.Collections.ObjectModel; 4 using System.IO; 5 using System.Linq; 6 using System.Xml.Linq; 7 using System.Xml.XPath; 8 using OpenBveApi.Colors; 9 using OpenBveApi.Interface; 10 using TrainEditor2.Extensions; 11 using TrainEditor2.Models.Panels; 12 using TrainEditor2.Models.Sounds; 13 using TrainEditor2.Models.Trains; 14 using TrainManager.BrakeSystems; 15 using TrainManager.Car; 16 using TrainManager.Handles; 17 using TrainManager.SafetySystems; 18 19 namespace TrainEditor2.IO.IntermediateFile 20 { 21 internal static partial class IntermediateFile 22 { Parse(string fileName, out Train train, out Panel panel, out Sound sound)23 internal static void Parse(string fileName, out Train train, out Panel panel, out Sound sound) 24 { 25 XDocument xml = XDocument.Load(fileName); 26 if (xml.XPathSelectElement("/openBVE") != null) 27 { 28 throw new InvalidDataException(); 29 } 30 train = ParseTrainNode(xml.XPathSelectElement("/TrainEditor/Train")); 31 panel = ParsePanelNode(xml.XPathSelectElement("/TrainEditor/Panel")); 32 sound = ParseSoundsNode(xml.XPathSelectElement("/TrainEditor/Sounds")); 33 } 34 ParseTrainNode(XElement parent)35 private static Train ParseTrainNode(XElement parent) 36 { 37 return new Train 38 { 39 Handle = ParseHandleNode(parent.Element("Handle")), 40 Cab = ParseCabNode(parent.Element("Cab")), 41 Device = ParseDeviceNode(parent.Element("Device")), 42 Cars = new ObservableCollection<Car>(parent.XPathSelectElements("Cars/Car").Select(ParseCarNode)), 43 Couplers = new ObservableCollection<Models.Trains.Coupler>(parent.XPathSelectElements("Couplers/Coupler").Select(ParseCouplerNode)) 44 }; 45 } 46 ParseHandleNode(XElement parent)47 private static Handle ParseHandleNode(XElement parent) 48 { 49 return new Handle 50 { 51 HandleType = (HandleType)Enum.Parse(typeof(HandleType), (string)parent.Element("HandleType")), 52 PowerNotches = (int)parent.Element("PowerNotches"), 53 BrakeNotches = (int)parent.Element("BrakeNotches"), 54 PowerNotchReduceSteps = (int)parent.Element("PowerNotchReduceSteps"), 55 HandleBehaviour = (EbHandleBehaviour)Enum.Parse(typeof(EbHandleBehaviour), (string)parent.Element("EbHandleBehaviour")), 56 LocoBrake = (LocoBrakeType)Enum.Parse(typeof(LocoBrakeType), (string)parent.Element("LocoBrakeType")), 57 LocoBrakeNotches = (int)parent.Element("LocoBrakeNotches"), 58 DriverPowerNotches = (int)parent.Element("DriverPowerNotches"), 59 DriverBrakeNotches = (int)parent.Element("DriverBrakeNotches") 60 }; 61 } 62 ParseCabNode(XElement parent)63 private static Cab ParseCabNode(XElement parent) 64 { 65 double[] position = ((string)parent.Element("Position")).Split(',').Select(double.Parse).ToArray(); 66 67 return new Cab 68 { 69 PositionX = position[0], 70 PositionY = position[1], 71 PositionZ = position[2], 72 DriverCar = (int)parent.Element("DriverCar") 73 }; 74 } 75 ParseDeviceNode(XElement parent)76 private static Device ParseDeviceNode(XElement parent) 77 { 78 return new Device 79 { 80 Ats = (AtsModes)Enum.Parse(typeof(AtsModes), (string)parent.Element("Ats")), 81 Atc = (AtcModes)Enum.Parse(typeof(AtcModes), (string)parent.Element("Atc")), 82 Eb = (bool)parent.Element("Eb"), 83 ConstSpeed = (bool)parent.Element("ConstSpeed"), 84 HoldBrake = (bool)parent.Element("HoldBrake"), 85 ReAdhesionDevice = (ReadhesionDeviceType)Enum.Parse(typeof(ReadhesionDeviceType), (string)parent.Element("ReAdhesionDevice")), 86 LoadCompensatingDevice = (double)parent.Element("LoadCompensatingDevice"), 87 PassAlarm = (PassAlarmType)Enum.Parse(typeof(PassAlarmType), (string)parent.Element("PassAlarm")), 88 DoorOpenMode = (DoorMode)Enum.Parse(typeof(DoorMode), (string)parent.Element("DoorOpenMode")), 89 DoorCloseMode = (DoorMode)Enum.Parse(typeof(DoorMode), (string)parent.Element("DoorCloseMode")), 90 DoorWidth = (double)parent.Element("DoorWidth"), 91 DoorMaxTolerance = (double)parent.Element("DoorMaxTolerance") 92 }; 93 } 94 ParseCarNode(XElement parent)95 private static Car ParseCarNode(XElement parent) 96 { 97 Car car; 98 99 if ((bool)parent.Element("IsMotorCar")) 100 { 101 car = new MotorCar(); 102 } 103 else 104 { 105 car = new TrailerCar(); 106 } 107 108 car.Mass = (double)parent.Element("Mass"); 109 car.Length = (double)parent.Element("Length"); 110 car.Width = (double)parent.Element("Width"); 111 car.Height = (double)parent.Element("Height"); 112 car.CenterOfGravityHeight = (double)parent.Element("CenterOfGravityHeight"); 113 car.DefinedAxles = (bool)parent.Element("DefinedAxles"); 114 car.FrontAxle = (double)parent.Element("FrontAxle"); 115 car.RearAxle = (double)parent.Element("RearAxle"); 116 117 car.FrontBogie = ParseBogieNode(parent.Element("FrontBogie")); 118 car.RearBogie = ParseBogieNode(parent.Element("RearBogie")); 119 120 car.ExposedFrontalArea = (double)parent.Element("ExposedFrontalArea"); 121 car.UnexposedFrontalArea = (double)parent.Element("UnexposedFrontalArea"); 122 123 car.Performance = ParsePerformanceNode(parent.Element("Performance")); 124 car.Delay = ParseDelayNode(parent.Element("Delay")); 125 car.Move = ParseMoveNode(parent.Element("Move")); 126 car.Brake = ParseBrakeNode(parent.Element("Brake")); 127 car.Pressure = ParsePressureNode(parent.Element("Pressure")); 128 129 MotorCar motorCar = car as MotorCar; 130 131 if (motorCar != null) 132 { 133 motorCar.Acceleration = ParseAccelerationNode(parent.Element("Acceleration")); 134 motorCar.Motor = ParseMotorNode(parent.Element("Motor")); 135 } 136 137 car.Reversed = (bool)parent.Element("Reversed"); 138 car.Object = (string)parent.Element("Object"); 139 car.LoadingSway = (bool)parent.Element("LoadingSway"); 140 141 return car; 142 } 143 ParseBogieNode(XElement parent)144 private static Car.Bogie ParseBogieNode(XElement parent) 145 { 146 return new Car.Bogie 147 { 148 DefinedAxles = (bool)parent.Element("DefinedAxles"), 149 FrontAxle = (double)parent.Element("FrontAxle"), 150 RearAxle = (double)parent.Element("RearAxle"), 151 Reversed = (bool)parent.Element("Reversed"), 152 Object = (string)parent.Element("Object") 153 }; 154 } 155 ParsePerformanceNode(XElement parent)156 private static Performance ParsePerformanceNode(XElement parent) 157 { 158 return new Performance 159 { 160 Deceleration = (double)parent.Element("Deceleration"), 161 CoefficientOfStaticFriction = (double)parent.Element("CoefficientOfStaticFriction"), 162 CoefficientOfRollingResistance = (double)parent.Element("CoefficientOfRollingResistance"), 163 AerodynamicDragCoefficient = (double)parent.Element("AerodynamicDragCoefficient") 164 }; 165 } 166 ParseDelayNode(XElement parent)167 private static Delay ParseDelayNode(XElement parent) 168 { 169 return new Delay 170 { 171 DelayPower = new ObservableCollection<Delay.Entry>(parent.XPathSelectElements("DelayPower/Entry").Select(ParseDelayEntryNode)), 172 DelayBrake = new ObservableCollection<Delay.Entry>(parent.XPathSelectElements("DelayBrake/Entry").Select(ParseDelayEntryNode)), 173 DelayLocoBrake = new ObservableCollection<Delay.Entry>(parent.XPathSelectElements("DelayLocoBrake/Entry").Select(ParseDelayEntryNode)) 174 }; 175 } 176 ParseDelayEntryNode(XElement parent)177 private static Delay.Entry ParseDelayEntryNode(XElement parent) 178 { 179 return new Delay.Entry 180 { 181 Up = (double)parent.Element("Up"), 182 Down = (double)parent.Element("Down") 183 }; 184 } 185 ParseMoveNode(XElement parent)186 private static Move ParseMoveNode(XElement parent) 187 { 188 return new Move 189 { 190 JerkPowerUp = (double)parent.Element("JerkPowerUp"), 191 JerkPowerDown = (double)parent.Element("JerkPowerDown"), 192 JerkBrakeUp = (double)parent.Element("JerkBrakeUp"), 193 JerkBrakeDown = (double)parent.Element("JerkBrakeDown") 194 }; 195 } 196 ParseBrakeNode(XElement parent)197 private static Brake ParseBrakeNode(XElement parent) 198 { 199 return new Brake 200 { 201 BrakeType = (BrakeSystemType)Enum.Parse(typeof(BrakeSystemType), (string)parent.Element("BrakeType")), 202 LocoBrakeType = (Brake.LocoBrakeTypes)Enum.Parse(typeof(Brake.LocoBrakeTypes), (string)parent.Element("LocoBrakeType")), 203 BrakeControlSystem = (EletropneumaticBrakeType)Enum.Parse(typeof(EletropneumaticBrakeType), (string)parent.Element("BrakeControlSystem")), 204 BrakeControlSpeed = (double)parent.Element("BrakeControlSpeed") 205 }; 206 } 207 ParsePressureNode(XElement parent)208 private static Pressure ParsePressureNode(XElement parent) 209 { 210 return new Pressure 211 { 212 BrakeCylinderServiceMaximumPressure = (double)parent.Element("BrakeCylinderServiceMaximumPressure"), 213 BrakeCylinderEmergencyMaximumPressure = (double)parent.Element("BrakeCylinderEmergencyMaximumPressure"), 214 MainReservoirMinimumPressure = (double)parent.Element("MainReservoirMinimumPressure"), 215 MainReservoirMaximumPressure = (double)parent.Element("MainReservoirMaximumPressure"), 216 BrakePipeNormalPressure = (double)parent.Element("BrakePipeNormalPressure") 217 }; 218 } 219 ParseAccelerationNode(XElement parent)220 private static Acceleration ParseAccelerationNode(XElement parent) 221 { 222 return new Acceleration 223 { 224 Entries = new ObservableCollection<Acceleration.Entry>(parent.Elements("Entry").Select(n => new Acceleration.Entry 225 { 226 A0 = (double)n.Element("a0"), 227 A1 = (double)n.Element("a1"), 228 V1 = (double)n.Element("v1"), 229 V2 = (double)n.Element("v2"), 230 E = (double)n.Element("e") 231 })) 232 }; 233 } 234 ParseMotorNode(XElement parent)235 private static Motor ParseMotorNode(XElement parent) 236 { 237 return new Motor 238 { 239 Tracks = new ObservableCollection<Motor.Track>(parent.Elements("Track").Select(ParseTrackNode)) 240 }; 241 } 242 ParseTrackNode(XElement parent)243 private static Motor.Track ParseTrackNode(XElement parent) 244 { 245 Motor.Track track = new Motor.Track(); 246 247 ParseVertexLineNode(parent.Element("Pitch"), out track.PitchVertices, out track.PitchLines); 248 ParseVertexLineNode(parent.Element("Volume"), out track.VolumeVertices, out track.VolumeLines); 249 ParseAreaNode(parent.Element("SoundIndex"), out track.SoundIndices); 250 251 return track; 252 } 253 ParseVertexLineNode(XElement parent, out Motor.VertexLibrary vertices, out ObservableCollection<Motor.Line> lines)254 private static void ParseVertexLineNode(XElement parent, out Motor.VertexLibrary vertices, out ObservableCollection<Motor.Line> lines) 255 { 256 vertices = new Motor.VertexLibrary(); 257 258 foreach (XElement n in parent.XPathSelectElements("Vertices/Vertex")) 259 { 260 double[] position = ((string)n.Element("Position")).Split(',').Select(double.Parse).ToArray(); 261 262 vertices.Add((int)n.Element("Id"), new Motor.Vertex(position[0], position[1])); 263 } 264 265 lines = new ObservableCollection<Motor.Line>(parent.XPathSelectElements("Lines/Line").Select(n => new Motor.Line((int)n.Element("LeftID"), (int)n.Element("RightID")))); 266 } 267 ParseAreaNode(XElement parent, out ObservableCollection<Motor.Area> areas)268 private static void ParseAreaNode(XElement parent, out ObservableCollection<Motor.Area> areas) 269 { 270 areas = new ObservableCollection<Motor.Area>(parent.XPathSelectElements("Areas/Area").Select(n => new Motor.Area((double)n.Element("LeftX"), (double)n.Element("RightX"), (int)n.Element("Index")))); 271 } 272 ParseCouplerNode(XElement parent)273 private static Models.Trains.Coupler ParseCouplerNode(XElement parent) 274 { 275 return new Models.Trains.Coupler 276 { 277 Min = (double)parent.Element("Min"), 278 Max = (double)parent.Element("Max"), 279 Object = (string)parent.Element("Object") 280 }; 281 } 282 ParsePanelNode(XElement parent)283 private static Panel ParsePanelNode(XElement parent) 284 { 285 return new Panel 286 { 287 This = ParseThisNode(parent.Element("This")), 288 Screens = new ObservableCollection<Screen>(parent.XPathSelectElements("Screens/Screen").Select(ParseScreenNode)), 289 PanelElements = new ObservableCollection<PanelElement>(parent.XPathSelectElements("PanelElements/*").Select(ParsePanelElementNode).Where(x => x != null)) 290 }; 291 } 292 ParseThisNode(XElement parent)293 private static This ParseThisNode(XElement parent) 294 { 295 double[] center = ((string)parent.Element("Center")).Split(',').Select(double.Parse).ToArray(); 296 double[] origin = ((string)parent.Element("Origin")).Split(',').Select(double.Parse).ToArray(); 297 298 return new This 299 { 300 Resolution = (double)parent.Element("Resolution"), 301 Left = (double)parent.Element("Left"), 302 Right = (double)parent.Element("Right"), 303 Top = (double)parent.Element("Top"), 304 Bottom = (double)parent.Element("Bottom"), 305 DaytimeImage = (string)parent.Element("DaytimeImage"), 306 NighttimeImage = (string)parent.Element("NighttimeImage"), 307 TransparentColor = Color24.ParseHexColor((string)parent.Element("TransparentColor")), 308 CenterX = center[0], 309 CenterY = center[1], 310 OriginX = origin[0], 311 OriginY = origin[1] 312 }; 313 } 314 ParseScreenNode(XElement parent)315 private static Screen ParseScreenNode(XElement parent) 316 { 317 Screen screen = new Screen 318 { 319 Number = (int)parent.Element("Number"), 320 Layer = (int)parent.Element("Layer"), 321 PanelElements = new ObservableCollection<PanelElement>(parent.XPathSelectElements("PanelElements/*").Select(ParsePanelElementNode).Where(x => x != null)) 322 }; 323 324 screen.TouchElements = new ObservableCollection<Models.Panels.TouchElement>(parent.XPathSelectElements("TouchElements/Touch").Select(x => ParseTouchElementNode(screen, x))); 325 326 return screen; 327 } 328 ParsePanelElementNode(XElement parent)329 private static PanelElement ParsePanelElementNode(XElement parent) 330 { 331 PanelElement element = null; 332 333 switch (parent.Name.LocalName) 334 { 335 case "PilotLamp": 336 ParsePilotLampElementNode(parent, out element); 337 break; 338 case "Needle": 339 ParseNeedleElementNode(parent, out element); 340 break; 341 case "DigitalNumber": 342 ParseDigitalNumberElementNode(parent, out element); 343 break; 344 case "DigitalGauge": 345 ParseDigitalGaugeElementNode(parent, out element); 346 break; 347 case "LinearGauge": 348 ParseLinearGaugeElementNode(parent, out element); 349 break; 350 case "Timetable": 351 ParseTimetableElementNode(parent, out element); 352 break; 353 } 354 355 return element; 356 } 357 ParsePilotLampElementNode(XElement parent, out PanelElement element)358 private static void ParsePilotLampElementNode(XElement parent, out PanelElement element) 359 { 360 double[] location = ((string)parent.Element("Location")).Split(',').Select(double.Parse).ToArray(); 361 362 element = new Models.Panels.PilotLampElement 363 { 364 LocationX = location[0], 365 LocationY = location[1], 366 Layer = (int)parent.Element("Layer"), 367 Subject = ParseSubjectNode(parent.Element("Subject")), 368 DaytimeImage = (string)parent.Element("DaytimeImage"), 369 NighttimeImage = (string)parent.Element("NighttimeImage"), 370 TransparentColor = Color24.ParseHexColor((string)parent.Element("TransparentColor")) 371 }; 372 } 373 ParseNeedleElementNode(XElement parent, out PanelElement element)374 private static void ParseNeedleElementNode(XElement parent, out PanelElement element) 375 { 376 double[] location = ((string)parent.Element("Location")).Split(',').Select(double.Parse).ToArray(); 377 double[] origin = ((string)parent.Element("Origin")).Split(',').Select(double.Parse).ToArray(); 378 379 element = new NeedleElement 380 { 381 LocationX = location[0], 382 LocationY = location[1], 383 Layer = (int)parent.Element("Layer"), 384 Subject = ParseSubjectNode(parent.Element("Subject")), 385 DaytimeImage = (string)parent.Element("DaytimeImage"), 386 NighttimeImage = (string)parent.Element("NighttimeImage"), 387 TransparentColor = Color24.ParseHexColor((string)parent.Element("TransparentColor")), 388 DefinedRadius = (bool)parent.Element("DefinedRadius"), 389 Radius = (double)parent.Element("Radius"), 390 Color = Color24.ParseHexColor((string)parent.Element("Color")), 391 DefinedOrigin = (bool)parent.Element("DefinedOrigin"), 392 OriginX = origin[0], 393 OriginY = origin[1], 394 InitialAngle = (double)parent.Element("InitialAngle"), 395 LastAngle = (double)parent.Element("LastAngle"), 396 Minimum = (double)parent.Element("Minimum"), 397 Maximum = (double)parent.Element("Maximum"), 398 DefinedNaturalFreq = (bool)parent.Element("DefinedNaturalFreq"), 399 NaturalFreq = (double)parent.Element("NaturalFreq"), 400 DefinedDampingRatio = (bool)parent.Element("DefinedDampingRatio"), 401 DampingRatio = (double)parent.Element("DampingRatio"), 402 Backstop = (bool)parent.Element("Backstop"), 403 Smoothed = (bool)parent.Element("Smoothed") 404 }; 405 } 406 ParseDigitalNumberElementNode(XElement parent, out PanelElement element)407 private static void ParseDigitalNumberElementNode(XElement parent, out PanelElement element) 408 { 409 double[] location = ((string)parent.Element("Location")).Split(',').Select(double.Parse).ToArray(); 410 411 element = new DigitalNumberElement 412 { 413 LocationX = location[0], 414 LocationY = location[1], 415 Layer = (int)parent.Element("Layer"), 416 Subject = ParseSubjectNode(parent.Element("Subject")), 417 DaytimeImage = (string)parent.Element("DaytimeImage"), 418 NighttimeImage = (string)parent.Element("NighttimeImage"), 419 TransparentColor = Color24.ParseHexColor((string)parent.Element("TransparentColor")), 420 Interval = (int)parent.Element("Interval") 421 }; 422 } 423 ParseDigitalGaugeElementNode(XElement parent, out PanelElement element)424 private static void ParseDigitalGaugeElementNode(XElement parent, out PanelElement element) 425 { 426 double[] location = ((string)parent.Element("Location")).Split(',').Select(double.Parse).ToArray(); 427 428 element = new DigitalGaugeElement 429 { 430 LocationX = location[0], 431 LocationY = location[1], 432 Layer = (int)parent.Element("Layer"), 433 Subject = ParseSubjectNode(parent.Element("Subject")), 434 Radius = (double)parent.Element("Radius"), 435 Color = Color24.ParseHexColor((string)parent.Element("Color")), 436 InitialAngle = (double)parent.Element("InitialAngle"), 437 LastAngle = (double)parent.Element("LastAngle"), 438 Minimum = (double)parent.Element("Minimum"), 439 Maximum = (double)parent.Element("Maximum"), 440 Step = (double)parent.Element("Step") 441 }; 442 } 443 ParseLinearGaugeElementNode(XElement parent, out PanelElement element)444 private static void ParseLinearGaugeElementNode(XElement parent, out PanelElement element) 445 { 446 double[] location = ((string)parent.Element("Location")).Split(',').Select(double.Parse).ToArray(); 447 int[] direction = ((string)parent.Element("Direction")).Split(',').Select(int.Parse).ToArray(); 448 449 element = new LinearGaugeElement 450 { 451 LocationX = location[0], 452 LocationY = location[1], 453 Layer = (int)parent.Element("Layer"), 454 Subject = ParseSubjectNode(parent.Element("Subject")), 455 DaytimeImage = (string)parent.Element("DaytimeImage"), 456 NighttimeImage = (string)parent.Element("NighttimeImage"), 457 TransparentColor = Color24.ParseHexColor((string)parent.Element("TransparentColor")), 458 Minimum = (double)parent.Element("Minimum"), 459 Maximum = (double)parent.Element("Maximum"), 460 DirectionX = direction[0], 461 DirectionY = direction[1], 462 Width = (int)parent.Element("Width") 463 }; 464 } 465 ParseTimetableElementNode(XElement parent, out PanelElement element)466 private static void ParseTimetableElementNode(XElement parent, out PanelElement element) 467 { 468 double[] location = ((string)parent.Element("Location")).Split(',').Select(double.Parse).ToArray(); 469 470 element = new TimetableElement 471 { 472 LocationX = location[0], 473 LocationY = location[1], 474 Layer = (int)parent.Element("Layer"), 475 Width = (double)parent.Element("Width"), 476 Height = (double)parent.Element("Height"), 477 TransparentColor = Color24.ParseHexColor((string)parent.Element("TransparentColor")) 478 }; 479 } 480 ParseSubjectNode(XElement parent)481 private static Subject ParseSubjectNode(XElement parent) 482 { 483 return new Subject 484 { 485 Base = (SubjectBase)Enum.Parse(typeof(SubjectBase), (string)parent.Element("Base")), 486 BaseOption = (int)parent.Element("BaseOption"), 487 Suffix = (SubjectSuffix)Enum.Parse(typeof(SubjectSuffix), (string)parent.Element("Suffix")), 488 SuffixOption = (int)parent.Element("SuffixOption") 489 }; 490 } 491 ParseTouchElementNode(Screen screen, XElement parent)492 private static Models.Panels.TouchElement ParseTouchElementNode(Screen screen, XElement parent) 493 { 494 double[] location = ((string)parent.Element("Location")).Split(',').Select(double.Parse).ToArray(); 495 double[] size = ((string)parent.Element("Size")).Split(',').Select(double.Parse).ToArray(); 496 497 Models.Panels.TouchElement element = new Models.Panels.TouchElement(screen) 498 { 499 LocationX = location[0], 500 LocationY = location[1], 501 SizeX = size[0], 502 SizeY = size[1], 503 JumpScreen = (int)parent.Element("JumpScreen") 504 }; 505 506 if (parent.Element("SoundIndex") != null) 507 { 508 element.SoundEntries.Add(new Models.Panels.TouchElement.SoundEntry 509 { 510 Index = (int)parent.Element("SoundIndex") 511 }); 512 } 513 514 if (parent.Element("CommandInfo") != null && parent.Element("CommandOption") != null) 515 { 516 element.CommandEntries.Add(new Models.Panels.TouchElement.CommandEntry 517 { 518 Info = Translations.CommandInfos.TryGetInfo((Translations.Command)Enum.Parse(typeof(Translations.Command), (string)parent.Element("CommandInfo"))), 519 Option = (int)parent.Element("CommandOption") 520 }); 521 } 522 523 element.SoundEntries.AddRange(parent.XPathSelectElements("SoundEntries/Entry").Select(ParseTouchElementSoundEntryNode)); 524 element.CommandEntries.AddRange(parent.XPathSelectElements("CommandEntries/Entry").Select(ParseTouchElementCommandEntryNode)); 525 element.Layer = (int)parent.Element("Layer"); 526 527 return element; 528 } 529 ParseTouchElementSoundEntryNode(XElement parent)530 private static Models.Panels.TouchElement.SoundEntry ParseTouchElementSoundEntryNode(XElement parent) 531 { 532 return new Models.Panels.TouchElement.SoundEntry 533 { 534 Index = (int)parent.Element("Index") 535 }; 536 } 537 ParseTouchElementCommandEntryNode(XElement parent)538 private static Models.Panels.TouchElement.CommandEntry ParseTouchElementCommandEntryNode(XElement parent) 539 { 540 return new Models.Panels.TouchElement.CommandEntry 541 { 542 Info = Translations.CommandInfos.TryGetInfo((Translations.Command)Enum.Parse(typeof(Translations.Command), (string)parent.Element("Info"))), 543 Option = (int)parent.Element("Option") 544 }; 545 } 546 ParseSoundsNode(XElement parent)547 private static Sound ParseSoundsNode(XElement parent) 548 { 549 Sound sound = new Sound(); 550 551 ParseArraySoundNode<RunElement>(parent.Element("Run"), sound.SoundElements); 552 ParseArraySoundNode<FlangeElement>(parent.Element("Flange"), sound.SoundElements); 553 ParseArraySoundNode<MotorElement>(parent.Element("Motor"), sound.SoundElements); 554 ParseArraySoundNode<FrontSwitchElement>(parent.Element("FrontSwitch"), sound.SoundElements); 555 ParseArraySoundNode<RearSwitchElement>(parent.Element("RearSwitch"), sound.SoundElements); 556 ParseArraySoundNode<BrakeElement, BrakeKey>(parent.Element("Brake"), sound.SoundElements); 557 ParseArraySoundNode<CompressorElement, CompressorKey>(parent.Element("Compressor"), sound.SoundElements); 558 ParseArraySoundNode<SuspensionElement, SuspensionKey>(parent.Element("Suspension"), sound.SoundElements); 559 ParseArraySoundNode<PrimaryHornElement, HornKey>(parent.Element("PrimaryHorn"), sound.SoundElements); 560 ParseArraySoundNode<SecondaryHornElement, HornKey>(parent.Element("SecondaryHorn"), sound.SoundElements); 561 ParseArraySoundNode<MusicHornElement, HornKey>(parent.Element("MusicHornHorn"), sound.SoundElements); 562 ParseArraySoundNode<DoorElement, DoorKey>(parent.Element("Door"), sound.SoundElements); 563 ParseArraySoundNode<AtsElement>(parent.Element("Ats"), sound.SoundElements); 564 ParseArraySoundNode<BuzzerElement, BuzzerKey>(parent.Element("Buzzer"), sound.SoundElements); 565 ParseArraySoundNode<Models.Sounds.PilotLampElement, PilotLampKey>(parent.Element("PilotLamp"), sound.SoundElements); 566 ParseArraySoundNode<BrakeHandleElement, BrakeHandleKey>(parent.Element("BrakeHandle"), sound.SoundElements); 567 ParseArraySoundNode<MasterControllerElement, MasterControllerKey>(parent.Element("MasterController"), sound.SoundElements); 568 ParseArraySoundNode<ReverserElement, ReverserKey>(parent.Element("Reverser"), sound.SoundElements); 569 ParseArraySoundNode<BreakerElement, BreakerKey>(parent.Element("Breaker"), sound.SoundElements); 570 ParseArraySoundNode<RequestStopElement, RequestStopKey>(parent.Element("RequestStop"), sound.SoundElements); 571 ParseArraySoundNode<Models.Sounds.TouchElement>(parent.Element("Touch"), sound.SoundElements); 572 ParseArraySoundNode<OthersElement, OthersKey>(parent.Element("Others"), sound.SoundElements); 573 574 return sound; 575 } 576 577 private static T ParseSoundNode<T>(XElement parent) where T : SoundElement<int>, new() 578 { 579 double[] position = ((string)parent.Element("Position")).Split(',').Select(double.Parse).ToArray(); 580 581 return new T 582 { 583 Key = (int)parent.Element("Key"), 584 FilePath = (string)parent.Element("FilePath"), 585 DefinedPosition = (bool)parent.Element("DefinedPosition"), 586 PositionX = position[0], 587 PositionY = position[1], 588 PositionZ = position[2], 589 DefinedRadius = (bool)parent.Element("DefinedRadius"), 590 Radius = (double)parent.Element("Radius") 591 }; 592 } 593 594 private static T ParseSoundNode<T, U>(XElement parent) where T : SoundElement<U>, new() 595 { 596 double[] position = ((string)parent.Element("Position")).Split(',').Select(double.Parse).ToArray(); 597 598 return new T 599 { 600 Key = (U)Enum.Parse(typeof(U), (string)parent.Element("Key")), 601 FilePath = (string)parent.Element("FilePath"), 602 DefinedPosition = (bool)parent.Element("DefinedPosition"), 603 PositionX = position[0], 604 PositionY = position[1], 605 PositionZ = position[2], 606 DefinedRadius = (bool)parent.Element("DefinedRadius"), 607 Radius = (double)parent.Element("Radius") 608 }; 609 } 610 611 private static void ParseArraySoundNode<T>(XElement parent, ICollection<SoundElement> elements) where T : SoundElement<int>, new() 612 { 613 if (parent != null) 614 { 615 elements.AddRange(parent.Elements("Sound").Select(ParseSoundNode<T>)); 616 } 617 } 618 619 private static void ParseArraySoundNode<T, U>(XElement parent, ICollection<SoundElement> elements) where T : SoundElement<U>, new() 620 { 621 if (parent != null) 622 { 623 elements.AddRange(parent.Elements("Sound").Select(ParseSoundNode<T, U>)); 624 } 625 } 626 } 627 } 628