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