simplified cache_key

This commit is contained in:
Will McGugan
2022-11-18 13:59:58 +00:00
parent ccabbf01a3
commit fa5ac0dd68
2 changed files with 39 additions and 1 deletions

View File

@@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Watchers are now called immediately when setting the attribute if they are synchronous. https://github.com/Textualize/textual/pull/1145 - Watchers are now called immediately when setting the attribute if they are synchronous. https://github.com/Textualize/textual/pull/1145
- Widget.call_later has been renamed to Widget.call_after_refresh. - Widget.call_later has been renamed to Widget.call_after_refresh.
- Button variant values are now checked at runtime. https://github.com/Textualize/textual/issues/1189 - Button variant values are now checked at runtime. https://github.com/Textualize/textual/issues/1189
- Added caching of some properties in Styles object
### Fixed ### Fixed

View File

@@ -557,6 +557,7 @@ class StylesBase(ABC):
class Styles(StylesBase): class Styles(StylesBase):
node: DOMNode | None = None node: DOMNode | None = None
_rules: RulesMap = field(default_factory=dict) _rules: RulesMap = field(default_factory=dict)
_updates: int = 0
important: set[str] = field(default_factory=set) important: set[str] = field(default_factory=set)
@@ -577,6 +578,7 @@ class Styles(StylesBase):
Returns: Returns:
bool: ``True`` if a rule was cleared, or ``False`` if it was already not set. bool: ``True`` if a rule was cleared, or ``False`` if it was already not set.
""" """
self._updates += 1
return self._rules.pop(rule, None) is not None return self._rules.pop(rule, None) is not None
def get_rules(self) -> RulesMap: def get_rules(self) -> RulesMap:
@@ -592,6 +594,7 @@ class Styles(StylesBase):
Returns: Returns:
bool: ``True`` if the rule changed, otherwise ``False``. bool: ``True`` if the rule changed, otherwise ``False``.
""" """
self._updates += 1
if value is None: if value is None:
return self._rules.pop(rule, None) is not None return self._rules.pop(rule, None) is not None
current = self._rules.get(rule) current = self._rules.get(rule)
@@ -610,6 +613,7 @@ class Styles(StylesBase):
def reset(self) -> None: def reset(self) -> None:
"""Reset the rules to initial state.""" """Reset the rules to initial state."""
self._updates += 1
self._rules.clear() self._rules.clear()
def merge(self, other: Styles) -> None: def merge(self, other: Styles) -> None:
@@ -618,10 +622,11 @@ class Styles(StylesBase):
Args: Args:
other (Styles): A Styles object. other (Styles): A Styles object.
""" """
self._updates += 1
self._rules.update(other._rules) self._rules.update(other._rules)
def merge_rules(self, rules: RulesMap) -> None: def merge_rules(self, rules: RulesMap) -> None:
self._updates += 1
self._rules.update(rules) self._rules.update(rules)
def extract_rules( def extract_rules(
@@ -929,6 +934,18 @@ class RenderStyles(StylesBase):
self._base_styles = base self._base_styles = base
self._inline_styles = inline_styles self._inline_styles = inline_styles
self._animate: BoundAnimator | None = None self._animate: BoundAnimator | None = None
self._updates: int = 0
self._rich_style: tuple[int, Style] | None = None
self._gutter: tuple[int, Spacing] | None = None
@property
def _cache_key(self) -> int:
"""A key key, that changes when any style is changed.
Returns:
int: An opaque integer.
"""
return self._updates + self._base_styles._updates + self._inline_styles._updates
@property @property
def base(self) -> Styles: def base(self) -> Styles:
@@ -946,6 +963,21 @@ class RenderStyles(StylesBase):
assert self.node is not None assert self.node is not None
return self.node.rich_style return self.node.rich_style
@property
def gutter(self) -> Spacing:
"""Get space around widget.
Returns:
Spacing: Space around widget content.
"""
if self._gutter is not None:
cache_key, gutter = self._gutter
if cache_key == self._updates:
return gutter
gutter = self.padding + self.border.spacing
self._gutter = (self._cache_key, gutter)
return gutter
def animate( def animate(
self, self,
attribute: str, attribute: str,
@@ -972,6 +1004,7 @@ class RenderStyles(StylesBase):
""" """
if self._animate is None: if self._animate is None:
assert self.node is not None
self._animate = self.node.app.animator.bind(self) self._animate = self.node.app.animator.bind(self)
assert self._animate is not None assert self._animate is not None
self._animate( self._animate(
@@ -1003,16 +1036,19 @@ class RenderStyles(StylesBase):
def merge_rules(self, rules: RulesMap) -> None: def merge_rules(self, rules: RulesMap) -> None:
self._inline_styles.merge_rules(rules) self._inline_styles.merge_rules(rules)
self._updates += 1
def reset(self) -> None: def reset(self) -> None:
"""Reset the rules to initial state.""" """Reset the rules to initial state."""
self._inline_styles.reset() self._inline_styles.reset()
self._updates += 1
def has_rule(self, rule: str) -> bool: def has_rule(self, rule: str) -> bool:
"""Check if a rule has been set.""" """Check if a rule has been set."""
return self._inline_styles.has_rule(rule) or self._base_styles.has_rule(rule) return self._inline_styles.has_rule(rule) or self._base_styles.has_rule(rule)
def set_rule(self, rule: str, value: object | None) -> bool: def set_rule(self, rule: str, value: object | None) -> bool:
self._updates += 1
return self._inline_styles.set_rule(rule, value) return self._inline_styles.set_rule(rule, value)
def get_rule(self, rule: str, default: object = None) -> object: def get_rule(self, rule: str, default: object = None) -> object:
@@ -1022,6 +1058,7 @@ class RenderStyles(StylesBase):
def clear_rule(self, rule_name: str) -> bool: def clear_rule(self, rule_name: str) -> bool:
"""Clear a rule (from inline).""" """Clear a rule (from inline)."""
self._updates += 1
return self._inline_styles.clear_rule(rule_name) return self._inline_styles.clear_rule(rule_name)
def get_rules(self) -> RulesMap: def get_rules(self) -> RulesMap: