Files
StarPilot/openpilot/starpilot/vehicle_startup.py
T

71 lines
2.4 KiB
Python

"""Generic lifetime holder for a car-owned prepublication startup transaction."""
import threading
class VehicleStartupOwner:
def __init__(self, owner=None):
# Explicit-CI callers may supply an already prepared car-owned decision.
self.owner = owner
self.send_lock = threading.Lock()
def prepare(self, cp, interface, callbacks, *, requested, admission, defer_until_controls=False):
factory = getattr(interface, 'startup_owner', None)
if factory is None:
return cp
recv, send = callbacks
def locked_send(frames):
with self.send_lock:
send(frames)
owner = factory(cp, (recv, locked_send), requested=requested)
if owner is None:
return cp
# Register before any ECU request so a partially constructed Card can close.
self.owner = owner
prepare = getattr(owner, 'prepare_when_controls_ready', owner.prepare) if defer_until_controls else owner.prepare
return prepare(admission=admission)
def configure(self, ci):
required = getattr(type(ci), 'startup_required', None)
if required is not None and required(ci.CP):
matches = getattr(self.owner, 'prepared_for', None)
if matches is None or not matches(ci.CP):
raise RuntimeError('Car interface requires a matching prepared startup owner')
if self.owner is not None:
self.owner.configure(ci)
def finalize_aol_configuration(self, ci):
finalize = getattr(self.owner, 'finalize_aol_configuration', None)
if finalize is not None:
finalize(ci)
def seal_publication(self):
if self.owner is not None:
self.owner.seal_publication()
def check(self):
if self.owner is not None:
self.owner.check()
def after_state(self, **context):
if self.owner is not None:
self.owner.after_state(**context)
def consume_cruise_resume(self):
return self.owner.consume_cruise_resume() if self.owner is not None else None
def before_control(self, *, configured, ci, now_ns, control_current):
return self.owner is None or self.owner.before_control(
configured=configured, sources_current=self.owner.sources_current(ci, now_ns), control_current=control_current)
def maintain(self, *, configured):
if self.owner is not None:
self.owner.maintain(configured=configured)
def sent(self, frames, *, valid):
if self.owner is not None:
self.owner.sent(frames, valid=valid)
def close(self):
if self.owner is not None:
self.owner.close()