Skip to content
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
5 changes: 5 additions & 0 deletions TLM/TLM/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
namespace TrafficManager {
using TrafficManager.API.Manager;
using TrafficManager.API.Notifier;
using TrafficManager.API.UI;
using TrafficManager.U;
using TrafficManager.UI.Textures;

public static class Constants {
/// <summary>
Expand Down Expand Up @@ -35,6 +37,9 @@ public static float ByteToFloat(byte b) {

public static IManagerFactory ManagerFactory => Manager.Impl.ManagerFactory.Instance;

public static IUIFactory UIFactory => UI.UIFactory.Instance;

public static INotifier Notifier => TrafficManager.Notifier.Instance;

}
}
10 changes: 1 addition & 9 deletions TLM/TLM/Manager/Impl/JunctionRestrictionsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace TrafficManager.Manager.Impl {
using TrafficManager.Util;
using TrafficManager.Util.Extensions;
using TrafficManager.Lifecycle;
using TrafficManager.API.Traffic.Enums;

public class JunctionRestrictionsManager
: AbstractGeometryObservingManager,
Expand Down Expand Up @@ -1318,15 +1319,6 @@ public bool LoadData(List<Configuration.SegmentNodeConf> data) {
return ret;
}

private enum JunctionRestrictionFlags {
AllowUTurn = 1 << 0,
AllowNearTurnOnRed = 1 << 1,
AllowFarTurnOnRed = 1 << 2,
AllowForwardLaneChange = 1 << 3,
AllowEnterWhenBlocked = 1 << 4,
AllowPedestrianCrossing = 1 << 5,
}

private struct SegmentJunctionRestrictions {
public JunctionRestrictions startNodeRestrictions;
public JunctionRestrictions endNodeRestrictions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class LaneConnectionManager
| VehicleInfo.VehicleType.Trolleybus;

public LaneConnectionSubManager Sub = // TODO #354 divide into Road/Track
new LaneConnectionSubManager(LaneEndTransitionGroup.All);
new LaneConnectionSubManager(LaneEndTransitionGroup.Vehicle);

public NetInfo.LaneType LaneTypes => LANE_TYPES;

Expand Down
14 changes: 14 additions & 0 deletions TLM/TLM/Manager/Impl/TrafficLightManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ public void RemoveAllExistingTrafficLights() {
}
}

public bool ToggleTrafficLight(ushort nodeId) => ToggleTrafficLight(nodeId, ref nodeId.ToNode());

public bool ToggleTrafficLight(ushort nodeId, ref NetNode node) {
return SetTrafficLight(nodeId, !HasTrafficLight(nodeId, ref node), ref node);
}
Expand All @@ -127,6 +129,16 @@ public bool ToggleTrafficLight(ushort nodeId, ref NetNode node, out ToggleTraffi
return SetTrafficLight(nodeId, !HasTrafficLight(nodeId, ref node), ref node, out reason);
}

bool ITrafficLightManager.CanToggleTrafficLight(ushort nodeId) {
ref NetNode netNode = ref nodeId.ToNode();
return netNode.IsValid() &&
CanToggleTrafficLight(
nodeId,
HasTrafficLight(nodeId, ref netNode),
ref netNode,
out _);
}

public bool CanToggleTrafficLight(ushort nodeId,
bool flag, // override?
ref NetNode node,
Expand Down Expand Up @@ -242,6 +254,8 @@ public bool CanEnableTrafficLight(ushort nodeId,
return ret;
}

public bool HasTrafficLight(ushort nodeId) => HasTrafficLight(nodeId, ref nodeId.ToNode());

public bool HasTrafficLight(ushort nodeId, ref NetNode node) {
return node.IsValid()
&& node.m_flags.IsFlagSet(NetNode.Flags.TrafficLights);
Expand Down
1 change: 1 addition & 0 deletions TLM/TLM/TLM.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@
<Compile Include="UI\SubTools\RoutingDetector\Connection.cs" />
<Compile Include="UI\SubTools\RoutingDetector\LaneEnd.cs" />
<Compile Include="UI\SubTools\RoutingDetector\RoutingDetectorTool.cs" />
<Compile Include="UI\UIFactory.cs" />
<Compile Include="UI\WhatsNew\MarkupKeyword.cs" />
<Compile Include="UI\WhatsNew\WhatsNewMarkup.cs" />
<Compile Include="Util\Extensions\CitizenUnitExtensions.cs" />
Expand Down
39 changes: 37 additions & 2 deletions TLM/TLM/UI/Textures/RoadSignTheme.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
namespace TrafficManager.UI.Textures {
namespace TrafficManager.UI.Textures {
using System;
using System.Collections.Generic;
using CSUtil.Commons;
using JetBrains.Annotations;
using TrafficManager.API.Traffic.Data;
using TrafficManager.API.Traffic.Enums;
using TrafficManager.API.UI;
using TrafficManager.Manager.Impl;
using TrafficManager.State;
using TrafficManager.UI.SubTools;
using TrafficManager.Util;
Expand All @@ -15,7 +17,7 @@
/// Defines one theme for road signs. All themes are accessible via, and stored in
/// <see cref="RoadSignThemeManager"/>.
/// </summary>
public class RoadSignTheme {
public class RoadSignTheme : ITheme {
public enum OtherRestriction {
Crossing,
EnterBlockedJunction,
Expand Down Expand Up @@ -148,6 +150,39 @@ public Texture2D GetOtherRestriction(OtherRestriction type, bool allow) {
: this.ParentTheme.GetOtherRestriction(type, allow: false);
}

public Texture2D JunctionRestriction(JunctionRestrictionFlags rule, bool allowed) {
bool rht = Shortcuts.RHT;
switch (rule) {
case JunctionRestrictionFlags.AllowPedestrianCrossing:
return GetOtherRestriction(OtherRestriction.Crossing, allowed);
case JunctionRestrictionFlags.AllowUTurn:
return GetOtherRestriction(OtherRestriction.UTurn, allowed);
case JunctionRestrictionFlags.AllowEnterWhenBlocked:
return GetOtherRestriction(OtherRestriction.EnterBlockedJunction, allowed);
case JunctionRestrictionFlags.AllowForwardLaneChange:
return GetOtherRestriction(OtherRestriction.LaneChange, allowed);
case JunctionRestrictionFlags.AllowFarTurnOnRed when rht:
case JunctionRestrictionFlags.AllowNearTurnOnRed when !rht:
return GetOtherRestriction(OtherRestriction.LeftOnRed, allowed);
case JunctionRestrictionFlags.AllowNearTurnOnRed when rht:
case JunctionRestrictionFlags.AllowFarTurnOnRed when !rht:
return GetOtherRestriction(OtherRestriction.RightOnRed, allowed);
default:
Log.Error($"could not get texture for {rule}.");
return null;
}
}

public Texture2D TrafficLightIcon(ushort nodeId) {
if (!TrafficLightManager.Instance.HasTrafficLight(nodeId)) {
return TrafficLightTextures.Instance.TrafficLightDisabled;
} else if (TrafficLightSimulationManager.Instance.HasSimulation(nodeId)) {
return TrafficLightTextures.Instance.TrafficLightEnabledTimed;
} else {
return TrafficLightTextures.Instance.TrafficLightEnabled;
}
}

public RoadSignTheme Load(bool whiteTexture = false) {
if (this.AttemptedToLoad) {
return this;
Expand Down
10 changes: 10 additions & 0 deletions TLM/TLM/UI/UIFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace TrafficManager.UI {
using TrafficManager.API.UI;
using TrafficManager.UI.Textures;

public class UIFactory : IUIFactory {
public static IUIFactory Instance = new UIFactory();

public ITheme ActiveTheme => RoadSignThemeManager.ActiveTheme;
}
}
3 changes: 3 additions & 0 deletions TLM/TMPE.API/Implementations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ namespace TrafficManager.API {
using TrafficManager.API.Manager;
using TrafficManager.API.Notifier;
using System.Linq;
using TrafficManager.API.UI;

public static class Implementations {
private static Type constantsType_;
private static IManagerFactory managerFactory_;
private static INotifier notifier_;
private static IUIFactory uiFactory_;

public static IManagerFactory ManagerFactory => managerFactory_ ??= GetImplementation<IManagerFactory>();
public static INotifier Notifier => notifier_ ??= GetImplementation<INotifier>();
public static IUIFactory UIFactory => uiFactory_ ??= GetImplementation<IUIFactory>();

private static T GetImplementation<T>()
where T : class {
Expand Down
18 changes: 18 additions & 0 deletions TLM/TMPE.API/Manager/ITrafficLightManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,23 @@ namespace TrafficManager.API.Manager {
using TrafficManager.API.Traffic.Enums;

public interface ITrafficLightManager {
/// <summary>
/// returns if the node as any kind of traffic light (vanilla, manual, timed).
/// </summary>
public bool HasTrafficLight(ushort nodeId);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public bool HasTrafficLight(ushort nodeId);
bool HasTrafficLight(ushort nodeId);

implicitly public so redundant

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@krzychu124 no that does not work
image
Interface Implementation has to be public.

unless if I do like this:
image

But that is not necessary in this case.

Copy link
Collaborator Author

@kianzarrin kianzarrin May 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might not be a bad idea to implicitly define all API implementations that we do not want to use internally. If we want to go that route we need to have a discussion about it and apply the rule consistently everywhere.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you get an error probably because you are explicitly implementing the interface and implementation you shown is private then making it explicit you force us to cast to the interface to use that method (is there another one with the same signature?). Explicit and implicit implementation are completely different things with some implications.
Basically when you create explicit implementation you won't be able to use it like this
TraffLightManager.Instance.CanToggleTrafficLight() (assuming that Instance returns TrafficLightManager, not the interface)
but forced to do this instead:
((ITrafficLightManager)TraffLightManager.Instance).CanToggleTrafficLight()

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you said first does not work:

Suggested change
public bool HasTrafficLight(ushort nodeId);
bool HasTrafficLight(ushort nodeId);

but this will work:

Suggested change
public bool HasTrafficLight(ushort nodeId);
bool ITrafficLightManager.HasTrafficLight(ushort nodeId);

I understand how implicit/explicit works.


/// <summary>
/// Manual/timed traffic light cannot be toggled using <see cref="ITrafficLightManager"/>.
/// Use <see cref="ITrafficLightSimulationManager"/> to do that.
/// Also certain node types cannot have traffic light.
/// </summary>
bool CanToggleTrafficLight(ushort nodeId);

/// <summary>
/// if node has no traffic light, vanilla traffic light is set (if possible).
/// if node has vanilla traffic light, it is removed (if possible).
/// this method will fail if node has Manual/timed traffic light.
/// </summary>
bool ToggleTrafficLight(ushort nodeId);
}
}
3 changes: 3 additions & 0 deletions TLM/TMPE.API/Manager/ITrafficLightSimulationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@ namespace TrafficManager.API.Manager {
using System.Collections.Generic;

public interface ITrafficLightSimulationManager {
bool HasTimedSimulation(ushort nodeId);

bool HasActiveTimedSimulation(ushort nodeId);
}
}
3 changes: 3 additions & 0 deletions TLM/TMPE.API/TMPE.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
<Compile Include="Traffic\Enums\ExtVehicleType.cs" />
<Compile Include="Traffic\Enums\FlowWaitCalcMode.cs" />
<Compile Include="Traffic\Enums\GeometryCalculationMode.cs" />
<Compile Include="Traffic\Enums\JunctionRestrictionFlags.cs" />
<Compile Include="Traffic\Enums\LocaleKeyAttribute.cs" />
<Compile Include="Traffic\Enums\LaneArrows.cs" />
<Compile Include="Traffic\Enums\LaneEndTransitionGroup.cs" />
Expand All @@ -166,6 +167,8 @@
<Compile Include="Traffic\Enums\VehicleRestrictionsMode.cs" />
<Compile Include="Traffic\ISegmentEnd.cs" />
<Compile Include="Traffic\ISegmentEndId.cs" />
<Compile Include="UI\IUIFactory.cs" />
<Compile Include="UI\ITheme.cs" />
<Compile Include="Util\IObservable.cs" />
<Compile Include="Util\IObserver.cs" />
</ItemGroup>
Expand Down
10 changes: 10 additions & 0 deletions TLM/TMPE.API/Traffic/Enums/JunctionRestrictionFlags.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace TrafficManager.API.Traffic.Enums {
public enum JunctionRestrictionFlags {
AllowUTurn = 1 << 0,
AllowNearTurnOnRed = 1 << 1,
AllowFarTurnOnRed = 1 << 2,
AllowForwardLaneChange = 1 << 3,
AllowEnterWhenBlocked = 1 << 4,
AllowPedestrianCrossing = 1 << 5,
}
}
4 changes: 3 additions & 1 deletion TLM/TMPE.API/Traffic/Enums/LaneEndTransitionGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ public enum LaneEndTransitionGroup {
None = 0,
Road = 1,
Track = 2,
All = Road | Track,
Vehicle = Road | Track,
Bicycle = 4,
Pedestrian = 8,
}
}
19 changes: 19 additions & 0 deletions TLM/TMPE.API/UI/ITheme.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace TrafficManager.API.UI {
using TrafficManager.API.Traffic.Enums;
using UnityEngine;

/// <summary>
/// gets the texture for overlay sprite for each traffic rule according to the current theme.
/// </summary>
public interface ITheme {
Texture2D JunctionRestriction(JunctionRestrictionFlags rule, bool allowed);

Texture2D Parking(bool allowed);

Texture2D Priority(PriorityType p);

Texture2D VehicleRestriction(ExtVehicleType type, bool allow);

Texture2D TrafficLightIcon(ushort nodeId);
}
}
9 changes: 9 additions & 0 deletions TLM/TMPE.API/UI/IUIFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace TrafficManager.API.UI {

/// <summary>
/// gets the texture for overlay sprite for each traffic rule according to the current theme.
/// </summary>
public interface IUIFactory {
ITheme ActiveTheme { get; }
}
}