Skip to content

Commit 0be4ea2

Browse files
committed
Fixed unloaded signal lights not being reloaded when needed
1 parent 838cb63 commit 0be4ea2

File tree

3 files changed

+166
-108
lines changed

3 files changed

+166
-108
lines changed

Source/RunActivity/Viewer3D/Signals.cs

Lines changed: 162 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
using System.Collections.Generic;
3131
using System.Diagnostics;
3232
using System.IO;
33+
using System.Linq;
3334
using Event = Orts.Common.Event;
3435
using 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

Source/RunActivity/Viewer3D/Viewer.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ public class Viewer
6565
public SharedTextureManager TextureManager { get; private set; }
6666
public SharedMaterialManager MaterialManager { get; private set; }
6767
public SharedShapeManager ShapeManager { get; private set; }
68+
public SignalTypeDataManager SignalTypeDataManager { get; private set; }
6869
public Point DisplaySize { get { return RenderProcess.DisplaySize; } }
6970
// Components
7071
public Orts.Viewer3D.Processes.Game Game { get; private set; }
@@ -456,6 +457,7 @@ internal void Initialize()
456457

457458
MaterialManager = new SharedMaterialManager(this);
458459
ShapeManager = new SharedShapeManager(this);
460+
SignalTypeDataManager = new SignalTypeDataManager(this);
459461

460462
WindowManager = new WindowManager(this);
461463
MessagesWindow = new MessagesWindow(WindowManager);

Source/RunActivity/Viewer3D/World.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ public void Load()
9999
Viewer.ShapeManager.Mark();
100100
Viewer.MaterialManager.Mark();
101101
Viewer.TextureManager.Mark();
102+
Viewer.SignalTypeDataManager.Mark();
102103
if (Viewer.Settings.UseMSTSEnv)
103104
MSTSSky.Mark();
104105
else
@@ -112,6 +113,7 @@ public void Load()
112113
Viewer.ShapeManager.Sweep();
113114
Viewer.MaterialManager.Sweep();
114115
Viewer.TextureManager.Sweep();
116+
Viewer.SignalTypeDataManager.Sweep();
115117
}
116118
}
117119

0 commit comments

Comments
 (0)