|
| 1 | +from dataclasses import dataclass |
1 | 2 | from pathlib import Path |
2 | 3 | from typing import Any |
3 | 4 | from typing import Dict |
4 | 5 | from typing import List |
5 | 6 |
|
6 | 7 | from ...exceptions import InvalidDefinition |
| 8 | +from ...statemachine import StateMachine |
7 | 9 | from .. import StateDefinition |
8 | 10 | from .. import TransitionDict |
9 | 11 | from .. import TransitionsDict |
|
17 | 19 | from .schema import Transition |
18 | 20 |
|
19 | 21 |
|
| 22 | +class IOProcessor: |
| 23 | + def __init__(self, processor: "SCXMLProcessor", machine: StateMachine): |
| 24 | + self.scxml_processor = processor |
| 25 | + self.machine = machine |
| 26 | + |
| 27 | + def __getitem__(self, name: str): |
| 28 | + return self |
| 29 | + |
| 30 | + @property |
| 31 | + def location(self): |
| 32 | + return self.machine.name |
| 33 | + |
| 34 | + |
| 35 | +@dataclass |
| 36 | +class SessionData: |
| 37 | + machine: StateMachine |
| 38 | + processor: IOProcessor |
| 39 | + |
| 40 | + def __post_init__(self): |
| 41 | + self.session_id = f"{self.machine.name}:{id(self.machine)}" |
| 42 | + |
| 43 | + |
20 | 44 | class SCXMLProcessor: |
21 | 45 | def __init__(self): |
22 | 46 | self.scs = {} |
23 | | - self.sessions = {} |
| 47 | + self.sessions: Dict[str, SessionData] = {} |
24 | 48 | self._ioprocessors = { |
25 | 49 | "http://www.w3.org/TR/scxml/#SCXMLEventProcessor": self, |
26 | 50 | "scxml": self, |
@@ -54,15 +78,23 @@ def _prepare_event(self, *args, **kwargs): |
54 | 78 | machine_weakref = getattr(machine, "__weakref__", None) |
55 | 79 | if machine_weakref: |
56 | 80 | machine = machine_weakref() |
57 | | - session_id = f"{machine.name}:{id(machine)}" |
| 81 | + |
| 82 | + session_data = self._get_session(machine) |
58 | 83 |
|
59 | 84 | return { |
60 | 85 | "_name": machine.name, |
61 | | - "_sessionid": session_id, |
62 | | - "_ioprocessors": self.wrap(**kwargs), |
| 86 | + "_sessionid": session_data.session_id, |
| 87 | + "_ioprocessors": session_data.processor, |
63 | 88 | "_event": EventDataWrapper(kwargs["event_data"]), |
64 | 89 | } |
65 | 90 |
|
| 91 | + def _get_session(self, machine: StateMachine): |
| 92 | + if machine.name not in self.sessions: |
| 93 | + self.sessions[machine.name] = SessionData( |
| 94 | + processor=IOProcessor(self, machine=machine), machine=machine |
| 95 | + ) |
| 96 | + return self.sessions[machine.name] |
| 97 | + |
66 | 98 | def _process_states(self, states: Dict[str, State]) -> Dict[str, StateDefinition]: |
67 | 99 | states_dict: Dict[str, StateDefinition] = {} |
68 | 100 | for state_id, state in states.items(): |
@@ -139,21 +171,4 @@ def start(self, **kwargs): |
139 | 171 | kwargs["enable_self_transition_entries"] = True |
140 | 172 | self.root_cls = next(iter(self.scs.values())) |
141 | 173 | self.root = self.root_cls(**kwargs) |
142 | | - self.sessions[self.root.name] = self.root |
143 | 174 | return self.root |
144 | | - |
145 | | - def wrap(self, **kwargs): |
146 | | - return IOProcessor(self, **kwargs) |
147 | | - |
148 | | - |
149 | | -class IOProcessor: |
150 | | - def __init__(self, processor: "SCXMLProcessor", **kwargs): |
151 | | - self.scxml_processor = processor |
152 | | - self.machine = kwargs["machine"] |
153 | | - |
154 | | - def __getitem__(self, name: str): |
155 | | - return self |
156 | | - |
157 | | - @property |
158 | | - def location(self): |
159 | | - return self.machine.name |
|
0 commit comments