"""The simulation engine of pooltool"""from__future__importannotationsimportattrsfrompooltool.evolution.event_based.detectimportEventDetectorfrompooltool.physics.dimensionalityimportSKIP_DIMENSION,Dimfrompooltool.physics.resolveimportResolver
[docs]@attrs.defineclassSimulationEngine:"""A bundle of physics strategies used by the simulator. Holds the resolver (pluggable per-event-type collision strategies) and the detector. The simulator is handed an instance and routes work to its components. Attributes: is_3d: Whether the simulation supports the airborne motion state and ball-table events. Validated at construction against the dimensionality capability (``dim``) of every bundled strategy in ``resolver``. resolver: Pluggable bundle of event-resolution strategies. Each strategy declares a ``Dim`` capability (except ``ball_table``). detector: Canonical event detector. Not constructor-passable — built from ``is_3d`` automatically. """is_3d:bool=Falseresolver:Resolver=attrs.field(factory=Resolver.default)detector:EventDetector=attrs.field(init=False)@detector.default# type: ignoredef_default_detector(self)->EventDetector:returnEventDetector(is_3d=self.is_3d)def__attrs_post_init__(self)->None:self._validate_dimensionality()def_validate_dimensionality(self)->None:required=Dim.THREEifself.is_3delseDim.TWOforfieldinattrs.fields(type(self.resolver)):iffield.nameinSKIP_DIMENSION:continuestrategy=getattr(self.resolver,field.name)ifnotattrs.has(type(strategy)):continueifnothasattr(strategy,"dim"):raiseAttributeError(f"Resolver.{field.name} "f"({type(strategy).__name__}) is missing required "f"'dim' attribute")ifstrategy.dimnotin(required,Dim.BOTH):raiseValueError(f"Resolver.{field.name} "f"({type(strategy).__name__}) has dim={strategy.dim}, "f"incompatible with is_3d={self.is_3d}; "f"expected {required} or {Dim.BOTH}")