source: geniuswebcore/geniusweb/progress/ProgressRounds.py@ 94

Last change on this file since 94 was 90, checked in by Bart Vastenhouw, 3 years ago

Refactor to help reusing partiesserver.

File size: 3.3 KB
Line 
1from __future__ import annotations
2from datetime import datetime
3
4from geniusweb.progress.Progress import Progress
5
6
7class ProgressRounds (Progress):
8 '''
9 progress in terms of number of rounds. The round has to be updated by the
10 user of this class, calling {@link #advance()}. immutable.
11 '''
12
13 def __init__(self, duration:int, currentRound:int, endtime:datetime):
14 '''
15 @param duration length max number of rounds, must be positive (not 0)
16 @param currentRound the current round number (can be from 0 to deadlne).
17 When = deadline, it means the progress has gone past
18 the deadline.
19 @param end the termination time of this session.
20 WARNING due to a bug in python for windows, this value must be
21 at least 100000 seconds above jan. 1, 1970.
22 '''
23 if duration <= 0:
24 raise ValueError("deadline must be positive but is " + str(duration))
25 if currentRound < 0 or currentRound > duration:
26 raise ValueError("current round must be inside [0," + str(duration) + "]")
27 self._duration = duration
28 self._currentRound = currentRound
29 self._endtime = endtime
30
31 def getTerminationTime(self) -> datetime:
32 return self._endtime
33
34 def getDuration(self):
35 '''
36 @return max number of rounds, positive integer (not 0)
37 '''
38 return self._duration
39
40 def getEndtime(self):
41 return self._endtime
42
43 def getCurrentRound(self) -> int:
44 '''
45 @return the current round. First round is 0. It is recommended that you
46 use the functions in {@link Progress} instead of this, to ensure
47 your code works with all implementations of Progress including
48 future developments.
49 '''
50 return self._currentRound
51
52 def getTotalRounds(self) -> int:
53 '''
54 @return total number of rounds. It is recommended that you use the
55 functions in {@link Progress} instead of this, to ensure your
56 code works with all implementations of Progress including future
57 developments.
58 '''
59 return self._duration
60
61 def get(self, currentTimeMs:int) -> float:
62 # deadline and current both are limited to MAXINT is 32 bits; double
63 # fits 52
64 # bits so this should not result in accuracy issues
65 ratio:float = self._currentRound / self._duration;
66 if ratio > 1:
67 ratio = 1;
68 elif ratio < 0:
69 ratio = 0;
70 return ratio;
71
72 def isPastDeadline(self, currentTimeMs:int) -> bool:
73 return self._currentRound >= self._duration or \
74 currentTimeMs > int(1000 * datetime.timestamp(self._endtime))
75
76 def advance(self) -> "ProgressRounds" :
77 '''
78 @return new ProgressRounds with round 1 advanced (or this, if
79 currentRound= duration). This is up to the user, as it is up to
80 the used protocol what exactly is a round.
81 '''
82 if self._duration == self._currentRound:
83 return self
84 return ProgressRounds(self._duration, self._currentRound + 1, self._endtime)
85
86 def __hash__(self):
87 return hash((self._currentRound, self._duration))
88
89 def __eq__(self, other):
90 return isinstance(other, self.__class__) \
91 and self._currentRound == other._currentRound \
92 and self._duration == other._duration \
93 and self._endtime == other._endtime
94
95 def __repr__(self):
96 return "ProgressRounds[" + str(self._currentRound) \
97 +" of " + str(self._duration) \
98 +"," + str(datetime.timestamp(self._endtime)) + "]"
Note: See TracBrowser for help on using the repository browser.