Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove decorative and non-vehicle networks from speed limits manager. #513

Merged
merged 4 commits into from
Aug 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 84 additions & 44 deletions TLM/TLM/Manager/Impl/SpeedLimitManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace TrafficManager.Manager.Impl {
namespace TrafficManager.Manager.Impl {
using System;
using System.Collections.Generic;
using System.Diagnostics;
Expand All @@ -11,6 +11,9 @@
using UI.SubTools.SpeedLimits;
using UnityEngine;
using Util;
#if DEBUG
using State.ConfigData;
#endif

public class SpeedLimitManager
: AbstractGeometryObservingManager,
Expand All @@ -28,6 +31,14 @@ public class SpeedLimitManager
/// <summary>Ingame speed units, max possible speed</summary>
public const float MAX_SPEED = 10f * 2f; // 1000 km/h

public static readonly SpeedLimitManager Instance = new SpeedLimitManager();

// For each NetInfo (by name) and lane index: custom speed limit
internal Dictionary<string, float> CustomLaneSpeedLimitByNetInfoName;

// For each name: NetInfo
internal Dictionary<string, NetInfo> NetInfoByName;

/// <summary>Ingame speed units, minimal speed</summary>
private const float MIN_SPEED = 0.1f; // 5 km/h

Expand All @@ -39,14 +50,6 @@ public class SpeedLimitManager

private List<NetInfo> customizableNetInfos;

// For each NetInfo (by name) and lane index: custom speed limit
internal Dictionary<string, float> CustomLaneSpeedLimitByNetInfoName;

// For each name: NetInfo
internal Dictionary<string, NetInfo> NetInfoByName;

public static readonly SpeedLimitManager Instance = new SpeedLimitManager();

private SpeedLimitManager() {
vanillaLaneSpeedLimitsByNetInfoName = new Dictionary<string, float[]>();
CustomLaneSpeedLimitByNetInfoName = new Dictionary<string, float>();
Expand All @@ -55,11 +58,6 @@ private SpeedLimitManager() {
NetInfoByName = new Dictionary<string, NetInfo>();
}

protected override void InternalPrintDebugInfo() {
base.InternalPrintDebugInfo();
Log.NotImpl("InternalPrintDebugInfo for SpeedLimitManager");
}

/// <summary>
/// Determines if custom speed limits may be assigned to the given segment.
/// </summary>
Expand All @@ -84,7 +82,7 @@ public bool MayHaveCustomSpeedLimits(ushort segmentId, ref NetSegment segment) {
/// <summary>
/// Determines if custom speed limits may be assigned to the given lane info
/// </summary>
/// <param name="laneInfo"></param>
/// <param name="laneInfo">The <see cref="NetInfo.Lane"/> that you wish to check.</param>
/// <returns></returns>
public bool MayHaveCustomSpeedLimits(NetInfo.Lane laneInfo) {
return (laneInfo.m_laneType & LANE_TYPES) != NetInfo.LaneType.None
Expand Down Expand Up @@ -136,7 +134,7 @@ public float GetCustomSpeedLimit(ushort segmentId, NetInfo.Direction finalDir) {

++validLanes;

nextIter:
nextIter:
curLaneId = Singleton<NetManager>.instance.m_lanes.m_buffer[curLaneId].m_nextLane;
laneIndex++;
}
Expand Down Expand Up @@ -319,11 +317,11 @@ public float ToGameSpeedLimit(float customSpeedLimit) {
/// <summary>
/// Explicitly stores currently set speed limits for all segments of the specified NetInfo
/// </summary>
/// <param name="info"></param>
/// <param name="info">The <see cref="NetInfo"/> for which speed limits should be stored.</param>
public void FixCurrentSpeedLimits(NetInfo info) {
if (info == null) {
#if DEBUG
Log.Warning($"SpeedLimitManager.FixCurrentSpeedLimits: info is null!");
Log.Warning("SpeedLimitManager.FixCurrentSpeedLimits: info is null!");
#endif
return;
}
Expand Down Expand Up @@ -362,10 +360,10 @@ public void FixCurrentSpeedLimits(NetInfo info) {
/// <summary>
/// Explicitly clear currently set speed limits for all segments of the specified NetInfo
/// </summary>
/// <param name="info"></param>
/// <param name="info">The <see cref="NetInfo"/> for which speed limits should be cleared.</param>
public void ClearCurrentSpeedLimits(NetInfo info) {
if (info == null) {
Log._DebugOnlyWarning($"SpeedLimitManager.ClearCurrentSpeedLimits: info is null!");
Log._DebugOnlyWarning("SpeedLimitManager.ClearCurrentSpeedLimits: info is null!");
return;
}

Expand Down Expand Up @@ -407,17 +405,15 @@ public void ClearCurrentSpeedLimits(NetInfo info) {
/// <param name="info">the NetInfo of which the game default speed limit should be determined</param>
/// <param name="roundToSignLimits">if true, custom speed limit are rounded to speed limits
/// available as speed limit sign</param>
/// <returns></returns>
/// <returns>The vanilla speed limit, in game units.</returns>
public float GetVanillaNetInfoSpeedLimit(NetInfo info, bool roundToSignLimits = true) {
if (info == null) {
Log._DebugOnlyWarning(
$"SpeedLimitManager.GetVanillaNetInfoSpeedLimit: info is null!");
Log._DebugOnlyWarning("SpeedLimitManager.GetVanillaNetInfoSpeedLimit: info is null!");
return 0;
}

if (info.m_netAI == null) {
Log._DebugOnlyWarning(
$"SpeedLimitManager.GetVanillaNetInfoSpeedLimit: info.m_netAI is null!");
Log._DebugOnlyWarning("SpeedLimitManager.GetVanillaNetInfoSpeedLimit: info.m_netAI is null!");
return 0;
}

Expand Down Expand Up @@ -511,6 +507,11 @@ public void SetCustomNetInfoSpeedLimit(NetInfo info, float customSpeedLimit) {
}
}

protected override void InternalPrintDebugInfo() {
base.InternalPrintDebugInfo();
Log.NotImpl("InternalPrintDebugInfo for SpeedLimitManager");
}

private void UpdateNetInfoGameSpeedLimit(NetInfo info, float gameSpeedLimit) {
if (info == null) {
Log._DebugOnlyWarning(
Expand Down Expand Up @@ -546,7 +547,7 @@ private void UpdateNetInfoGameSpeedLimit(NetInfo info, float gameSpeedLimit) {
/// <param name="laneInfo"></param>
/// <param name="laneId"></param>
/// <param name="speedLimit">Game speed units, 0=unlimited</param>
/// <returns></returns>
/// <returns>Returns <c>true</c> if successful, otherwise <c>false</c>.</returns>
public bool SetSpeedLimit(ushort segmentId,
uint laneIndex,
NetInfo.Lane laneInfo,
Expand Down Expand Up @@ -623,7 +624,7 @@ public bool SetSpeedLimit(ushort segmentId, NetInfo.Direction finalDir, float sp
#endif
Flags.SetLaneSpeedLimit(curLaneId, speedLimit);

nextIter:
nextIter:
curLaneId = Singleton<NetManager>.instance.m_lanes.m_buffer[curLaneId].m_nextLane;
laneIndex++;
}
Expand Down Expand Up @@ -651,38 +652,75 @@ public override void OnBeforeLoadData() {

List<NetInfo> mainNetInfos = new List<NetInfo>();

Log.Info($"SpeedLimitManager.OnBeforeLoadData: {numLoaded} NetInfos loaded.");
// #378: Output some detail either side of null NetInfos to help track down their source
string previousNetInfoName = string.Empty; // last non-null netinfo
bool previousWasNull = false; // if true, next non-numm netinfo will be output to log

Log.Info($"SpeedLimitManager.OnBeforeLoadData: {numLoaded} NetInfos loaded. Verifying...");

for (uint i = 0; i < numLoaded; ++i) {
NetInfo info = PrefabCollection<NetInfo>.GetLoaded(i);

if (info == null
|| info.m_netAI == null
|| !(info.m_netAI is RoadBaseAI || info.m_netAI is MetroTrackAI ||
info.m_netAI is TrainTrackBaseAI)
|| !(info.m_dlcRequired == 0 || (uint)(info.m_dlcRequired & dlcMask) != 0u)) {
if (info == null) {
Log.Warning($"SpeedLimitManager.OnBeforeLoadData: NetInfo @ {i} is null!");
}
// Basic validity checks to see if this NetInfo is something speed limits can be applied to...

// Something in the workshop has null NetInfos in it...
if (info == null) {
Log.Info($"- Pre-null NetInfo (see warning below) was: {previousNetInfoName}");
Log.Warning($"SpeedLimitManager.OnBeforeLoadData: NetInfo @ {i} is null!");
previousWasNull = true;
continue;
}

string infoName = info.name;

// Resharper warning: condition always false
// if (infoName == null) {
// Log.Warning($"SpeedLimitManager.OnBeforeLoadData: NetInfo name @ {i} is null!");
// continue;
// }
// We need a valid name
if (string.IsNullOrEmpty(infoName)) {
Log.Warning($"SpeedLimitManager.OnBeforeLoadData: NetInfo name @ {i} is null or empty!");
continue;
}

previousNetInfoName = infoName;

if (previousWasNull) {
Log.Info($"- Post-null NetInfo (see warning above) is: {infoName}");
previousWasNull = false;
}

// Make sure it's valid AI
if (info.m_netAI == null) {
Log.Info($"- Skipped: NetInfo @ {i} ({infoName}) - m_netAI is null.");
continue;
}

// Must be road or track based
if (!(info.m_netAI is RoadBaseAI || info.m_netAI is TrainTrackBaseAI || info.m_netAI is MetroTrackAI)) {
// Only outputting these in debug as there are loads of them
#if DEBUG
Log._DebugIf(DebugSwitch.SpeedLimits.Get(), () => $"- Skipped: NetInfo @ {i} ({infoName}) - m_netAI is not applicable: {info.m_netAI}.");
#endif
continue;
}

// If it requires DLC, check the DLC is active
if (!(info.m_dlcRequired == 0 || (uint)(info.m_dlcRequired & dlcMask) != 0u)) {
Log.Info($"- Skipped: NetInfo @ {i} ({infoName}) - required DLC not active.");
continue;
}

// #510: Filter out decorative networks (`None`) and bike paths (`Bicycle`)
if (info.m_vehicleTypes == VehicleInfo.VehicleType.None || info.m_vehicleTypes == VehicleInfo.VehicleType.Bicycle) {
Log.Info($"- Skipped: NetInfo @ {i} ({infoName}) - no vehicle support (decorative network or bike path?)");
continue;
}

if (!vanillaLaneSpeedLimitsByNetInfoName.ContainsKey(infoName)) {
if (info.m_lanes == null) {
Log.Warning(
$"SpeedLimitManager.OnBeforeLoadData: NetInfo lanes @ {i} is null!");
$"SpeedLimitManager.OnBeforeLoadData: NetInfo @ {i} ({infoName}) lanes is null!");
continue;
}

Log._Trace($"Loaded road NetInfo: {infoName}");
Log._Trace($"- Loaded road NetInfo: {infoName}");
NetInfoByName[infoName] = info;
mainNetInfos.Add(info);

Expand All @@ -696,8 +734,10 @@ public override void OnBeforeLoadData() {
}
}

Log.Info("SpeedLimitManager.OnBeforeLoadData: Scan complete");

mainNetInfos.Sort(
delegate(NetInfo a, NetInfo b) {
(NetInfo a, NetInfo b) => {
bool aRoad = a.m_netAI is RoadBaseAI;
bool bRoad = b.m_netAI is RoadBaseAI;

Expand Down
8 changes: 5 additions & 3 deletions TLM/TLM/State/ConfigData/DebugSettings.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace TrafficManager.State.ConfigData {
namespace TrafficManager.State.ConfigData {
using System;
using API.Traffic.Enums;
using JetBrains.Annotations;
Expand Down Expand Up @@ -40,7 +40,8 @@ public class DebugSettings {
false, // 22: parking ai debug log (vehicles)
false, // 23: debug lane connections
false, // 24: debug resource loading
false // 25: debug turn-on-red
false, // 25: debug turn-on-red
false // 26: debug speed limits (also lists NetInfos skipped due to m_netAI in SpeedLimitsManager.cs)
};

private int nodeId_ = 0;
Expand Down Expand Up @@ -126,7 +127,8 @@ public enum DebugSwitch {
VehicleParkingAILog = 22,
LaneConnections = 23,
ResourceLoading = 24,
TurnOnRed = 25
TurnOnRed = 25,
SpeedLimits = 26
}

static class DebugSwitchExtensions {
Expand Down