From c3ec97a2a9791b323caabd48ccf74b7118d19ef5 Mon Sep 17 00:00:00 2001 From: esitarski Date: Tue, 23 Apr 2024 09:20:32 -0400 Subject: [PATCH 1/2] Fixed bug in early bell results. Added early bell symbol to the RaceHUD (Head's Up Display). --- Categories.py | 2 +- GetResults.py | 4 ++-- NumKeypad.py | 5 +++-- RaceHUD.py | 20 ++++++++++++++++---- Version.py | 2 +- 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Categories.py b/Categories.py index 8f50f8f3..7b03b071 100644 --- a/Categories.py +++ b/Categories.py @@ -671,7 +671,7 @@ def _setRow( self, r, active, name, catStr, startOffset='00:00:00', startOffset = '00:' + startOffset earlyBellTime = earlyBellTime or '' if isinstance( earlyBellTime, (float, int) ): - earlyBellTime = Utils.formatTime( float(earlyBellTime) ) + earlyBellTime = Utils.formatTime( float(earlyBellTime) ) if earlyBellTime else '' GetTranslation = _ gender = gender if gender in ['Men', 'Women'] else 'Open' diff --git a/GetResults.py b/GetResults.py index be242d7b..2ac11070 100644 --- a/GetResults.py +++ b/GetResults.py @@ -372,9 +372,9 @@ def _GetResultsCore( category ): interp.clear() # Apply the early bell time. Early bell time signifies the beginning of the last lap for all riders. - if riderCategory.earlyBellTime and not race.isTimeTrial: + if riderCategory.earlyBellTime and not race.isTimeTrial and times: try: - while riderCategory.earlyBellTime <= times[-2]: + while times[-3] >= riderCategory.earlyBellTime: times.pop() interp.pop() laps -= 1 diff --git a/NumKeypad.py b/NumKeypad.py index 51a33d50..1e549e56 100644 --- a/NumKeypad.py +++ b/NumKeypad.py @@ -465,7 +465,7 @@ def setLapCounter( leaderCategory, category, lapCur, lapMax, tLeaderArrival=sys. except (KeyError, IndexError): pass - leader, raceTimes = [], [] + leader, raceTimes, earlyBellTime = [], [], [] for category in categories: results = GetResultsWithData( category ) if not results or not results[0].status == Finisher or not results[0].raceTimes: @@ -473,6 +473,7 @@ def setLapCounter( leaderCategory, category, lapCur, lapMax, tLeaderArrival=sys. raceTimes.append( [] ) continue + earlyBellTime.append( category.earlyBellTime ) leader.append( '{} [{}]'.format(category.fullname, results[0].num) ) for rank, rr in enumerate(results, 1): if rr.status != Finisher or not rr.raceTimes or len(rr.raceTimes) < 2: @@ -536,7 +537,7 @@ def setLapCounter( leaderCategory, category, lapCur, lapMax, tLeaderArrival=sys. del self.lapReminder[category] # Ensure that the raceTime and leader are sorted the same as the Categories are defined. - self.raceHUD.SetData( raceTimes, leader, tCur if race.isRunning() else None ) + self.raceHUD.SetData( raceTimes, leader, tCur if race.isRunning() else None, earlyBellTime ) if Utils.mainWin: Utils.mainWin.updateLapCounter( lapCounter ) self.updateLayout() diff --git a/RaceHUD.py b/RaceHUD.py index fcce13bc..4feec926 100644 --- a/RaceHUD.py +++ b/RaceHUD.py @@ -20,6 +20,7 @@ def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, super().__init__(parent, id, pos, size, style, validator, name) self.SetBackgroundColour(wx.WHITE) self.raceTimes = None # Last time is red lantern. + self.earlyBellTime = None self.leader = None self.nowTime = None self.getNowTimeCallback = None @@ -68,8 +69,9 @@ def GetDefaultAttributes(self): def ShouldInheritColours(self): return True - def SetData( self, raceTimes = None, leader = None, nowTime = None ): - self.leader = leader or [] # List of the category names. + def SetData( self, raceTimes=None, leader=None, nowTime=None, earlyBellTime=None ): + self.leader = leader or [] # List of the category names. + self.earlyBellTime = earlyBellTime or [] # Early bell times per category. # Race times for the category leader. The last time is the last rider expected to finish. self.raceTimes = [rt if not rt or len(rt)>=2 else [] for rt in (raceTimes or [])] self.nowTime = nowTime @@ -77,6 +79,7 @@ def SetData( self, raceTimes = None, leader = None, nowTime = None ): maxRaceTimes = 16 self.raceTimes = self.raceTimes[:maxRaceTimes] self.leader = self.leader[:maxRaceTimes] + self.earlyBellTime = self.earlyBellTime[:maxRaceTimes] self.Refresh() def GetLaps( self ): @@ -291,6 +294,15 @@ def drawTooSmall(): ctx.SetBrush( wx.Brush(wx.Colour(255,0,0)) ) ctx.DrawEllipse( round(x - iRadius / 2), round(yTop + hMiddle - tickHeight - iRadius/4), round(iRadius), round(iRadius) ) + # Draw early bell time. + try: + ebt = self.earlyBellTime[iRaceTimes] + except (TypeError, IndexError): + ebt = None + if ebt: + x = xLeft + int( ebt * xMult ) + dc.DrawBitmap( self.bell, round(x), round(yTop + hMiddle - self.bell.GetHeight()*1.5) ) + ctx.SetPen( wx.BLACK_PEN ) # Draw the time to the leader's next lap (or the broom if the race is over). @@ -396,12 +408,12 @@ def GetData(): t = 55*60 tVar = t * 0.15 data = GetData() - RaceHUD.SetData( data, leader = [20,120], nowTime = data[0][3] - 13.0 - 30) + RaceHUD.SetData( data, leader = [20,120], nowTime = data[0][3] - 13.0 - 30, earlyBellTime=[d[-5] for d in data]) startTime = datetime.datetime.now() - datetime.timedelta( seconds = 20 ) def updateTime(): nowTime = (datetime.datetime.now() - startTime).total_seconds() / 2 - RaceHUD.SetData( data, leader = [20,120], nowTime = nowTime ) + RaceHUD.SetData( data, leader = [20,120], nowTime = nowTime, earlyBellTime=[d[-5] for d in data] ) if nowTime < data[-1][-1]: wx.CallLater( 1000, updateTime ) diff --git a/Version.py b/Version.py index 59faf85f..041ccd94 100644 --- a/Version.py +++ b/Version.py @@ -1 +1 @@ -AppVerName="CrossMgr 3.1.49-private" +AppVerName="CrossMgr 3.1.50-private" From 106652f46363f9dbda34ec0e947014ed12b89d78 Mon Sep 17 00:00:00 2001 From: esitarski Date: Tue, 23 Apr 2024 12:14:59 -0400 Subject: [PATCH 2/2] Fixed bug in the EarlyBellTime logic. Added visuals for EarlyBellTime in the RaceHUD and the GanttChartPanel. Updated documentation about the EBT visuals. --- Gantt.py | 7 +++++++ GanttChartPanel.py | 13 ++++++++++++- GetResults.py | 2 +- helptxt/Chart.md | 2 ++ helptxt/Record.md | 2 ++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Gantt.py b/Gantt.py index 12124fdb..a8acb673 100644 --- a/Gantt.py +++ b/Gantt.py @@ -563,6 +563,7 @@ def refresh( self ): headerSet = set() if race.groupByStartWave and not category: results = [] + earlyBellTimes = [] for c in sorted(race.getCategories(), key=lambda x:x.getStartOffsetSecs()): catResults = GetResults(c) if not catResults: @@ -571,10 +572,15 @@ def refresh( self ): rr = RiderResult( num='', status=Finisher, lastTime=None, raceCat=c, lapTimes=[], raceTimes=[], interp=[] ) rr.FirstName = c.fullname headerSet.add( rr.FirstName ) + results.append( rr ) + earlyBellTimes.append( None ) + results.extend( list(catResults) ) + earlyBellTimes.extend( c.earlyBellTime if r.status == Finisher else None for r in catResults ) else: results = GetResults( category ) + earlyBellTimes = [category.earlyBellTime if r.status == Finisher else None for r in results] if race.showFullNamesInChart: def getLabel( r ): @@ -608,6 +614,7 @@ def getLabel( r ): getattr( Model.race, 'lapNote', None), headerSet = headerSet, status = status, + earlyBellTimes = earlyBellTimes, ) self.updateStats( results ) diff --git a/GanttChartPanel.py b/GanttChartPanel.py index d5bbaaa0..d536e350 100644 --- a/GanttChartPanel.py +++ b/GanttChartPanel.py @@ -151,7 +151,7 @@ def ShouldInheritColours(self): def SetData( self, data, labels = None, nowTime = None, interp = None, greyOutSet = set(), numTimeInfo = None, lapNote = None, status = None, - headerSet = None ): + headerSet = None, earlyBellTimes = None ): """ * data is a list of lists. Each list is a list of times. * labels are the names of the series. Optional. @@ -164,6 +164,7 @@ def SetData( self, data, labels = None, nowTime = None, interp = None, greyOutSe self.numTimeInfo = numTimeInfo self.lapNote = lapNote self.headerSet = headerSet or set() + self.earlyBellTimes = earlyBellTimes if data and any( s for s in data ): self.data = data self.dataMax = max(max(s) if s else -sys.float_info.max for s in self.data) @@ -179,6 +180,7 @@ def SetData( self, data, labels = None, nowTime = None, interp = None, greyOutSe self.nowTime = nowTime self.interp = interp + self.earlyBellTimes = earlyBellTimes or [] self.Refresh() def OnPaint(self, event ): @@ -495,6 +497,9 @@ def overlaps( d ): penBar.SetJoin( wx.JOIN_MITER ) dc.SetPen( penBar ) + penEBT = wx.Pen( wx.Colour(230,0,0), 3 ) + penEBT.SetCap( wx.CAP_BUTT ) + brushBar = wx.Brush( wx.BLACK ) transparentBrush = wx.Brush( wx.WHITE, style = wx.TRANSPARENT ) @@ -625,6 +630,12 @@ def tToX( t ): dc.SetBrush( brushBar ) dc.DrawRectangle( xLast, yLast, xCur - xLast + 1, yCur - yLast + 1 ) + # Draw the early bell line. + if self.earlyBellTimes and self.earlyBellTimes[i]: + ebtX = tToX( self.earlyBellTimes[i] ) + dc.SetPen( penEBT ) + dc.DrawLine( ebtX, yLast, ebtX, yLast+dy ) + # Draw the label on both ends. if self.greyOutSet and i in self.greyOutSet: dc.SetPen( wx.TRANSPARENT_PEN ) diff --git a/GetResults.py b/GetResults.py index 2ac11070..101de8df 100644 --- a/GetResults.py +++ b/GetResults.py @@ -374,7 +374,7 @@ def _GetResultsCore( category ): # Apply the early bell time. Early bell time signifies the beginning of the last lap for all riders. if riderCategory.earlyBellTime and not race.isTimeTrial and times: try: - while times[-3] >= riderCategory.earlyBellTime: + while times[-3] >= riderCategory.earlyBellTime: # This is confusing. Don't change it! times.pop() interp.pop() laps -= 1 diff --git a/helptxt/Chart.md b/helptxt/Chart.md index d2c7693e..6fc7fac2 100644 --- a/helptxt/Chart.md +++ b/helptxt/Chart.md @@ -21,6 +21,8 @@ Diamond|Indicates a CrossMgr auto-corrected time that did not appear in the orig Star|Indicates a User Edit of the original input. Changes made by users are logged and timestamped (see RiderDetail). Red Circle|Indicates a duplicate time. Although rare, times may be entered more than once for the same lap. For example, a number caller might turn around see the numbers on the backs of riders and call the same number twice. CrossMgr's Auto-Correct will take care of these, but you will see them if you turn Auto-Correct off. To fix this situation manually, delete one of the duplicates. A time is considered a duplicate if it results in a lap that is less than 15 seconds. +The __Early Bell Time__ (when used) is shown as a vertical red line. All riders in a category will start their last lap after the __Early Bell Time__. + # Controls ## Category Selects the Category of the chart. Category "All" will show results as if all riders were in the same category. This is useful for comparing against manually generated results for the race as a whole. diff --git a/helptxt/Record.md b/helptxt/Record.md index eadf3739..a0dc7f43 100644 --- a/helptxt/Record.md +++ b/helptxt/Record.md @@ -176,6 +176,8 @@ Use this display to manage lap counters by category. It allows you to easily se For additional information, hover the mouse over the lap. This will show more start/end times and lap time. +The __Early Bell Time__ is also shown as a small bell (when set). See below for information about the __Early Bell Time__ and the [SetLaps][] dialog. + ### Set Laps from the Lap Chart To modify the number of laps during the race, click anywhere on the Progress bars (or Start Wave labels).