mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 21:03:01 +00:00
Optimize stock news display performance: - Cache text image to reduce rendering overhead - Improve frame creation and update logic - Optimize text wrapping for smoother scrolling - Remove unnecessary display clears
This commit is contained in:
@@ -26,6 +26,8 @@ class StockNewsManager:
|
|||||||
self.news_data = {}
|
self.news_data = {}
|
||||||
self.current_news_group = 0 # Track which group of headlines we're showing
|
self.current_news_group = 0 # Track which group of headlines we're showing
|
||||||
self.scroll_position = 0
|
self.scroll_position = 0
|
||||||
|
self.cached_text_image = None # Cache for the text image
|
||||||
|
self.cached_text = None # Cache for the text string
|
||||||
|
|
||||||
# Get scroll settings from config with faster defaults
|
# Get scroll settings from config with faster defaults
|
||||||
self.scroll_speed = self.stock_news_config.get('scroll_speed', 1)
|
self.scroll_speed = self.stock_news_config.get('scroll_speed', 1)
|
||||||
@@ -205,33 +207,54 @@ class StockNewsManager:
|
|||||||
separator = " - " # Visual separator between news items
|
separator = " - " # Visual separator between news items
|
||||||
news_text = separator.join(news_texts)
|
news_text = separator.join(news_texts)
|
||||||
|
|
||||||
# Create a text image for efficient scrolling
|
# Only create new text image if the text has changed
|
||||||
text_image = self._create_text_image(news_text)
|
if news_text != self.cached_text:
|
||||||
text_width = text_image.width
|
self.cached_text = news_text
|
||||||
text_height = text_image.height
|
self.cached_text_image = self._create_text_image(news_text)
|
||||||
|
self.scroll_position = 0 # Reset scroll position for new text
|
||||||
|
|
||||||
# Calculate display position
|
if not self.cached_text_image:
|
||||||
|
return
|
||||||
|
|
||||||
|
text_width = self.cached_text_image.width
|
||||||
|
text_height = self.cached_text_image.height
|
||||||
display_width = self.display_manager.matrix.width
|
display_width = self.display_manager.matrix.width
|
||||||
total_width = text_width + display_width
|
total_width = text_width + display_width
|
||||||
|
|
||||||
# Update scroll position
|
# Update scroll position
|
||||||
self.scroll_position = (self.scroll_position + self.scroll_speed) % total_width
|
self.scroll_position = (self.scroll_position + self.scroll_speed) % total_width
|
||||||
|
|
||||||
# Clear the display
|
|
||||||
self.display_manager.clear()
|
|
||||||
|
|
||||||
# Calculate the visible portion of the text
|
# Calculate the visible portion of the text
|
||||||
visible_width = min(display_width, text_width - self.scroll_position)
|
visible_width = min(display_width, text_width - self.scroll_position)
|
||||||
if visible_width > 0:
|
if visible_width > 0:
|
||||||
# Crop the text image to show only the visible portion
|
# Create a new blank image for this frame
|
||||||
visible_portion = text_image.crop((self.scroll_position, 0,
|
frame_image = Image.new('RGB', (display_width, text_height), (0, 0, 0))
|
||||||
self.scroll_position + visible_width, text_height))
|
|
||||||
|
|
||||||
# Paste the visible portion onto the display
|
# Crop and paste in one operation
|
||||||
self.display_manager.image.paste(visible_portion, (0, 0))
|
if self.scroll_position + visible_width <= text_width:
|
||||||
|
# Normal case - text is still scrolling in
|
||||||
# Update the display
|
visible_portion = self.cached_text_image.crop((
|
||||||
self.display_manager.update_display()
|
self.scroll_position, 0,
|
||||||
|
self.scroll_position + visible_width, text_height
|
||||||
|
))
|
||||||
|
frame_image.paste(visible_portion, (0, 0))
|
||||||
|
else:
|
||||||
|
# Wrapping case - text is wrapping around
|
||||||
|
first_part_width = text_width - self.scroll_position
|
||||||
|
first_part = self.cached_text_image.crop((
|
||||||
|
self.scroll_position, 0,
|
||||||
|
text_width, text_height
|
||||||
|
))
|
||||||
|
second_part = self.cached_text_image.crop((
|
||||||
|
0, 0,
|
||||||
|
visible_width - first_part_width, text_height
|
||||||
|
))
|
||||||
|
frame_image.paste(first_part, (0, 0))
|
||||||
|
frame_image.paste(second_part, (first_part_width, 0))
|
||||||
|
|
||||||
|
# Update the display with the new frame
|
||||||
|
self.display_manager.image = frame_image
|
||||||
|
self.display_manager.update_display()
|
||||||
|
|
||||||
# If we've completed a full scroll, move to the next group
|
# If we've completed a full scroll, move to the next group
|
||||||
if self.scroll_position == 0:
|
if self.scroll_position == 0:
|
||||||
|
|||||||
@@ -38,14 +38,9 @@ def main():
|
|||||||
|
|
||||||
print("Testing news display. Press Ctrl+C to exit.")
|
print("Testing news display. Press Ctrl+C to exit.")
|
||||||
|
|
||||||
# Run the news display in a loop with proper timing
|
# Run the news display in a loop
|
||||||
last_update = time.time()
|
|
||||||
while True:
|
while True:
|
||||||
current_time = time.time()
|
news_manager.display_news()
|
||||||
# Ensure we're not updating too frequently
|
|
||||||
if current_time - last_update >= 0.001: # 1ms minimum between updates
|
|
||||||
news_manager.display_news()
|
|
||||||
last_update = current_time
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("\nTest interrupted by user")
|
print("\nTest interrupted by user")
|
||||||
|
|||||||
Reference in New Issue
Block a user