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

don't save empty records in asset editor #1681

Merged
merged 11 commits into from
Nov 19, 2022
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
2 changes: 1 addition & 1 deletion TLM/TLM/Lifecycle/AssetDataExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public static void OnAssetSavedImpl(string name, object asset, out Dictionary<st
Log.Info("AssetDataExtension.OnAssetSavedImpl(): prefab is " + prefab);
var assetData = AssetData.GetAssetData(prefab);
if (assetData == null) {
Log._Debug("AssetDataExtension.OnAssetSavedImpl(): No segments to record.");
Log._Debug("AssetDataExtension.OnAssetSavedImpl(): Nothing to record.");
} else {
Log._Debug("AssetDataExtension.OnAssetSavedImpl(): assetData=" + assetData);
userData = new Dictionary<string, byte[]>();
Expand Down
8 changes: 8 additions & 0 deletions TLM/TLM/Manager/Impl/TrafficLightManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,14 @@ public void ResetTrafficLightAndPrioritySignsFromNode(ushort nodeId) {
: null;
}

public void SetHasTrafficLight(ushort nodeId, bool? value) {
if (value == null) {
ResetTrafficLightAndPrioritySignsFromNode(nodeId);
} else {
SetTrafficLight(nodeId, value.Value, ref nodeId.ToNode());
}
}

bool ITrafficLightManager.CanToggleTrafficLight(ushort nodeId) {
ref NetNode netNode = ref nodeId.ToNode();
return netNode.IsValid() &&
Expand Down
8 changes: 6 additions & 2 deletions TLM/TLM/State/Asset/AssetData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,14 @@ public static AssetData GetAssetData(BuildingInfo prefab) {
if (!HasPaths(prefab)) {
return null;
}

var record = RecordAll();
if (record == null || record.IsDefault()) {
return null;
}

return new AssetData {
Version = VersionUtil.ModVersion,
Record = RecordAll(),
Record = record,
PathNetworkIDs = GetPathsNetworkIDs(prefab),
};
}
Expand Down
1 change: 1 addition & 0 deletions TLM/TLM/TLM.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
<Compile Include="UI\WhatsNew\MarkupKeyword.cs" />
<Compile Include="UI\WhatsNew\WhatsNewMarkup.cs" />
<Compile Include="Util\DetailLogger.cs" />
<Compile Include="Util\Extensions\EnumerableExtensions.cs" />
<Compile Include="Util\Extensions\ParkedVehicleExtensions.cs" />
<Compile Include="Util\Extensions\UIHelperExtensions.cs" />
<Compile Include="Util\Extensions\VersionExtension.cs" />
Expand Down
11 changes: 11 additions & 0 deletions TLM/TLM/Util/Extensions/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace TrafficManager.Util.Extensions {
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

internal static class EnumerableExtensions {
internal static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> e) => e ?? Enumerable.Empty<T>();
}
}
14 changes: 13 additions & 1 deletion TLM/TLM/Util/Record/IRecordable.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System.Linq;
using System.Collections.Generic;

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

/// <summary>
/// Detects if record is empty to help releasing empty records from memory.
/// </summary>
/// <returns>true if record stores only default values. false if record stores any useful information.</returns>
bool IsDefault();

byte[] Serialize();
}

public static class RecordExtensions {
public static bool AreDefault<T>(this IEnumerable<T> records)
where T : IRecordable =>
records == null || records.All(record => record == null || record.IsDefault());
}
}
2 changes: 2 additions & 0 deletions TLM/TLM/Util/Record/LaneArrowsRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public void Record() {
arrows_ = Flags.GetLaneArrowFlags(LaneId);
}

public bool IsDefault() => arrows_ == null;

public void Restore() => Transfer(LaneId);

public void Transfer(Dictionary<InstanceID, InstanceID> map) =>
Expand Down
5 changes: 5 additions & 0 deletions TLM/TLM/Util/Record/LaneConnectionRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ private void RestoreImpl(LaneConnectionSubManager man, uint[] connections) {
}
}

public bool IsDefault() =>
connections_.IsNullOrEmpty() &&
roadConnections_.IsNullOrEmpty() &&
trackConnections_.IsNullOrEmpty();

