Fix leaderboard scrolling performance after PR #39 merge (#63)

* Fix leaderboard scrolling performance after PR #39 merge

- Restore leaderboard background updates that were accidentally removed
- Fix duration method call from get_dynamic_duration() back to get_duration()
- Restore proper fallback duration (600s instead of 60s) for leaderboard
- Add back sports manager updates that feed data to leaderboard
- Fix leaderboard defer_update priority to prevent scrolling lag

These changes restore the leaderboard's dynamic duration calculation
and ensure it gets proper background updates for smooth scrolling.

* Apply PR #60 leaderboard performance optimizations

- Change scroll_delay from 0.05s to 0.01s (100fps instead of 20fps)
- Remove conditional scrolling logic - scroll every frame for smooth animation
- Add FPS tracking and logging for performance monitoring
- Restore high-framerate scrolling that was working before PR #39 merge

These changes restore the smooth leaderboard scrolling performance
that was achieved in PR #60 but was lost during the PR #39 merge.

* Fix critical bugs identified in PR #39 review

- Fix record filtering logic bug: change away_record == set to away_record in set
- Fix incorrect sport specification: change 'nfl' to 'ncaa_fb' for NCAA Football data requests
- These bugs were causing incorrect data display and wrong sport data fetching

Addresses issues found by cursor bot in PR #39 review:
- Record filtering was always evaluating to False
- NCAA Football was fetching NFL data instead of college football data

* Enhance cache clearing implementation from PR #39

- Add detailed logging to cache clearing process for better visibility
- Log cache clearing statistics (memory entries and file count)
- Improve startup logging to show cache clearing and data refetch process
- Addresses legoguy1000's comment about preventing stale data issues

This enhances the cache clearing implementation that was added in PR #39
to help prevent legacy cache issues and stale data problems.

* continuing on base_classes - added baseball and api extractor since we don't use ESPN api for all sports

* tests

* fix missing duration

* ensure milb, mlb, ncaa bb are all using new baseball base class properly

* cursor rule to help with PR creation

* fix image call

* fix _scoreboard suffix on milb, MLB
This commit is contained in:
Chuck
2025-09-25 09:34:20 -04:00
committed by GitHub
parent 76a9e98ba7
commit ad8a652183
30 changed files with 2821 additions and 102 deletions

View File

@@ -40,7 +40,7 @@ class LeaderboardManager:
self.enabled_sports = self.leaderboard_config.get('enabled_sports', {})
self.update_interval = self.leaderboard_config.get('update_interval', 3600)
self.scroll_speed = self.leaderboard_config.get('scroll_speed', 2)
self.scroll_delay = self.leaderboard_config.get('scroll_delay', 0.05)
self.scroll_delay = self.leaderboard_config.get('scroll_delay', 0.01)
self.display_duration = self.leaderboard_config.get('display_duration', 30)
self.loop = self.leaderboard_config.get('loop', True)
self.request_timeout = self.leaderboard_config.get('request_timeout', 30)
@@ -53,6 +53,12 @@ class LeaderboardManager:
self.dynamic_duration = 60 # Default duration in seconds
self.total_scroll_width = 0 # Track total width for dynamic duration calculation
# FPS tracking variables
self.frame_times = [] # Store last 30 frame times for averaging
self.last_frame_time = 0
self.fps_log_interval = 10.0 # Log FPS every 10 seconds
self.last_fps_log_time = 0
# Initialize managers
self.cache_manager = CacheManager()
# Store reference to config instead of creating new ConfigManager
@@ -1234,6 +1240,13 @@ class LeaderboardManager:
logger.debug(f"get_dynamic_duration called, returning: {self.dynamic_duration}s")
return self.dynamic_duration
def get_duration(self) -> int:
"""Get the display duration for the leaderboard."""
if self.dynamic_duration_enabled:
return self.get_dynamic_duration()
else:
return self.display_duration
def update(self) -> None:
"""Update leaderboard data."""
current_time = time.time()
@@ -1329,20 +1342,31 @@ class LeaderboardManager:
try:
current_time = time.time()
# Check if we should be scrolling
should_scroll = current_time - self.last_scroll_time >= self.scroll_delay
# FPS tracking
if self.last_frame_time > 0:
frame_time = current_time - self.last_frame_time
self.frame_times.append(frame_time)
if len(self.frame_times) > 30:
self.frame_times.pop(0)
# Log FPS every 10 seconds
if current_time - self.last_fps_log_time >= self.fps_log_interval:
if self.frame_times:
avg_frame_time = sum(self.frame_times) / len(self.frame_times)
fps = 1.0 / avg_frame_time if avg_frame_time > 0 else 0
logger.info(f"Leaderboard FPS: {fps:.1f} (avg frame time: {avg_frame_time*1000:.1f}ms)")
self.last_fps_log_time = current_time
self.last_frame_time = current_time
# Signal scrolling state to display manager
if should_scroll:
self.display_manager.set_scrolling_state(True)
else:
# If we're not scrolling, check if we should process deferred updates
self.display_manager.process_deferred_updates()
self.display_manager.set_scrolling_state(True)
# Scroll the image
if should_scroll:
self.scroll_position += self.scroll_speed
self.last_scroll_time = current_time
# Scroll the image every frame for smooth animation
self.scroll_position += self.scroll_speed
# Add scroll delay like other managers for consistent timing
time.sleep(self.scroll_delay)
# Calculate crop region
width = self.display_manager.matrix.width