3030using System . Collections . Generic ;
3131using System . Diagnostics ;
3232using System . IO ;
33+ using System . Linq ;
3334using Event = Orts . Common . Event ;
3435using Events = Orts . Common . Events ;
3536
@@ -175,8 +176,6 @@ internal override void Mark()
175176
176177 class SignalShapeHead
177178 {
178- static readonly Dictionary < string , SignalTypeData > SignalTypes = new Dictionary < string , SignalTypeData > ( ) ;
179-
180179 readonly Viewer Viewer ;
181180 readonly SignalShape SignalShape ;
182181#if DEBUG_SIGNAL_SHAPES
@@ -196,7 +195,7 @@ class SignalShapeHead
196195 private readonly SignalLightState [ ] lightStates ;
197196
198197 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 )
200199 {
201200 Viewer = viewer ;
202201 SignalShape = signalShape ;
@@ -217,10 +216,7 @@ public SignalShapeHead(Viewer viewer, SignalShape signalShape, int index, Signal
217216
218217 var mstsSignalType = viewer . SIGCFG . SignalTypes [ mstsSignalSubObj . SignalSubSignalType ] ;
219218
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 ) ;
224220
225221 if ( SignalTypeData . Semaphore )
226222 {
@@ -412,142 +408,200 @@ void renderEffect(Material material)
412408 [ CallOnThread ( "Loader" ) ]
413409 internal void Mark ( )
414410 {
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 ;
417452 }
418453 }
419454
420- class SignalTypeData
455+ public void Sweep ( )
421456 {
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 ;
424470#if DEBUG_SIGNAL_SHAPES
425471 public readonly SignalTypeDataType Type ;
426472#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 ) )
439489 {
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" ) ;
444492#if DEBUG_SIGNAL_SHAPES
445493 Type = SignalTypeDataType . Normal ;
446494#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" ) ;
455503#if DEBUG_SIGNAL_SHAPES
456504 Type = ( SignalTypeDataType ) mstsSignalType . FnType ;
457505#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 )
459522 {
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+ }
481529
482- foreach ( var mstsSignalLight in mstsSignalType . Lights )
530+ foreach ( var mstsSignalLight in mstsSignalType . Lights )
531+ {
532+ if ( ! viewer . SIGCFG . LightsTable . ContainsKey ( mstsSignalLight . Name ) )
483533 {
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 ;
492536 }
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 ) ;
493540 }
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 ;
502541 }
503542
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 ;
505550 }
551+
552+ OnOffTimeS = mstsSignalType . OnOffTimeS ;
506553 }
507554
508- enum SignalTypeDataType
555+ public void Mark ( )
509556 {
510- Normal ,
511- Distance ,
512- Repeater ,
513- Shunting ,
514- Info ,
557+ Viewer . SignalTypeDataManager . Mark ( this ) ;
558+ Material . Mark ( ) ;
559+ GlowMaterial ? . Mark ( ) ;
515560 }
561+ }
516562
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+ }
522571
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 )
524581 {
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+ }
535590
536- if ( drawStateData . DrawLights != null )
591+ if ( drawStateData . DrawLights != null )
592+ {
593+ foreach ( var drawLight in drawStateData . DrawLights )
537594 {
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
539598 {
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 ;
547601 }
548602 }
549- SemaphorePos = drawStateData . SemaphorePos ;
550603 }
604+ SemaphorePos = drawStateData . SemaphorePos ;
551605 }
552606 }
553607
0 commit comments