Skip to content

Commit 9e34862

Browse files
committed
Add global time metric to stats3, hide power in level viewer
1 parent 01b34ec commit 9e34862

File tree

4 files changed

+51
-24
lines changed

4 files changed

+51
-24
lines changed

app/statistics3/LogEventValidator.py

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import timedelta
12
import logging
23

34
from sqlalchemy.orm import Session
@@ -58,7 +59,8 @@ def handle_event(self, event: LogEvent, session: Session, statsParticipant: Stat
5859
assert isinstance(event, ChronoEvent)
5960
self.event_chrono(statsParticipant, player, event)
6061
case StartSessionEvent.__tablename__:
61-
pass
62+
assert isinstance(event, StartSessionEvent)
63+
self.event_start_session(statsParticipant, event)
6264
case SkillAssessmentEvent.__tablename__:
6365
pass
6466
case QualiEvent.__tablename__:
@@ -204,6 +206,33 @@ def event_chrono(self,
204206
raise LogValidationError(f'Unknown timer type "{event.timerType}"')
205207

206208

209+
def event_start_session(self,
210+
statsParticipant: StatsParticipant,
211+
event: StartSessionEvent
212+
):
213+
assert event.timeClient is not None
214+
assert event.phase is not None
215+
216+
# No need to set the page reload flag, if this is the first launch
217+
if not statsParticipant.game_started:
218+
statsParticipant.game_started = True
219+
statsParticipant.start_time = event.timeClient
220+
return
221+
222+
# Otherwise at this point this must be a page reload
223+
statsParticipant.activePhase.reloaded = True
224+
levelName = ''
225+
226+
if isinstance(statsParticipant.activePhase, StatsPhaseLevels):
227+
statsParticipant.activePhase.activeLevel.reloaded = True
228+
levelName = '@' + statsParticipant.activePhase.activeLevel.log_name
229+
230+
ui = getShortPseudo(statsParticipant.pseudonym)
231+
reload_location = statsParticipant.activePhase.phaseType + levelName
232+
logging.warning(f'Participant {ui} reloaded the page at "{reload_location}"')
233+
statsParticipant.reloads.append(reload_location)
234+
235+
207236
def event_quali(self,
208237
statsParticipant: StatsParticipant,
209238
event: QualiEvent
@@ -321,24 +350,14 @@ def start_phase(self, event: ChronoEvent, statsParticipant: StatsParticipant):
321350
assert event.timeClient is not None
322351
assert event.phase is not None
323352

324-
# Set the reload flag on page reload for phase and if applicable, also level
353+
# Preload events follow directly after event_start_session
325354
if event.phase.activePhase == PhaseType.Preload:
326-
# No need to set the page reload flag, if this is the first launch
327-
if not statsParticipant.game_started:
328-
statsParticipant.game_started = True
329-
return
330-
331-
statsParticipant.activePhase.reloaded = True
332-
levelName = ''
333-
334-
if isinstance(statsParticipant.activePhase, StatsPhaseLevels):
335-
statsParticipant.activePhase.activeLevel.reloaded = True
336-
levelName = '@' + statsParticipant.activePhase.activeLevel.log_name
337-
338-
ui = getShortPseudo(statsParticipant.pseudonym)
339-
reload_location = statsParticipant.activePhase.phaseType + levelName
340-
logging.warning(f'Participant {ui} reloaded the page at "{reload_location}"')
341-
statsParticipant.reloads.append(reload_location)
355+
if not statsParticipant.game_started or statsParticipant.start_time is None:
356+
raise LogValidationError('Preload Scene must follow directly after an event_start_phase')
357+
358+
# The Preload event contains the time limit
359+
if event.limit is not None:
360+
statsParticipant.time_limit = timedelta(seconds=event.limit)
342361

343362
# If this is not a preload phase, start the phase as usual
344363
else:

app/statistics3/StatsParticipant.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class StatsParticipant:
2222
game_started: bool = False
2323
reloads: list[str] = field(default_factory=list[str])
2424

25+
start_time: TIMESTAMP_MS|None = None
26+
finish_time: TIMESTAMP_MS|None = None
2527
time_limit: timedelta|None = None
2628

2729
@property

app/statistics3/statistics3.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ def main():
160160
.execution_options(sqlite_readonly = True))
161161

162162
try:
163-
if args.beginning is not None and len(args.beginning) > 0:
164-
start_time = datetime.fromisoformat(args.beginning)
163+
if args.beginning is not None and len(args.beginning.strip()) > 0:
164+
start_time = datetime.fromisoformat(args.beginning.strip())
165165
else:
166166
start_time = None
167167
except Exception as e:

static/src/LevelEditor/LevelViewScene.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,18 @@ class LevelViewScene extends BaseScene
5555
*/
5656
customSettings()
5757
{
58-
const url = new URL(window.location.href);
58+
const searchParams = new URL(window.location.href).searchParams;
5959

6060
// Make the screen print friendly
61-
if(!url.searchParams.has('darkMode'))
61+
if(!searchParams.has('darkMode'))
6262
this.setBrightMode();
63+
64+
// Visualize the simulation state
65+
if(searchParams.has('hidePower'))
66+
{
67+
this.state.outputStateVisible = false;
68+
this.state.wireStateVisible = false;
69+
}
6370

6471
this.showTextAnchors = false;
6572
this.splittersAlwaysVisible = false;
@@ -155,8 +162,7 @@ class LevelViewScene extends BaseScene
155162
else
156163
this.circuit = new Circuit(this, this.levelFile.fileContent, this.splittersAlwaysVisible);
157164

158-
this.circuit.calculateOutputs();
159-
this.circuit.wireDrawer.drawWires();
165+
this.updateLevelState(false);
160166

161167
// Show the wire length if enabled
162168
if(this.showWireLen)

0 commit comments

Comments
 (0)