source: src/main/java/genius/core/session/Session.java

Last change on this file was 127, checked in by Wouter Pasman, 6 years ago

#41 ROLL BACK of rev.126 . So this version is equal to rev. 125

File size: 7.4 KB
Line 
1package genius.core.session;
2
3import static java.lang.Math.pow;
4
5import java.util.ArrayList;
6import java.util.Collections;
7import java.util.List;
8
9import genius.core.Deadline;
10import genius.core.actions.Action;
11import genius.core.parties.SessionsInfo;
12import genius.core.protocol.MultilateralProtocol;
13import genius.core.timeline.ContinuousTimeline;
14import genius.core.timeline.DiscreteTimeline;
15import genius.core.timeline.Timeline;
16
17/**
18 * Stores runtime info around a session. Mainly the rounds info. A
19 * {@link Session} consists of {@link Round}s with in turn consists of
20 * {@link Turn}. From this session object some information about the current
21 * negotiation can be extracted. Important is the
22 * {@link Session#startNewRound(Round)} method which is used to add a new round
23 * to the session. At this moment (05-08-2014) adding new rounds to the session
24 * is the responsibility of the {@link SessionManager}.
25 *
26 * @author David Festen
27 */
28public class Session {
29 /**
30 * Holds the round objects of which this instance consists
31 */
32 private ArrayList<Round> rounds;
33
34 /**
35 * Holds the deadline constraints
36 */
37 private Deadline deadlines;
38
39 /**
40 * Holds a timestamp of the time started (used for runtime calculations)
41 * startTime should be updated using {@code System.nanoTime()}
42 */
43 private long startTime;
44
45 /**
46 * Holds a timestamp of the time started (used for runtime calculations)
47 * stopTime should be updated using {@code System.nanoTime()}
48 */
49 private long stopTime;
50
51 /**
52 * Holds a value to indicate whether the timer is running
53 */
54 private boolean timerRunning;
55
56 private Timeline timeline;
57
58 private SessionsInfo sessionsInfo;
59
60 /**
61 * Create a new instance of the session object. This should normally only
62 * happen once every session. See also the class documentation of
63 * {@link Session}. This also creates a timeline that starts running the
64 * moment Session is created.
65 *
66 * @param deadlines
67 * Map of deadline constraints
68 * @param info
69 * the global {@link SessionsInfo}
70 */
71 public Session(Deadline deadlines, SessionsInfo info) {
72 this.rounds = new ArrayList<Round>();
73 this.deadlines = deadlines;
74 this.sessionsInfo = info;
75 switch (deadlines.getType()) {
76 case ROUND:
77 this.timeline = new DiscreteTimeline(deadlines.getValue());
78 break;
79 case TIME:
80 this.timeline = new ContinuousTimeline(deadlines.getValue());
81 break;
82 }
83 }
84
85 /**
86 * Gets the deadline constraints
87 *
88 * @return a map of deadline types and values
89 */
90 public Deadline getDeadlines() {
91 return deadlines;
92 }
93
94 /**
95 * Updates the timestamp of this {@link Session}. Use just before starting
96 * the negotiation for most accurate timing. Timing is used in for example
97 * time deadline constraints. But might also be used in log messages as well
98 * as statistics.
99 */
100 public void startTimer() {
101 startTime = System.nanoTime();
102 timerRunning = true;
103 if (timeline instanceof ContinuousTimeline) {
104 ((ContinuousTimeline) timeline).reset();
105 }
106 }
107
108 /**
109 * Updates the timestamp of this {@link Session}. Use just after finish the
110 * negotiation for most accurate timing. Timing is used in for example time
111 * deadline constraints. But might also be used in log messages as well as
112 * statistics. If you need to manually set it, consider using the
113 * {@link #setRuntimeInNanoSeconds(long)} function.
114 */
115 public void stopTimer() {
116 stopTime = System.nanoTime();
117 timerRunning = false;
118 }
119
120 /**
121 * Gets the rounds currently in this session. When
122 * {@link #startNewRound(Round)} is called a new round will be added. Each
123 * round already includes all its {@link Turn}s, but some turns might not
124 * yet been done.
125 *
126 * @return list of rounds. Can be empty.
127 */
128 public List<Round> getRounds() {
129 return Collections.unmodifiableList(rounds);
130 }
131
132 /**
133 * Get the most recent round.
134 *
135 * @return The last round of the {@link #getRounds()} method, or null if no
136 * round has been done yet.
137 */
138 public Round getMostRecentRound() {
139 if (rounds.isEmpty()) {
140 return null;
141 }
142 return rounds.get(rounds.size() - 1);
143 }
144
145 /**
146 * Add a round to this session. Make sure it contains all the turns
147 * necessary to execute the rounds. Normally the new round will be created
148 * by using
149 * {@link MultilateralProtocol#getRoundStructure(java.util.List, Session)}
150 *
151 *
152 * @param round
153 * The round to add to this session.
154 */
155 public void startNewRound(Round round) {
156 rounds.add(round);
157 }
158
159 /**
160 * Get the current round number. one-based (meaning first round is round 1)
161 *
162 * @return Integer representing the round number
163 */
164 public int getRoundNumber() {
165 return rounds.size();
166 }
167
168 /**
169 * Get the current turn number within the current round.
170 *
171 * @return current turn within the round. 0 if no actions have been done yet
172 * or if we are not even in a round.
173 */
174 public int getTurnNumber() {
175 if (rounds.isEmpty()) {
176 return 0;
177 }
178 return getMostRecentRound().getActions().size();
179 }
180
181 /**
182 * Check whether this is the first round (round 1).
183 *
184 * @return true if {@link #getRoundNumber()} equals 1
185 */
186 public boolean isFirstRound() {
187 return getRoundNumber() == 1;
188 }
189
190 /**
191 * Removes the last (supposedly incomplete) round, if there is a last round
192 */
193 public void removeLastRound() {
194 if (!rounds.isEmpty()) {
195 rounds.remove(rounds.size() - 1);
196 }
197 }
198
199 /**
200 * Get the most recently executed action.
201 *
202 * @return The most recent action of the most recent round. Null if no
203 * action has been done yet.
204 */
205 public Action getMostRecentAction() {
206 Round lastround = getMostRecentRound();
207 if (lastround == null)
208 return null;
209 return getMostRecentRound().getMostRecentAction();
210 }
211
212 /**
213 * Check whether one of the deadlines is reached.
214 *
215 * @return true iff the deadline is reached. True if the runtime/round
216 * number is bigger than the actual deadline.
217 */
218 public boolean isDeadlineReached() {
219 boolean deadlineReached = false;
220
221 switch (deadlines.getType()) {
222 case TIME:
223 int timeDeadlineInSeconds = deadlines.getValue();
224 double timeRanInSeconds = getRuntimeInSeconds();
225 deadlineReached |= timeRanInSeconds > timeDeadlineInSeconds;
226 break;
227 case ROUND:
228 int roundsDeadline = (Integer) deadlines.getValue();
229 deadlineReached |= getRoundNumber() > roundsDeadline;
230 break;
231 }
232
233 return deadlineReached;
234 }
235
236 public long getRuntimeInNanoSeconds() {
237 if (timerRunning)
238 return System.nanoTime() - startTime;
239 else
240 return stopTime - startTime;
241 }
242
243 public double getRuntimeInSeconds() {
244 return (double) getRuntimeInNanoSeconds() / pow(10, 9); // ns -> s ( /
245 // 10^9 )
246 }
247
248 public void setRuntimeInNanoSeconds(long nanoSeconds) {
249 stopTime = System.nanoTime();
250 startTime = stopTime - nanoSeconds;
251 }
252
253 public void setRuntimeInSeconds(double seconds) {
254 setRuntimeInNanoSeconds(Math.round(seconds * pow(10, 9)));
255 }
256
257 public boolean isTimerRunning() {
258 return timerRunning;
259 }
260
261 public Timeline getTimeline() {
262 return timeline;
263 }
264
265 public void setTimeline(Timeline timeline) {
266 this.timeline = timeline;
267 }
268
269 /**
270 * @return SessionsInfo containing all information that is fixed for all
271 * sessions in the tournament/negotiation
272 */
273 public SessionsInfo getInfo() {
274 return sessionsInfo;
275 }
276
277}
Note: See TracBrowser for help on using the repository browser.