Skip to content

Commit 8b6fd00

Browse files
authored
don't save empty records in asset editor (#1681)
1 parent f11c37b commit 8b6fd00

14 files changed

+116
-58
lines changed

TLM/TLM/Lifecycle/AssetDataExtension.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public static void OnAssetSavedImpl(string name, object asset, out Dictionary<st
4343
Log.Info("AssetDataExtension.OnAssetSavedImpl(): prefab is " + prefab);
4444
var assetData = AssetData.GetAssetData(prefab);
4545
if (assetData == null) {
46-
Log._Debug("AssetDataExtension.OnAssetSavedImpl(): No segments to record.");
46+
Log._Debug("AssetDataExtension.OnAssetSavedImpl(): Nothing to record.");
4747
} else {
4848
Log._Debug("AssetDataExtension.OnAssetSavedImpl(): assetData=" + assetData);
4949
userData = new Dictionary<string, byte[]>();

TLM/TLM/Manager/Impl/TrafficLightManager.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,14 @@ public void ResetTrafficLightAndPrioritySignsFromNode(ushort nodeId) {
159159
: null;
160160
}
161161

162+
public void SetHasTrafficLight(ushort nodeId, bool? value) {
163+
if (value == null) {
164+
ResetTrafficLightAndPrioritySignsFromNode(nodeId);
165+
} else {
166+
SetTrafficLight(nodeId, value.Value, ref nodeId.ToNode());
167+
}
168+
}
169+
162170
bool ITrafficLightManager.CanToggleTrafficLight(ushort nodeId) {
163171
ref NetNode netNode = ref nodeId.ToNode();
164172
return netNode.IsValid() &&

TLM/TLM/State/Asset/AssetData.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,14 @@ public static AssetData GetAssetData(BuildingInfo prefab) {
3737
if (!HasPaths(prefab)) {
3838
return null;
3939
}
40-
40+
var record = RecordAll();
41+
if (record == null || record.IsDefault()) {
42+
return null;
43+
}
44+
4145
return new AssetData {
4246
Version = VersionUtil.ModVersion,
43-
Record = RecordAll(),
47+
Record = record,
4448
PathNetworkIDs = GetPathsNetworkIDs(prefab),
4549
};
4650
}

TLM/TLM/TLM.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@
200200
<Compile Include="UI\WhatsNew\MarkupKeyword.cs" />
201201
<Compile Include="UI\WhatsNew\WhatsNewMarkup.cs" />
202202
<Compile Include="Util\DetailLogger.cs" />
203+
<Compile Include="Util\Extensions\EnumerableExtensions.cs" />
203204
<Compile Include="Util\Extensions\ParkedVehicleExtensions.cs" />
204205
<Compile Include="Util\Extensions\UIHelperExtensions.cs" />
205206
<Compile Include="Util\Extensions\VersionExtension.cs" />
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace TrafficManager.Util.Extensions {
2+
using System;
3+
using System.Collections;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Text;
7+
8+
internal static class EnumerableExtensions {
9+
internal static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> e) => e ?? Enumerable.Empty<T>();
10+
}
11+
}

TLM/TLM/Util/Record/IRecordable.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System.Linq;
22
using System.Collections.Generic;
33

44
namespace TrafficManager.Util.Record {
@@ -19,6 +19,18 @@ public interface IRecordable {
1919
/// <param name="map">maps old Instance IDs to new Instance IDs</param>
2020
void Transfer(Dictionary<InstanceID, InstanceID> map);
2121

22+
/// <summary>
23+
/// Detects if record is empty to help releasing empty records from memory.
24+
/// </summary>
25+
/// <returns>true if record stores only default values. false if record stores any useful information.</returns>
26+
bool IsDefault();
27+
2228
byte[] Serialize();
2329
}
30+
31+
public static class RecordExtensions {
32+
public static bool AreDefault<T>(this IEnumerable<T> records)
33+
where T : IRecordable =>
34+
records == null || records.All(record => record == null || record.IsDefault());
35+
}
2436
}

TLM/TLM/Util/Record/LaneArrowsRecord.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public void Record() {
1717
arrows_ = Flags.GetLaneArrowFlags(LaneId);
1818
}
1919

20+
public bool IsDefault() => arrows_ == null;
21+
2022
public void Restore() => Transfer(LaneId);
2123

2224
public void Transfer(Dictionary<InstanceID, InstanceID> map) =>

TLM/TLM/Util/Record/LaneConnectionRecord.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ private void RestoreImpl(LaneConnectionSubManager man, uint[] connections) {
4848
}
4949
}
5050

51+
public bool IsDefault() =>
52+
connections_.IsNullOrEmpty() &&
53+
roadConnections_.IsNullOrEmpty() &&
54+
trackConnections_.IsNullOrEmpty();
55+
5156
public void Restore() {
5257
if (connections_ != null) {
5358
// legacy

TLM/TLM/Util/Record/NodeRecord.cs

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
namespace TrafficManager.Util.Record {
22
using System;
33
using System.Collections.Generic;
4+
using System.Linq;
45
using TrafficManager.Manager.Impl;
5-
using static TrafficManager.Util.Shortcuts;
66
using TrafficManager.State;
77
using TrafficManager.Util.Extensions;
88

@@ -13,45 +13,32 @@ public class NodeRecord : IRecordable {
1313
public ushort NodeId { get; private set; }
1414
InstanceID InstanceID => new InstanceID { NetNode = NodeId};
1515

16-
private bool trafficLight_;
16+
private bool? trafficLight_;
1717
private List<LaneConnectionRecord> lanes_;
1818
private static TrafficLightManager tlMan => TrafficLightManager.Instance;
1919

2020
public void Record() {
21-
trafficLight_ = tlMan.HasTrafficLight(NodeId, ref NodeId.ToNode());
21+
trafficLight_ = tlMan.GetHasTrafficLight(NodeId);
2222
lanes_ = LaneConnectionRecord.GetLanes(NodeId);
23-
foreach (LaneConnectionRecord sourceLane in lanes_) {
24-
sourceLane.Record();
23+
foreach (LaneConnectionRecord sourceLane in lanes_.EmptyIfNull()) {
24+
sourceLane?.Record();
2525
}
2626
}
2727

28+
public bool IsDefault() =>
29+
trafficLight_ == null && lanes_.AreDefault();
30+
2831
public void Restore() {
29-
SetTrafficLight(NodeId, trafficLight_);
30-
foreach (LaneConnectionRecord sourceLane in lanes_) {
31-
sourceLane.Restore();
32+
tlMan.SetHasTrafficLight(NodeId, trafficLight_);
33+
foreach (LaneConnectionRecord sourceLane in lanes_.EmptyIfNull()) {
34+
sourceLane?.Restore();
3235
}
3336
}
3437

3538
public void Transfer(Dictionary<InstanceID, InstanceID> map) {
36-
SetTrafficLight(map[InstanceID].NetNode, trafficLight_);
37-
foreach (LaneConnectionRecord sourceLane in lanes_)
38-
sourceLane.Transfer(map);
39-
}
40-
41-
private static bool SetTrafficLight(ushort nodeId, bool flag) {
42-
// TODO move code to manager.
43-
bool currentValue = tlMan.HasTrafficLight(nodeId, ref nodeId.ToNode());
44-
if (currentValue == flag)
45-
return true;
46-
bool canChangeValue = tlMan.CanToggleTrafficLight(
47-
nodeId,
48-
flag,
49-
ref nodeId.ToNode(),
50-
out _);
51-
if (!canChangeValue) {
52-
return false;
53-
}
54-
return tlMan.SetTrafficLight(nodeId, flag, ref nodeId.ToNode());
39+
tlMan.SetHasTrafficLight(map[InstanceID].NetNode, trafficLight_);
40+
foreach (LaneConnectionRecord sourceLane in lanes_.EmptyIfNull())
41+
sourceLane?.Transfer(map);
5542
}
5643

5744
public byte[] Serialize() => SerializationUtil.Serialize(this);

TLM/TLM/Util/Record/SegmentEndRecord.cs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ namespace TrafficManager.Util.Record {
66
using TrafficManager.API.Traffic.Enums;
77
using TrafficManager.Manager.Impl;
88
using TrafficManager.State;
9+
using TrafficManager.Util.Extensions;
910

1011
[Serializable]
11-
class SegmentEndRecord : IRecordable {
12+
public class SegmentEndRecord : IRecordable {
1213
public SegmentEndRecord(int segmentEndIndex) {
1314
SegmentEndManager.Instance.
1415
GetSegmentAndNodeFromIndex(segmentEndIndex, out ushort segmentId, out bool startNode);
@@ -23,7 +24,7 @@ public SegmentEndRecord(ushort segmentId, bool startNode) {
2324

2425
public ushort SegmentId { get; private set; }
2526
public bool StartNode { get; private set; }
26-
InstanceID InstanceID => new InstanceID { NetSegment = SegmentId };
27+
private InstanceID InstanceID => new InstanceID { NetSegment = SegmentId };
2728

2829
private TernaryBool uturnAllowed_;
2930
private TernaryBool nearTurnOnRedAllowed_;
@@ -38,6 +39,18 @@ public SegmentEndRecord(ushort segmentId, bool startNode) {
3839
private static TrafficPriorityManager priorityMan => TrafficPriorityManager.Instance;
3940
private static JunctionRestrictionsManager JRMan => JunctionRestrictionsManager.Instance;
4041

42+
public bool IsDefault() {
43+
return
44+
uturnAllowed_ == TernaryBool.Undefined &&
45+
nearTurnOnRedAllowed_ == TernaryBool.Undefined &&
46+
farTurnOnRedAllowed_ == TernaryBool.Undefined &&
47+
laneChangingAllowedWhenGoingStraight_ == TernaryBool.Undefined &&
48+
enteringBlockedJunctionAllowed_ == TernaryBool.Undefined &&
49+
pedestrianCrossingAllowed_ == TernaryBool.Undefined &&
50+
prioirtySign_ == PriorityType.None &&
51+
arrowLanes_.AreDefault();
52+
}
53+
4154
public void Record() {
4255
uturnAllowed_ = JRMan.GetUturnAllowed(SegmentId, StartNode);
4356
nearTurnOnRedAllowed_ = JRMan.GetNearTurnOnRedAllowed(SegmentId, StartNode);
@@ -49,13 +62,13 @@ public void Record() {
4962
prioirtySign_ = priorityMan.GetPrioritySign(SegmentId, StartNode);
5063

5164
arrowLanes_ = LaneArrowsRecord.GetLanes(SegmentId, StartNode);
52-
foreach(IRecordable lane in arrowLanes_)
53-
lane.Record();
65+
foreach(IRecordable lane in arrowLanes_.EmptyIfNull())
66+
lane?.Record();
5467
}
5568

5669
public void Restore() {
57-
foreach (IRecordable lane in arrowLanes_)
58-
lane.Restore();
70+
foreach (IRecordable lane in arrowLanes_.EmptyIfNull())
71+
lane?.Restore();
5972

6073
if (priorityMan.MaySegmentHavePrioritySign(SegmentId, StartNode) &&
6174
prioirtySign_ != priorityMan.GetPrioritySign(SegmentId, StartNode)) {
@@ -74,8 +87,8 @@ public void Restore() {
7487

7588
public void Transfer(Dictionary<InstanceID, InstanceID> map) {
7689
ushort segmentId = map[InstanceID].NetSegment;
77-
foreach (IRecordable lane in arrowLanes_)
78-
lane.Transfer(map);
90+
foreach (IRecordable lane in arrowLanes_.EmptyIfNull())
91+
lane?.Transfer(map);
7992

8093
if (priorityMan.MaySegmentHavePrioritySign(segmentId, StartNode) &&
8194
prioirtySign_ != priorityMan.GetPrioritySign(segmentId, StartNode)) {
@@ -95,8 +108,9 @@ public void Transfer(uint mappedId) {
95108
ushort segmentId = (ushort)mappedId;
96109

97110
var mappedLanes = SpeedLimitLaneRecord.GetLanes(segmentId);
98-
for (int i = 0; i == arrowLanes_.Count; ++i) {
99-
arrowLanes_[i].Transfer(mappedLanes[i].LaneId);
111+
int n = arrowLanes_?.Count ?? 0;
112+
for (int i = 0; i == n; ++i) {
113+
arrowLanes_[i]?.Transfer(mappedLanes[i].LaneId);
100114
}
101115
}
102116

0 commit comments

Comments
 (0)