1 package org.opentrafficsim.road.gtu.lane;
2
3 import org.djutils.exceptions.Try;
4 import org.opentrafficsim.core.gtu.Gtu;
5 import org.opentrafficsim.core.gtu.perception.Perception;
6
7 /**
8 * Utility to make debugging on a specific GTU more convenient. There is a method {@code on()} for a GTU and for perception.
9 * Should neither be available within the context of a method that needs to be debugged, {@code onSub()} can be used in
10 * combination with {@code onSuper()} at a higher-level method with a GTU or perception. <i>This class requires the user to set
11 * a break point in the method {@code trigger()}.</i>
12 * <p>
13 * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
14 * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
15 * </p>
16 * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
17 * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
18 * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
19 */
20 public final class Break
21 {
22
23 /** Condition to allow or prevent breaking in lower-level functionality. */
24 private static boolean superCondition = true;
25
26 /**
27 * Constructor.
28 */
29 private Break()
30 {
31 //
32 }
33
34 /**
35 * Sets a break condition to true which is triggered by {@code onSub()} at a lower level where context is insufficient to
36 * determine the break condition.
37 * @param perception Perception<?>; perception to obtain gtu from
38 * @param id String; GTU id to break on
39 * @param time double; time to break at (or after)
40 * @param additionalCondition boolean; additional condition
41 */
42 public static void onSuper(final Perception<?> perception, final String id, final double time,
43 final boolean additionalCondition)
44 {
45 Try.execute(() -> onSuper(perception.getGtu(), id, time, additionalCondition),
46 "Trying to break on gtu, but gtu could not be obtained from perception.");
47 }
48
49 /**
50 * Sets a break condition to true which is triggered by {@code onSub()} at a lower level where context is insufficient to
51 * determine the break condition.
52 * @param gtu Gtu; GTU
53 * @param id String; GTU id to break on
54 * @param time double; time to break at (or after)
55 * @param additionalCondition boolean; additional condition
56 */
57 public static void onSuper(final Gtu gtu, final String id, final double time, final boolean additionalCondition)
58 {
59 superCondition = gtu.getId().equals(id) && gtu.getSimulator().getSimulatorTime().si >= time && additionalCondition;
60 }
61
62 /**
63 * This method can be used if the context of a lower-level function does not contain the information on which to break. This
64 * method will only trigger a break if at a higher-level function where the context was sufficient, the break condition was
65 * set to true using {@code onSuper()}.
66 */
67 public static void onSub()
68 {
69 if (superCondition)
70 {
71 trigger();
72 }
73 }
74
75 /**
76 * This method can be used if the context of a lower-level function does not contain the information on which to break. This
77 * method will only trigger a break if at a higher-level function where the context was sufficient, the break condition was
78 * set to true using {@code onSuper()}.
79 * @param additionalCondition boolean; additional condition
80 */
81 public static void onSub(final boolean additionalCondition)
82 {
83 if (superCondition && additionalCondition)
84 {
85 trigger();
86 }
87 }
88
89 /**
90 * @param perception Perception<?>; perception to obtain gtu from
91 * @param id String; GTU id to break on
92 * @param time String; time to break at (or after), in format ss, mm:ss or hh:mm:ss
93 * @param additionalCondition boolean; additional condition
94 */
95 public static void on(final Perception<?> perception, final String id, final String time, final boolean additionalCondition)
96 {
97 on(perception, id, timeFromString(time), additionalCondition);
98 }
99
100 /**
101 * Returns a double representation of a String time.
102 * @param time String; string format, ss, mm:ss or hh:mm:ss
103 * @return double representation of a String time
104 */
105 private static double timeFromString(final String time)
106 {
107 int index = time.indexOf(":");
108 if (index < 0)
109 {
110 return Double.valueOf(time) - 1e-6;
111 }
112 int index2 = time.indexOf(":", index + 1);
113 double h;
114 double m;
115 double s;
116 if (index2 < 0)
117 {
118 h = 0;
119 m = Double.valueOf(time.substring(0, index));
120 s = Double.valueOf(time.substring(index + 1));
121 }
122 else
123 {
124 h = Double.valueOf(time.substring(0, index));
125 m = Double.valueOf(time.substring(index + 1, index2));
126 s = Double.valueOf(time.substring(index2 + 1));
127 }
128 return h * 3600.0 + m * 60.0 + s - 1e-6;
129 }
130
131 /**
132 * @param perception Perception<?>; perception to obtain gtu from
133 * @param id String; GTU id to break on
134 * @param time double; time to break at (or after)
135 * @param additionalCondition boolean; additional condition
136 */
137 public static void on(final Perception<?> perception, final String id, final double time, final boolean additionalCondition)
138 {
139 Try.execute(() -> on(perception.getGtu(), id, time, additionalCondition),
140 "Trying to break on gtu, but gtu could not be obtained from perception.");
141 }
142
143 /**
144 * @param gtu Gtu; GTU
145 * @param id String; GTU id to break on
146 * @param time String; time to break at (or after), in format ss, mm:ss or hh:mm:ss
147 * @param additionalCondition boolean; additional condition
148 */
149 public static void on(final Gtu gtu, final String id, final String time, final boolean additionalCondition)
150 {
151 on(gtu, id, timeFromString(time), additionalCondition);
152 }
153
154 /**
155 * @param gtu Gtu; GTU
156 * @param id String; GTU id to break on
157 * @param time double; time to break at (or after)
158 * @param additionalCondition boolean; additional condition
159 */
160 public static void on(final Gtu gtu, final String id, final double time, final boolean additionalCondition)
161 {
162 if (gtu.getId().equals(id) && gtu.getSimulator().getSimulatorTime().si >= time && additionalCondition)
163 {
164 trigger();
165 }
166 }
167
168 /**
169 * Method that is invoked on a break condition. A break-point here allows the user to debug specific situations.
170 */
171 private static void trigger()
172 {
173 System.err.println("Break condition for debugging is true."); // SET BREAK POINT ON THIS LINE
174 }
175
176 }