Simplify flight startup time calls.

We can always estimate a startup time now. Remove the nullability from
the result, cleanup the callsites, and eliminate
TotEstimator.mission_start_time since it no longer does anything useful.
This commit is contained in:
Dan Albert 2022-09-02 23:00:08 -07:00
parent d8486568b7
commit 71f68b3103
9 changed files with 17 additions and 46 deletions

View File

@ -253,8 +253,8 @@ class FlightPlan(ABC, Generic[LayoutT]):
def takeoff_time(self) -> timedelta: def takeoff_time(self) -> timedelta:
return self.tot - self._travel_time_to_waypoint(self.tot_waypoint) return self.tot - self._travel_time_to_waypoint(self.tot_waypoint)
def startup_time(self) -> timedelta | None: def startup_time(self) -> timedelta:
start_time: timedelta = ( start_time = (
self.takeoff_time() - self.estimate_startup() - self.estimate_ground_ops() self.takeoff_time() - self.estimate_startup() - self.estimate_ground_ops()
) )

View File

@ -5,7 +5,6 @@ from typing import TYPE_CHECKING
from dcs import Point from dcs import Point
from game.ato.traveltime import TotEstimator
from .flightstate import FlightState from .flightstate import FlightState
from ..starttype import StartType from ..starttype import StartType
@ -36,8 +35,7 @@ class Uninitialized(FlightState):
@property @property
def description(self) -> str: def description(self) -> str:
estimator = TotEstimator(self.flight.package) delay = self.flight.flight_plan.startup_time()
delay = estimator.mission_start_time(self.flight)
if self.flight.start_type is StartType.COLD: if self.flight.start_type is StartType.COLD:
action = "Starting up" action = "Starting up"
elif self.flight.start_type is StartType.WARM: elif self.flight.start_type is StartType.WARM:

View File

@ -1,6 +1,5 @@
from __future__ import annotations from __future__ import annotations
import logging
import math import math
from datetime import timedelta from datetime import timedelta
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
@ -57,15 +56,6 @@ class TotEstimator:
def __init__(self, package: Package) -> None: def __init__(self, package: Package) -> None:
self.package = package self.package = package
@staticmethod
def mission_start_time(flight: Flight) -> timedelta:
startup_time = flight.flight_plan.startup_time()
if startup_time is None:
# Could not determine takeoff time, probably due to a custom flight
# plan. Start immediately.
return timedelta()
return startup_time
def earliest_tot(self) -> timedelta: def earliest_tot(self) -> timedelta:
if not self.package.flights: if not self.package.flights:
return timedelta(0) return timedelta(0)
@ -83,9 +73,9 @@ class TotEstimator:
@staticmethod @staticmethod
def earliest_tot_for_flight(flight: Flight) -> timedelta: def earliest_tot_for_flight(flight: Flight) -> timedelta:
"""Estimate fastest time from mission start to the target position. """Estimate the fastest time from mission start to the target position.
For BARCAP flights, this is time to race track start. This ensures that For BARCAP flights, this is time to the racetrack start. This ensures that
they are on station at the same time any other package members reach they are on station at the same time any other package members reach
their ingress point. their ingress point.
@ -106,10 +96,4 @@ class TotEstimator:
time = flight.flight_plan.startup_time() time = flight.flight_plan.startup_time()
finally: finally:
flight.package.time_over_target = orig_tot flight.package.time_over_target = orig_tot
if time is None:
logging.warning(f"Cannot estimate TOT for {flight}")
# Return 0 so this flight's travel time does not affect the rest
# of the package.
return timedelta()
return -time return -time

View File

@ -16,7 +16,6 @@ from game.ato.flightstate import (
WaitingForStart, WaitingForStart,
) )
from game.ato.starttype import StartType from game.ato.starttype import StartType
from game.ato.traveltime import TotEstimator
from .combat import CombatInitiator, FrozenCombat from .combat import CombatInitiator, FrozenCombat
from .simulationresults import SimulationResults from .simulationresults import SimulationResults
@ -74,8 +73,7 @@ class AircraftSimulation:
def set_initial_flight_states(self) -> None: def set_initial_flight_states(self) -> None:
now = self.game.conditions.start_time now = self.game.conditions.start_time
for flight in self.iter_flights(): for flight in self.iter_flights():
estimator = TotEstimator(flight.package) start_time = flight.flight_plan.startup_time()
start_time = estimator.mission_start_time(flight)
if start_time <= timedelta(): if start_time <= timedelta():
self.set_active_flight_state(flight, now) self.set_active_flight_state(flight, now)
else: else:

View File

@ -16,7 +16,6 @@ from game.ato.airtaaskingorder import AirTaskingOrder
from game.ato.flight import Flight from game.ato.flight import Flight
from game.ato.flighttype import FlightType from game.ato.flighttype import FlightType
from game.ato.package import Package from game.ato.package import Package
from game.ato.traveltime import TotEstimator
from game.game import Game from game.game import Game
from game.server import EventStream from game.server import EventStream
from game.sim.gameupdateevents import GameUpdateEvents from game.sim.gameupdateevents import GameUpdateEvents
@ -136,11 +135,11 @@ class PackageModel(QAbstractListModel):
return flight return flight
return None return None
def text_for_flight(self, flight: Flight) -> str: @staticmethod
def text_for_flight(flight: Flight) -> str:
"""Returns the text that should be displayed for the flight.""" """Returns the text that should be displayed for the flight."""
estimator = TotEstimator(self.package)
delay = datetime.timedelta( delay = datetime.timedelta(
seconds=int(estimator.mission_start_time(flight).total_seconds()) seconds=int(flight.flight_plan.startup_time().total_seconds())
) )
origin = flight.from_cp.name origin = flight.from_cp.name
return f"{flight} from {origin} in {delay}" return f"{flight} from {origin} in {delay}"