public void Restore() {
if (connections_ != null) {
// legacy
Expand Down
41 changes: 14 additions & 27 deletions TLM/TLM/Util/Record/NodeRecord.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
namespace TrafficManager.Util.Record {
using System;
using System.Collections.Generic;
using System.Linq;
using TrafficManager.Manager.Impl;
using static TrafficManager.Util.Shortcuts;
using TrafficManager.State;
using TrafficManager.Util.Extensions;

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

private bool trafficLight_;
private bool? trafficLight_;
private List<LaneConnectionRecord> lanes_;
private static TrafficLightManager tlMan => TrafficLightManager.Instance;

public void Record() {
trafficLight_ = tlMan.HasTrafficLight(NodeId, ref NodeId.ToNode());
trafficLight_ = tlMan.GetHasTrafficLight(NodeId);
lanes_ = LaneConnectionRecord.GetLanes(NodeId);
foreach (LaneConnectionRecord sourceLane in lanes_) {
sourceLane.Record();
foreach (LaneConnectionRecord sourceLane in lanes_.EmptyIfNull()) {
sourceLane?.Record();
}
}

public bool IsDefault() =>
trafficLight_ == null && lanes_.AreDefault();

public void Restore() {
SetTrafficLight(NodeId, trafficLight_);
foreach (LaneConnectionRecord sourceLane in lanes_) {
sourceLane.Restore();
tlMan.SetHasTrafficLight(NodeId, trafficLight_);
foreach (LaneConnectionRecord sourceLane in lanes_.EmptyIfNull()) {
sourceLane?.Restore();
}
}

public void Transfer(Dictionary<InstanceID, InstanceID> map) {
SetTrafficLight(map[InstanceID].NetNode, trafficLight_);
foreach (LaneConnectionRecord sourceLane in lanes_)
sourceLane.Transfer(map);
}

private static bool SetTrafficLight(ushort nodeId, bool flag) {
// TODO move code to manager.
bool currentValue = tlMan.HasTrafficLight(nodeId, ref nodeId.ToNode());
if (currentValue == flag)
return true;
bool canChangeValue = tlMan.CanToggleTrafficLight(
nodeId,
flag,
ref nodeId.ToNode(),
out _);
if (!canChangeValue) {
return false;
}
return tlMan.SetTrafficLight(nodeId, flag, ref nodeId.ToNode());
tlMan.SetHasTrafficLight(map[InstanceID].NetNode, trafficLight_);
foreach (LaneConnectionRecord sourceLane in lanes_.EmptyIfNull())
sourceLane?.Transfer(map);
}

public byte[] Serialize() => SerializationUtil.Serialize(this);
Expand Down
34 changes: 24 additions & 10 deletions TLM/TLM/Util/Record/SegmentEndRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ namespace TrafficManager.Util.Record {
using TrafficManager.API.Traffic.Enums;
using TrafficManager.Manager.Impl;
using TrafficManager.State;
using TrafficManager.Util.Extensions;

[Serializable]
class SegmentEndRecord : IRecordable {
public class SegmentEndRecord : IRecordable {
public SegmentEndRecord(int segmentEndIndex) {
SegmentEndManager.Instance.
GetSegmentAndNodeFromIndex(segmentEndIndex, out ushort segmentId, out bool startNode);
Expand All @@ -23,7 +24,7 @@ public SegmentEndRecord(ushort segmentId, bool startNode) {

public ushort SegmentId { get; private set; }
public bool StartNode { get; private set; }
InstanceID InstanceID => new InstanceID { NetSegment = SegmentId };
private InstanceID InstanceID => new InstanceID { NetSegment = SegmentId };

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

public bool IsDefault() {
return
uturnAllowed_ == TernaryBool.Undefined &&
nearTurnOnRedAllowed_ == TernaryBool.Undefined &&
farTurnOnRedAllowed_ == TernaryBool.Undefined &&
laneChangingAllowedWhenGoingStraight_ == TernaryBool.Undefined &&
enteringBlockedJunctionAllowed_ == TernaryBool.Undefined &&
pedestrianCrossingAllowed_ == TernaryBool.Undefined &&
prioirtySign_ == PriorityType.None &&
arrowLanes_.AreDefault();
}

public void Record() {
uturnAllowed_ = JRMan.GetUturnAllowed(SegmentId, StartNode);
nearTurnOnRedAllowed_ = JRMan.GetNearTurnOnRedAllowed(SegmentId, StartNode);
Expand All @@ -49,13 +62,13 @@ public void Record() {
prioirtySign_ = priorityMan.GetPrioritySign(SegmentId, StartNode);

arrowLanes_ = LaneArrowsRecord.GetLanes(SegmentId, StartNode);
foreach(IRecordable lane in arrowLanes_)
lane.Record();
foreach(IRecordable lane in arrowLanes_.EmptyIfNull())
lane?.Record();
}

public void Restore() {
foreach (IRecordable lane in arrowLanes_)
lane.Restore();
foreach (IRecordable lane in arrowLanes_.EmptyIfNull())
lane?.Restore();

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

public void Transfer(Dictionary<InstanceID, InstanceID> map) {
ushort segmentId = map[InstanceID].NetSegment;
foreach (IRecordable lane in arrowLanes_)
lane.Transfer(map);
foreach (IRecordable lane in arrowLanes_.EmptyIfNull())
lane?.Transfer(map);

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

var mappedLanes = SpeedLimitLaneRecord.GetLanes(segmentId);
for (int i = 0; i == arrowLanes_.Count; ++i) {
arrowLanes_[i].Transfer(mappedLanes[i].LaneId);
int n = arrowLanes_?.Count ?? 0;
for (int i = 0; i == n; ++i) {
arrowLanes_[i]?.Transfer(mappedLanes[i].LaneId);
}
}

Expand Down
32 changes: 20 additions & 12 deletions TLM/TLM/Util/Record/SegmentRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,40 @@ public void Record() {
parkingForward_ = pMan.IsParkingAllowed(SegmentId, NetInfo.Direction.Forward);
parkingBackward_ = pMan.IsParkingAllowed(SegmentId, NetInfo.Direction.Backward);
speedLanes_ = SpeedLimitLaneRecord.GetLanes(SegmentId);
foreach (var lane in speedLanes_)
lane.Record();
foreach (var lane in speedLanes_.EmptyIfNull())
lane?.Record();
vehicleRestrictionsLanes_ = VehicleRestrictionsLaneRecord.GetLanes(SegmentId);
foreach (var lane in vehicleRestrictionsLanes_)
lane.Record();
foreach (var lane in vehicleRestrictionsLanes_.EmptyIfNull())
lane?.Record();
allLaneIds_ = GetAllLanes(SegmentId);
}

public bool IsDefault() {
return
parkingForward_ == true &&
parkingBackward_ == true &&
speedLanes_.AreDefault() &&
vehicleRestrictionsLanes_.AreDefault();
}

public void Restore() {
// TODO fix SetParkingAllowed
pMan.SetParkingAllowed(SegmentId, NetInfo.Direction.Forward, parkingForward_);
pMan.SetParkingAllowed(SegmentId, NetInfo.Direction.Backward, parkingBackward_);
foreach (var lane in speedLanes_)
lane.Restore();
foreach (var lane in vehicleRestrictionsLanes_)
lane.Restore();
foreach (var lane in speedLanes_.EmptyIfNull())
lane?.Restore();
foreach (var lane in vehicleRestrictionsLanes_.EmptyIfNull())
lane?.Restore();
}

public void Transfer(Dictionary<InstanceID, InstanceID> map){
ushort segmentId = map[InstanceID].NetSegment;
pMan.SetParkingAllowed(segmentId, NetInfo.Direction.Forward, parkingForward_);
pMan.SetParkingAllowed(segmentId, NetInfo.Direction.Backward, parkingBackward_);
foreach (var lane in speedLanes_)
lane.Transfer(map);
foreach (var lane in vehicleRestrictionsLanes_)
lane.Transfer(map);
foreach (var lane in speedLanes_.EmptyIfNull())
lane?.Transfer(map);
foreach (var lane in vehicleRestrictionsLanes_.EmptyIfNull())
lane?.Transfer(map);
}

public byte[] Serialize() => SerializationUtil.Serialize(this);
Expand Down
2 changes: 2 additions & 0 deletions TLM/TLM/Util/Record/SpeedLimitLaneRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public void Record() {
: (float?)null;
}

public bool IsDefault() => speedLimit_ == null;

public void Restore() => Transfer(LaneId);

public void Transfer(Dictionary<InstanceID, InstanceID> map) =>
Expand Down
12 changes: 7 additions & 5 deletions TLM/TLM/Util/Record/TrafficRulesRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ public void AddNodeAndSegmentEnds(ushort nodeId) {
}
}

public bool IsDefault() => Records.AreDefault();

public void Record() {
foreach (ushort nodeId in NodeIDs)
Records.Add(new NodeRecord(nodeId));
Expand All @@ -72,18 +74,18 @@ public void Record() {
foreach (int segmentEndIndex in SegmentEndIndeces)
Records.Add(new SegmentEndRecord(segmentEndIndex));
foreach (IRecordable record in Records)
record.Record();
record?.Record();
}

public void Restore() {
foreach (IRecordable record in Records)
record.Restore();
foreach (IRecordable record in Records.EmptyIfNull())
record?.Restore();
}

public void Transfer(Dictionary<InstanceID,InstanceID> map) {
foreach (IRecordable record in Records) {
foreach (IRecordable record in Records.EmptyIfNull()) {
try {
record.Transfer(map);
record?.Transfer(map);
}
catch(KeyNotFoundException ex) {
// hide message in release build to avoid scaring the user.
Expand Down
2 changes: 2 additions & 0 deletions TLM/TLM/Util/Record/VehicleRestrictionsLaneRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public class VehicleRestrictionsLaneRecord : IRecordable {

InstanceID InstanceID => new InstanceID { NetLane = LaneId };

public bool IsDefault() => allowedVehicleTypes_ == null;

public void Record() {
allowedVehicleTypes_ = VehicleRestrictionsManager.Instance.GetAllowedVehicleTypesRaw(SegmentId, LaneIndex);
}
Expand Down