|
37 | 37 | from . import errors, events, messages |
38 | 38 | from ._animator import DEFAULT_EASING, Animatable, BoundAnimator, EasingFunction |
39 | 39 | from ._arrange import DockArrangeResult, arrange |
| 40 | +from ._cache import LRUCache |
40 | 41 | from ._context import active_app |
41 | 42 | from ._easing import DEFAULT_SCROLL_EASING |
42 | 43 | from ._layout import Layout |
@@ -246,8 +247,8 @@ def __init__( |
246 | 247 | self._content_width_cache: tuple[object, int] = (None, 0) |
247 | 248 | self._content_height_cache: tuple[object, int] = (None, 0) |
248 | 249 |
|
249 | | - self._arrangement: DockArrangeResult | None = None |
250 | | - self._arrangement_cache_key: tuple[int, Size] = (-1, Size()) |
| 250 | + self._arrangement_cache_updates: int = -1 |
| 251 | + self._arrangement_cache: LRUCache[Size, DockArrangeResult] = LRUCache(4) |
251 | 252 |
|
252 | 253 | self._styles_cache = StylesCache() |
253 | 254 | self._rich_style_cache: dict[str, tuple[Style, Style]] = {} |
@@ -457,21 +458,24 @@ def _arrange(self, size: Size) -> DockArrangeResult: |
457 | 458 | Returns: |
458 | 459 | ArrangeResult: Widget locations. |
459 | 460 | """ |
| 461 | + assert self.is_container |
460 | 462 |
|
461 | | - arrange_cache_key = (self.children._updates, size) |
462 | | - if ( |
463 | | - self._arrangement is not None |
464 | | - and arrange_cache_key == self._arrangement_cache_key |
465 | | - ): |
466 | | - return self._arrangement |
| 463 | + if self._arrangement_cache_updates != self.children._updates: |
| 464 | + self._arrangement_cache_updates = self.children._updates |
| 465 | + self._arrangement_cache.clear() |
467 | 466 |
|
468 | | - self._arrangement_cache_key = arrange_cache_key |
469 | | - self._arrangement = arrange(self, self.children, size, self.screen.size) |
470 | | - return self._arrangement |
| 467 | + cached_arrangement = self._arrangement_cache.get(size, None) |
| 468 | + if cached_arrangement is not None: |
| 469 | + return cached_arrangement |
| 470 | + |
| 471 | + arrangement = self._arrangement_cache[size] = arrange( |
| 472 | + self, self.children, size, self.screen.size |
| 473 | + ) |
| 474 | + return arrangement |
471 | 475 |
|
472 | 476 | def _clear_arrangement_cache(self) -> None: |
473 | 477 | """Clear arrangement cache, forcing a new arrange operation.""" |
474 | | - self._arrangement = None |
| 478 | + self._arrangement_cache.clear() |
475 | 479 |
|
476 | 480 | def _get_virtual_dom(self) -> Iterable[Widget]: |
477 | 481 | """Get widgets not part of the DOM. |
|
0 commit comments