View File

@ -12,9 +12,9 @@ from PySide2.QtWidgets import (
import qt_ui.uiconstants as CONST import qt_ui.uiconstants as CONST
from game import Game, persistency from game import Game, persistency
from game.ato.package import Package from game.ato.package import Package
from game.ato.traveltime import TotEstimator
from game.profiling import logged_duration from game.profiling import logged_duration
from game.utils import meters from game.utils import meters
from game.ato.traveltime import TotEstimator
from qt_ui.models import GameModel from qt_ui.models import GameModel
from qt_ui.simcontroller import SimController from qt_ui.simcontroller import SimController
from qt_ui.widgets.QBudgetBox import QBudgetBox from qt_ui.widgets.QBudgetBox import QBudgetBox
@ -156,9 +156,8 @@ class QTopPanel(QFrame):
for package in self.game_model.ato_model.ato.packages: for package in self.game_model.ato_model.ato.packages:
if not package.flights: if not package.flights:
continue continue
estimator = TotEstimator(package)
for flight in package.flights: for flight in package.flights:
if estimator.mission_start_time(flight).total_seconds() < 0: if flight.flight_plan.startup_time().total_seconds() < 0:
packages.append(package) packages.append(package)
break break
return packages return packages

View File

@ -1,8 +1,7 @@
from PySide2.QtGui import QStandardItem, QIcon from PySide2.QtGui import QIcon, QStandardItem
from game.ato.package import Package
from game.ato.flight import Flight from game.ato.flight import Flight
from game.ato.traveltime import TotEstimator from game.ato.package import Package
from qt_ui.uiconstants import AIRCRAFT_ICONS from qt_ui.uiconstants import AIRCRAFT_ICONS
@ -17,6 +16,4 @@ class QFlightItem(QStandardItem):
icon = QIcon((AIRCRAFT_ICONS[self.flight.unit_type.dcs_id])) icon = QIcon((AIRCRAFT_ICONS[self.flight.unit_type.dcs_id]))
self.setIcon(icon) self.setIcon(icon)
self.setEditable(False) self.setEditable(False)
estimator = TotEstimator(self.package) self.setText(f"{flight} in {flight.flight_plan.startup_time()}")
delay = estimator.mission_start_time(flight)
self.setText(f"{flight} in {delay}")

View File

@ -4,10 +4,9 @@ from PySide2.QtCore import QItemSelectionModel, QSize
from PySide2.QtGui import QStandardItemModel from PySide2.QtGui import QStandardItemModel
from PySide2.QtWidgets import QAbstractItemView, QListView from PySide2.QtWidgets import QAbstractItemView, QListView
from game.theater.controlpoint import ControlPoint
from qt_ui.models import GameModel from qt_ui.models import GameModel
from qt_ui.windows.mission.QFlightItem import QFlightItem from qt_ui.windows.mission.QFlightItem import QFlightItem
from game.theater.controlpoint import ControlPoint
from game.ato.traveltime import TotEstimator
class QPlannedFlightsView(QListView): class QPlannedFlightsView(QListView):
@ -52,4 +51,4 @@ class QPlannedFlightsView(QListView):
@staticmethod @staticmethod
def mission_start_for_flight(flight_item: QFlightItem) -> timedelta: def mission_start_for_flight(flight_item: QFlightItem) -> timedelta:
return TotEstimator(flight_item.package).mission_start_time(flight_item.flight) return flight_item.flight.flight_plan.startup_time()

View File

@ -5,7 +5,6 @@ from PySide2.QtWidgets import QGroupBox, QLabel, QMessageBox, QVBoxLayout
from game import Game from game import Game
from game.ato.flight import Flight from game.ato.flight import Flight
from game.ato.flightplans.planningerror import PlanningError from game.ato.flightplans.planningerror import PlanningError
from game.ato.traveltime import TotEstimator
from qt_ui.models import PackageModel from qt_ui.models import PackageModel
from qt_ui.widgets.QLabeledWidget import QLabeledWidget from qt_ui.widgets.QLabeledWidget import QLabeledWidget
from qt_ui.widgets.combos.QArrivalAirfieldSelector import QArrivalAirfieldSelector from qt_ui.widgets.combos.QArrivalAirfieldSelector import QArrivalAirfieldSelector
@ -58,9 +57,7 @@ class FlightAirfieldDisplay(QGroupBox):
# handler may be called for a flight whose package has been canceled, which # handler may be called for a flight whose package has been canceled, which
# is an invalid state for calling anything in TotEstimator. # is an invalid state for calling anything in TotEstimator.
return return
estimator = TotEstimator(self.package_model.package) self.departure_time.setText(f"At T+{self.flight.flight_plan.startup_time()}")
delay = estimator.mission_start_time(self.flight)
self.departure_time.setText(f"At T+{delay}")
def set_divert(self, index: int) -> None: def set_divert(self, index: int) -> None:
old_divert = self.flight.divert old_divert = self.flight.divert