mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 21:03:01 +00:00
Fix/leaderboard timing improvements (#60)
* Fix leaderboard timing issues with comprehensive improvements - Add maximum display time cap (120s) to prevent hanging - Implement dynamic scroll speed tracking with runtime measurements - Simplify complex timing logic that was causing hangs - Add enhanced progress tracking and logging - Add configurable safety buffer (10s) - Update config template with new timing options - Add comprehensive test suite for timing logic Fixes the 30-second hanging issue reported in PR #53 by providing multiple layers of protection against time overestimation. * Simplify leaderboard timing to use long timeout with exception-based ending - Remove complex dynamic duration calculations - Remove safety buffer complexity - Remove scroll speed tracking and measurements - Use simple 10-minute timeout (600s) for both display_duration and max_display_time - Let content determine when display is complete via existing StopIteration logic - Update display controller to use simplified duration approach - Clean up config template to remove unused timing settings This approach is much more reliable than trying to predict content duration and eliminates the hanging issues reported in PR #53. * Fix configuration structure to use centralized display_durations - Remove redundant display_duration from leaderboard section - Use main display_durations.leaderboard (300s) for fixed duration mode - Update leaderboard manager to read from centralized config - Increase leaderboard default duration from 60s to 300s for better content coverage - Maintain dynamic_duration option for user choice between fixed/dynamic modes - Add comprehensive scroll behavior analysis and testing This completes the leaderboard timing improvements with proper config structure. * scroll every frame to be smoother like the stock ticker instead of waiting per subsecond * leaderboard block api calls while scrolling * leaderboard debugging * added leaderboard fps logging * leaderboard frame control and optimizations * background update memory leak for scrolling text found and first solution applied * tuning scroll speeds * working display scrolls * revert scroll delay to 0.01 (about 100fps) * revert min duration of leaderboard * remove onetime test scripts
This commit is contained in:
@@ -508,11 +508,15 @@ class DisplayController:
|
||||
if not hasattr(self, '_last_logged_duration') or self._last_logged_duration != dynamic_duration:
|
||||
logger.info(f"Using dynamic duration for stocks: {dynamic_duration} seconds")
|
||||
self._last_logged_duration = dynamic_duration
|
||||
# Debug: Always log the current dynamic duration value
|
||||
logger.debug(f"Stocks dynamic duration check: {dynamic_duration}s")
|
||||
return dynamic_duration
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting dynamic duration for stocks: {e}")
|
||||
# Fall back to configured duration
|
||||
return self.display_durations.get(mode_key, 60)
|
||||
fallback_duration = self.display_durations.get(mode_key, 60)
|
||||
logger.debug(f"Using fallback duration for stocks: {fallback_duration}s")
|
||||
return fallback_duration
|
||||
|
||||
# Handle dynamic duration for stock_news
|
||||
if mode_key == 'stock_news' and self.news:
|
||||
@@ -542,19 +546,20 @@ class DisplayController:
|
||||
# Fall back to configured duration
|
||||
return self.display_durations.get(mode_key, 60)
|
||||
|
||||
# Handle dynamic duration for leaderboard
|
||||
# Handle leaderboard duration (user choice between fixed or dynamic)
|
||||
if mode_key == 'leaderboard' and self.leaderboard:
|
||||
try:
|
||||
dynamic_duration = self.leaderboard.get_dynamic_duration()
|
||||
duration = self.leaderboard.get_duration()
|
||||
mode_type = "dynamic" if self.leaderboard.dynamic_duration else "fixed"
|
||||
# Only log if duration has changed or we haven't logged this duration yet
|
||||
if not hasattr(self, '_last_logged_leaderboard_duration') or self._last_logged_leaderboard_duration != dynamic_duration:
|
||||
logger.info(f"Using dynamic duration for leaderboard: {dynamic_duration} seconds")
|
||||
self._last_logged_leaderboard_duration = dynamic_duration
|
||||
return dynamic_duration
|
||||
if not hasattr(self, '_last_logged_leaderboard_duration') or self._last_logged_leaderboard_duration != duration:
|
||||
logger.info(f"Using leaderboard {mode_type} duration: {duration} seconds")
|
||||
self._last_logged_leaderboard_duration = duration
|
||||
return duration
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting dynamic duration for leaderboard: {e}")
|
||||
logger.error(f"Error getting duration for leaderboard: {e}")
|
||||
# Fall back to configured duration
|
||||
return self.display_durations.get(mode_key, 60)
|
||||
return self.display_durations.get(mode_key, 600)
|
||||
|
||||
# Simplify weather key handling
|
||||
if mode_key.startswith('weather_'):
|
||||
@@ -576,6 +581,8 @@ class DisplayController:
|
||||
# Defer updates for modules that might cause lag during scrolling
|
||||
if self.odds_ticker:
|
||||
self.display_manager.defer_update(self.odds_ticker.update, priority=1)
|
||||
if self.leaderboard:
|
||||
self.display_manager.defer_update(self.leaderboard.update, priority=1)
|
||||
if self.stocks:
|
||||
self.display_manager.defer_update(self.stocks.update_stock_data, priority=2)
|
||||
if self.news:
|
||||
@@ -1127,8 +1134,9 @@ class DisplayController:
|
||||
# Update data for all modules first
|
||||
self._update_modules()
|
||||
|
||||
# Process any deferred updates that may have accumulated
|
||||
self.display_manager.process_deferred_updates()
|
||||
# Process deferred updates less frequently when scrolling to improve performance
|
||||
if not self.display_manager.is_currently_scrolling() or (current_time % 2.0 < 0.1):
|
||||
self.display_manager.process_deferred_updates()
|
||||
|
||||
# Update live modes in rotation if needed
|
||||
self._update_live_modes_in_rotation()
|
||||
@@ -1250,6 +1258,10 @@ class DisplayController:
|
||||
if hasattr(self, '_last_logged_duration'):
|
||||
delattr(self, '_last_logged_duration')
|
||||
elif current_time - self.last_switch >= self.get_current_duration() or self.force_change:
|
||||
# Debug timing information
|
||||
elapsed_time = current_time - self.last_switch
|
||||
expected_duration = self.get_current_duration()
|
||||
logger.debug(f"Mode switch triggered: {self.current_display_mode} - Elapsed: {elapsed_time:.1f}s, Expected: {expected_duration}s, Force: {self.force_change}")
|
||||
self.force_change = False
|
||||
if self.current_display_mode == 'calendar' and self.calendar:
|
||||
self.calendar.advance_event()
|
||||
@@ -1271,6 +1283,8 @@ class DisplayController:
|
||||
if needs_switch:
|
||||
self.force_clear = True
|
||||
self.last_switch = current_time
|
||||
# Debug: Log when we set the switch time for a new mode
|
||||
logger.debug(f"Mode switch completed: {self.current_display_mode} - Switch time set to {current_time}, Duration: {self.get_current_duration()}s")
|
||||
else:
|
||||
self.force_clear = False
|
||||
# Only set manager_to_display if it hasn't been set by live priority logic
|
||||
|
||||
Reference in New Issue
Block a user