30
30
using System . Collections . Generic ;
31
31
using System . Diagnostics ;
32
32
using System . IO ;
33
+ using System . Linq ;
33
34
using Event = Orts . Common . Event ;
34
35
using Events = Orts . Common . Events ;
35
36
@@ -175,8 +176,6 @@ internal override void Mark()
175
176
176
177
class SignalShapeHead
177
178
{
178
- static readonly Dictionary < string , SignalTypeData > SignalTypes = new Dictionary < string , SignalTypeData > ( ) ;
179
-
180
179
readonly Viewer Viewer ;
181
180
readonly SignalShape SignalShape ;
182
181
#if DEBUG_SIGNAL_SHAPES
@@ -196,7 +195,7 @@ class SignalShapeHead
196
195
private readonly SignalLightState [ ] lightStates ;
197
196
198
197
public SignalShapeHead ( Viewer viewer , SignalShape signalShape , int index , SignalHead signalHead ,
199
- Orts . Formats . Msts . SignalItem mstsSignalItem , Orts . Formats . Msts . SignalShape . SignalSubObj mstsSignalSubObj )
198
+ SignalItem mstsSignalItem , Formats . Msts . SignalShape . SignalSubObj mstsSignalSubObj )
200
199
{
201
200
Viewer = viewer ;
202
201
SignalShape = signalShape ;
@@ -217,10 +216,7 @@ public SignalShapeHead(Viewer viewer, SignalShape signalShape, int index, Signal
217
216
218
217
var mstsSignalType = viewer . SIGCFG . SignalTypes [ mstsSignalSubObj . SignalSubSignalType ] ;
219
218
220
- if ( SignalTypes . ContainsKey ( mstsSignalType . Name ) )
221
- SignalTypeData = SignalTypes [ mstsSignalType . Name ] ;
222
- else
223
- SignalTypeData = SignalTypes [ mstsSignalType . Name ] = new SignalTypeData ( viewer , mstsSignalType ) ;
219
+ SignalTypeData = viewer . SignalTypeDataManager . Get ( mstsSignalType ) ;
224
220
225
221
if ( SignalTypeData . Semaphore )
226
222
{
@@ -412,142 +408,200 @@ void renderEffect(Material material)
412
408
[ CallOnThread ( "Loader" ) ]
413
409
internal void Mark ( )
414
410
{
415
- SignalTypeData . Material . Mark ( ) ;
416
- SignalTypeData . GlowMaterial ? . Mark ( ) ;
411
+ SignalTypeData . Mark ( ) ;
412
+ }
413
+ }
414
+ }
415
+
416
+ public class SignalTypeDataManager
417
+ {
418
+ readonly Viewer Viewer ;
419
+
420
+ Dictionary < string , SignalTypeData > SignalTypes = new Dictionary < string , SignalTypeData > ( ) ;
421
+ Dictionary < string , bool > SignalTypesMarks ;
422
+
423
+ public SignalTypeDataManager ( Viewer viewer )
424
+ {
425
+ Viewer = viewer ;
426
+ }
427
+
428
+ public SignalTypeData Get ( SignalType mstsSignalType )
429
+ {
430
+ if ( ! SignalTypes . ContainsKey ( mstsSignalType . Name ) )
431
+ {
432
+ SignalTypes [ mstsSignalType . Name ] = new SignalTypeData ( Viewer , mstsSignalType ) ;
433
+ }
434
+
435
+ return SignalTypes [ mstsSignalType . Name ] ;
436
+ }
437
+
438
+ public void Mark ( )
439
+ {
440
+ SignalTypesMarks = new Dictionary < string , bool > ( SignalTypes . Count ) ;
441
+ foreach ( string signalTypeName in SignalTypes . Keys )
442
+ {
443
+ SignalTypesMarks . Add ( signalTypeName , false ) ;
444
+ }
445
+ }
446
+
447
+ public void Mark ( SignalTypeData signalType )
448
+ {
449
+ if ( SignalTypes . ContainsValue ( signalType ) )
450
+ {
451
+ SignalTypesMarks [ SignalTypes . First ( x => x . Value == signalType ) . Key ] = true ;
417
452
}
418
453
}
419
454
420
- class SignalTypeData
455
+ public void Sweep ( )
421
456
{
422
- public readonly Material Material ;
423
- public readonly Material GlowMaterial ;
457
+ foreach ( var signalTypeName in SignalTypesMarks . Where ( x => ! x . Value ) . Select ( x => x . Key ) )
458
+ {
459
+ SignalTypes . Remove ( signalTypeName ) ;
460
+ }
461
+ }
462
+ }
463
+
464
+ public class SignalTypeData
465
+ {
466
+ readonly Viewer Viewer ;
467
+
468
+ public readonly Material Material ;
469
+ public readonly Material GlowMaterial ;
424
470
#if DEBUG_SIGNAL_SHAPES
425
471
public readonly SignalTypeDataType Type ;
426
472
#endif
427
- public readonly List < SignalLightPrimitive > Lights = new List < SignalLightPrimitive > ( ) ;
428
- public readonly List < bool > LightsSemaphoreChange = new List < bool > ( ) ;
429
- public readonly Dictionary < int , SignalAspectData > DrawAspects = new Dictionary < int , SignalAspectData > ( ) ;
430
- public readonly float FlashTimeOn ;
431
- public readonly float FlashTimeTotal ;
432
- public readonly float OnOffTimeS ;
433
- public readonly bool Semaphore ;
434
- public readonly bool DayLight = true ;
435
- public readonly float SemaphoreAnimationTime ;
436
- public bool AreSemaphoresReindexed ;
437
-
438
- public SignalTypeData ( Viewer viewer , Orts . Formats . Msts . SignalType mstsSignalType )
473
+ public readonly List < SignalLightPrimitive > Lights = new List < SignalLightPrimitive > ( ) ;
474
+ public readonly List < bool > LightsSemaphoreChange = new List < bool > ( ) ;
475
+ public readonly Dictionary < int , SignalAspectData > DrawAspects = new Dictionary < int , SignalAspectData > ( ) ;
476
+ public readonly float FlashTimeOn ;
477
+ public readonly float FlashTimeTotal ;
478
+ public readonly float OnOffTimeS ;
479
+ public readonly bool Semaphore ;
480
+ public readonly bool DayLight = true ;
481
+ public readonly float SemaphoreAnimationTime ;
482
+ public bool AreSemaphoresReindexed ;
483
+
484
+ public SignalTypeData ( Viewer viewer , SignalType mstsSignalType )
485
+ {
486
+ Viewer = viewer ;
487
+
488
+ if ( ! viewer . SIGCFG . LightTextures . ContainsKey ( mstsSignalType . LightTextureName ) )
439
489
{
440
- if ( ! viewer . SIGCFG . LightTextures . ContainsKey ( mstsSignalType . LightTextureName ) )
441
- {
442
- Trace . TraceWarning ( "Skipped invalid light texture {1} for signal type {0}" , mstsSignalType . Name , mstsSignalType . LightTextureName ) ;
443
- Material = viewer . MaterialManager . Load ( "missing-signal-light" ) ;
490
+ Trace . TraceWarning ( "Skipped invalid light texture {1} for signal type {0}" , mstsSignalType . Name , mstsSignalType . LightTextureName ) ;
491
+ Material = viewer . MaterialManager . Load ( "missing-signal-light" ) ;
444
492
#if DEBUG_SIGNAL_SHAPES
445
493
Type = SignalTypeDataType . Normal ;
446
494
#endif
447
- FlashTimeOn = 1 ;
448
- FlashTimeTotal = 2 ;
449
- }
450
- else
451
- {
452
- var mstsLightTexture = viewer . SIGCFG . LightTextures [ mstsSignalType . LightTextureName ] ;
453
- Material = viewer . MaterialManager . Load ( "SignalLight" , Helpers . GetRouteTextureFile ( viewer . Simulator , Helpers . TextureFlags . None , mstsLightTexture . TextureFile ) ) ;
454
- GlowMaterial = viewer . MaterialManager . Load ( "SignalLightGlow" ) ;
495
+ FlashTimeOn = 1 ;
496
+ FlashTimeTotal = 2 ;
497
+ }
498
+ else
499
+ {
500
+ var mstsLightTexture = viewer . SIGCFG . LightTextures [ mstsSignalType . LightTextureName ] ;
501
+ Material = viewer . MaterialManager . Load ( "SignalLight" , Helpers . GetRouteTextureFile ( viewer . Simulator , Helpers . TextureFlags . None , mstsLightTexture . TextureFile ) ) ;
502
+ GlowMaterial = viewer . MaterialManager . Load ( "SignalLightGlow" ) ;
455
503
#if DEBUG_SIGNAL_SHAPES
456
504
Type = ( SignalTypeDataType ) mstsSignalType . FnType ;
457
505
#endif
458
- if ( mstsSignalType . Lights != null )
506
+ if ( mstsSignalType . Lights != null )
507
+ {
508
+ // Set up some heuristic glow values from the available data:
509
+ // Typical electric light is 3.0/5.0
510
+ // Semaphore is 0.0/5.0
511
+ // Theatre box is 0.0/0.0
512
+ var glowDay = 3.0f ;
513
+ var glowNight = 5.0f ;
514
+
515
+ if ( mstsSignalType . Semaphore )
516
+ glowDay = 0.0f ;
517
+ if ( mstsSignalType . FnType == MstsSignalFunction . INFO || mstsSignalType . FnType == MstsSignalFunction . SHUNTING ) // These are good at identifying theatre boxes.
518
+ glowDay = glowNight = 0.0f ;
519
+
520
+ // use values from signal if defined
521
+ if ( mstsSignalType . DayGlow . HasValue )
459
522
{
460
- // Set up some heuristic glow values from the available data:
461
- // Typical electric light is 3.0/5.0
462
- // Semaphore is 0.0/5.0
463
- // Theatre box is 0.0/0.0
464
- var glowDay = 3.0f ;
465
- var glowNight = 5.0f ;
466
-
467
- if ( mstsSignalType . Semaphore )
468
- glowDay = 0.0f ;
469
- if ( mstsSignalType . FnType == MstsSignalFunction . INFO || mstsSignalType . FnType == MstsSignalFunction . SHUNTING ) // These are good at identifying theatre boxes.
470
- glowDay = glowNight = 0.0f ;
471
-
472
- // use values from signal if defined
473
- if ( mstsSignalType . DayGlow . HasValue )
474
- {
475
- glowDay = mstsSignalType . DayGlow . Value ;
476
- }
477
- if ( mstsSignalType . NightGlow . HasValue )
478
- {
479
- glowNight = mstsSignalType . NightGlow . Value ;
480
- }
523
+ glowDay = mstsSignalType . DayGlow . Value ;
524
+ }
525
+ if ( mstsSignalType . NightGlow . HasValue )
526
+ {
527
+ glowNight = mstsSignalType . NightGlow . Value ;
528
+ }
481
529
482
- foreach ( var mstsSignalLight in mstsSignalType . Lights )
530
+ foreach ( var mstsSignalLight in mstsSignalType . Lights )
531
+ {
532
+ if ( ! viewer . SIGCFG . LightsTable . ContainsKey ( mstsSignalLight . Name ) )
483
533
{
484
- if ( ! viewer . SIGCFG . LightsTable . ContainsKey ( mstsSignalLight . Name ) )
485
- {
486
- Trace . TraceWarning ( "Skipped invalid light {1} for signal type {0}" , mstsSignalType . Name , mstsSignalLight . Name ) ;
487
- continue ;
488
- }
489
- var mstsLight = viewer . SIGCFG . LightsTable [ mstsSignalLight . Name ] ;
490
- Lights . Add ( new SignalLightPrimitive ( viewer , new Vector3 ( - mstsSignalLight . X , mstsSignalLight . Y , mstsSignalLight . Z ) , mstsSignalLight . Radius , new Color ( mstsLight . r , mstsLight . g , mstsLight . b , mstsLight . a ) , glowDay , glowNight , mstsLightTexture . u0 , mstsLightTexture . v0 , mstsLightTexture . u1 , mstsLightTexture . v1 ) ) ;
491
- LightsSemaphoreChange . Add ( mstsSignalLight . SemaphoreChange ) ;
534
+ Trace . TraceWarning ( "Skipped invalid light {1} for signal type {0}" , mstsSignalType . Name , mstsSignalLight . Name ) ;
535
+ continue ;
492
536
}
537
+ var mstsLight = viewer . SIGCFG . LightsTable [ mstsSignalLight . Name ] ;
538
+ Lights . Add ( new SignalLightPrimitive ( viewer , new Vector3 ( - mstsSignalLight . X , mstsSignalLight . Y , mstsSignalLight . Z ) , mstsSignalLight . Radius , new Color ( mstsLight . r , mstsLight . g , mstsLight . b , mstsLight . a ) , glowDay , glowNight , mstsLightTexture . u0 , mstsLightTexture . v0 , mstsLightTexture . u1 , mstsLightTexture . v1 ) ) ;
539
+ LightsSemaphoreChange . Add ( mstsSignalLight . SemaphoreChange ) ;
493
540
}
494
-
495
- foreach ( KeyValuePair < string , Orts . Formats . Msts . SignalDrawState > sdrawstate in mstsSignalType . DrawStates )
496
- DrawAspects . Add ( sdrawstate . Value . Index , new SignalAspectData ( mstsSignalType , sdrawstate . Value ) ) ;
497
- FlashTimeOn = mstsSignalType . FlashTimeOn ;
498
- FlashTimeTotal = mstsSignalType . FlashTimeOn + mstsSignalType . FlashTimeOff ;
499
- Semaphore = mstsSignalType . Semaphore ;
500
- SemaphoreAnimationTime = mstsSignalType . SemaphoreInfo ;
501
- DayLight = mstsSignalType . DayLight ;
502
541
}
503
542
504
- OnOffTimeS = mstsSignalType . OnOffTimeS ;
543
+ foreach ( KeyValuePair < string , SignalDrawState > sdrawstate in mstsSignalType . DrawStates )
544
+ DrawAspects . Add ( sdrawstate . Value . Index , new SignalAspectData ( mstsSignalType , sdrawstate . Value ) ) ;
545
+ FlashTimeOn = mstsSignalType . FlashTimeOn ;
546
+ FlashTimeTotal = mstsSignalType . FlashTimeOn + mstsSignalType . FlashTimeOff ;
547
+ Semaphore = mstsSignalType . Semaphore ;
548
+ SemaphoreAnimationTime = mstsSignalType . SemaphoreInfo ;
549
+ DayLight = mstsSignalType . DayLight ;
505
550
}
551
+
552
+ OnOffTimeS = mstsSignalType . OnOffTimeS ;
506
553
}
507
554
508
- enum SignalTypeDataType
555
+ public void Mark ( )
509
556
{
510
- Normal ,
511
- Distance ,
512
- Repeater ,
513
- Shunting ,
514
- Info ,
557
+ Viewer . SignalTypeDataManager . Mark ( this ) ;
558
+ Material . Mark ( ) ;
559
+ GlowMaterial ? . Mark ( ) ;
515
560
}
561
+ }
516
562
517
- class SignalAspectData
518
- {
519
- public readonly bool [ ] DrawLights ;
520
- public readonly bool [ ] FlashLights ;
521
- public float SemaphorePos ;
563
+ enum SignalTypeDataType
564
+ {
565
+ Normal ,
566
+ Distance ,
567
+ Repeater ,
568
+ Shunting ,
569
+ Info ,
570
+ }
522
571
523
- public SignalAspectData ( Orts . Formats . Msts . SignalType mstsSignalType , Orts . Formats . Msts . SignalDrawState drawStateData )
572
+ public class SignalAspectData
573
+ {
574
+ public readonly bool [ ] DrawLights ;
575
+ public readonly bool [ ] FlashLights ;
576
+ public float SemaphorePos ;
577
+
578
+ public SignalAspectData ( SignalType mstsSignalType , SignalDrawState drawStateData )
579
+ {
580
+ if ( mstsSignalType . Lights != null )
524
581
{
525
- if ( mstsSignalType . Lights != null )
526
- {
527
- DrawLights = new bool [ mstsSignalType . Lights . Count ] ;
528
- FlashLights = new bool [ mstsSignalType . Lights . Count ] ;
529
- }
530
- else
531
- {
532
- DrawLights = null ;
533
- FlashLights = null ;
534
- }
582
+ DrawLights = new bool [ mstsSignalType . Lights . Count ] ;
583
+ FlashLights = new bool [ mstsSignalType . Lights . Count ] ;
584
+ }
585
+ else
586
+ {
587
+ DrawLights = null ;
588
+ FlashLights = null ;
589
+ }
535
590
536
- if ( drawStateData . DrawLights != null )
591
+ if ( drawStateData . DrawLights != null )
592
+ {
593
+ foreach ( var drawLight in drawStateData . DrawLights )
537
594
{
538
- foreach ( var drawLight in drawStateData . DrawLights )
595
+ if ( drawLight . LightIndex < 0 || DrawLights == null || drawLight . LightIndex >= DrawLights . Length )
596
+ Trace . TraceWarning ( "Skipped extra draw light {0}" , drawLight . LightIndex ) ;
597
+ else
539
598
{
540
- if ( drawLight . LightIndex < 0 || DrawLights == null || drawLight . LightIndex >= DrawLights . Length )
541
- Trace . TraceWarning ( "Skipped extra draw light {0}" , drawLight . LightIndex ) ;
542
- else
543
- {
544
- DrawLights [ drawLight . LightIndex ] = true ;
545
- FlashLights [ drawLight . LightIndex ] = drawLight . Flashing ;
546
- }
599
+ DrawLights [ drawLight . LightIndex ] = true ;
600
+ FlashLights [ drawLight . LightIndex ] = drawLight . Flashing ;
547
601
}
548
602
}
549
- SemaphorePos = drawStateData . SemaphorePos ;
550
603
}
604
+ SemaphorePos = drawStateData . SemaphorePos ;
551
605
}
552
606
}
553
607
0 commit comments