|
@@ -257,6 +257,17 @@ class State(Base, ABC):
|
|
|
field.required = False
|
|
|
field.default = default_value
|
|
|
|
|
|
+ def getattr(self, name: str) -> Any:
|
|
|
+ """Get a non-prop attribute.
|
|
|
+
|
|
|
+ Args:
|
|
|
+ name: The name of the attribute.
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ The attribute.
|
|
|
+ """
|
|
|
+ return super().__getattribute__(name)
|
|
|
+
|
|
|
def __getattribute__(self, name: str) -> Any:
|
|
|
"""Get the attribute.
|
|
|
|
|
@@ -287,17 +298,20 @@ class State(Base, ABC):
|
|
|
name: The name of the attribute.
|
|
|
value: The value of the attribute.
|
|
|
"""
|
|
|
- if name != "inherited_vars" and name in self.inherited_vars:
|
|
|
- setattr(self.parent_state, name, value)
|
|
|
+ # NOTE: We use super().__getattribute__ for performance reasons.
|
|
|
+ if name != "inherited_vars" and name in super().__getattribute__(
|
|
|
+ "inherited_vars"
|
|
|
+ ):
|
|
|
+ setattr(super().__getattribute__("parent_state"), name, value)
|
|
|
return
|
|
|
|
|
|
# Set the attribute.
|
|
|
super().__setattr__(name, value)
|
|
|
|
|
|
# Add the var to the dirty list.
|
|
|
- if name in self.vars:
|
|
|
- self.dirty_vars.add(name)
|
|
|
- self.mark_dirty()
|
|
|
+ if name in super().__getattribute__("vars"):
|
|
|
+ super().__getattribute__("dirty_vars").add(name)
|
|
|
+ super().__getattribute__("mark_dirty")()
|
|
|
|
|
|
def reset(self):
|
|
|
"""Reset all the base vars to their default values."""
|
|
@@ -344,10 +358,11 @@ class State(Base, ABC):
|
|
|
Returns:
|
|
|
The state update after processing the event.
|
|
|
"""
|
|
|
+ # NOTE: We use super().__getattribute__ for performance reasons.
|
|
|
# Get the event handler.
|
|
|
path = event.name.split(".")
|
|
|
path, name = path[:-1], path[-1]
|
|
|
- substate = self.get_substate(path)
|
|
|
+ substate = super().__getattribute__("get_substate")(path)
|
|
|
handler = getattr(substate, name)
|
|
|
|
|
|
# Process the event.
|
|
@@ -368,10 +383,10 @@ class State(Base, ABC):
|
|
|
events = utils.fix_events(events, event.token)
|
|
|
|
|
|
# Get the delta after processing the event.
|
|
|
- delta = self.get_delta()
|
|
|
+ delta = super().__getattribute__("get_delta")()
|
|
|
|
|
|
# Reset the dirty vars.
|
|
|
- self.clean()
|
|
|
+ super().__getattribute__("clean")()
|
|
|
|
|
|
# Return the state update.
|
|
|
return StateUpdate(delta=delta, events=events)
|
|
@@ -382,19 +397,22 @@ class State(Base, ABC):
|
|
|
Returns:
|
|
|
The delta for the state.
|
|
|
"""
|
|
|
+ # NOTE: We use super().__getattribute__ for performance reasons.
|
|
|
delta = {}
|
|
|
|
|
|
# Return the dirty vars, as well as all computed vars.
|
|
|
subdelta = {
|
|
|
prop: getattr(self, prop)
|
|
|
- for prop in self.dirty_vars | set(self.computed_vars.keys())
|
|
|
+ for prop in super().__getattribute__("dirty_vars")
|
|
|
+ | set(super().__getattribute__("computed_vars").keys())
|
|
|
}
|
|
|
if len(subdelta) > 0:
|
|
|
- delta[self.get_full_name()] = subdelta
|
|
|
+ delta[super().__getattribute__("get_full_name")()] = subdelta
|
|
|
|
|
|
# Recursively find the substate deltas.
|
|
|
- for substate in self.dirty_substates:
|
|
|
- delta.update(self.substates[substate].get_delta())
|
|
|
+ substates = super().__getattribute__("substates")
|
|
|
+ for substate in super().__getattribute__("dirty_substates"):
|
|
|
+ delta.update(substates[substate].getattr("get_delta")())
|
|
|
|
|
|
# Format the delta.
|
|
|
delta = utils.format_state(delta)
|
|
@@ -410,13 +428,14 @@ class State(Base, ABC):
|
|
|
|
|
|
def clean(self):
|
|
|
"""Reset the dirty vars."""
|
|
|
+ # NOTE: We use super().__getattribute__ for performance reasons.
|
|
|
# Recursively clean the substates.
|
|
|
- for substate in self.dirty_substates:
|
|
|
- self.substates[substate].clean()
|
|
|
+ for substate in super().__getattribute__("dirty_substates"):
|
|
|
+ super().__getattribute__("substates")[substate].getattr("clean")()
|
|
|
|
|
|
# Clean this state.
|
|
|
- self.dirty_vars = set()
|
|
|
- self.dirty_substates = set()
|
|
|
+ super().__setattr__("dirty_vars", set())
|
|
|
+ super().__setattr__("dirty_substates", set())
|
|
|
|
|
|
def dict(self, include_computed: bool = True, **kwargs) -> Dict[str, Any]:
|
|
|
"""Convert the object to a dictionary.
|