From 71f68b31035f4c50f9b37101ae2ca3c2270319eb Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Fri, 2 Sep 2022 23:00:08 -0700 Subject: [PATCH] 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. --- game/ato/flightplans/flightplan.py | 4 ++-- game/ato/flightstate/uninitialized.py | 4 +--- game/ato/traveltime.py | 20 ++----------------- game/sim/aircraftsimulation.py | 4 +--- qt_ui/models.py | 7 +++---- qt_ui/widgets/QTopPanel.py | 5 ++--- qt_ui/windows/mission/QFlightItem.py | 9 +++------ qt_ui/windows/mission/QPlannedFlightsView.py | 5 ++--- .../flight/settings/FlightAirfieldDisplay.py | 5 +---- 9 files changed, 17 insertions(+), 46 deletions(-) diff --git a/game/ato/flightplans/flightplan.py b/game/ato/flightplans/flightplan.py index c02a8848..fcb1e12a 100644 --- a/game/ato/flightplans/flightplan.py +++ b/game/ato/flightplans/flightplan.py @@ -253,8 +253,8 @@ class FlightPlan(ABC, Generic[LayoutT]): def takeoff_time(self) -> timedelta: return self.tot - self._travel_time_to_waypoint(self.tot_waypoint) - def startup_time(self) -> timedelta | None: - start_time: timedelta = ( + def startup_time(self) -> timedelta: + start_time = ( self.takeoff_time() - self.estimate_startup() - self.estimate_ground_ops() ) diff --git a/game/ato/flightstate/uninitialized.py b/game/ato/flightstate/uninitialized.py index 32a12a80..bc75490d 100644 --- a/game/ato/flightstate/uninitialized.py +++ b/game/ato/flightstate/uninitialized.py @@ -5,7 +5,6 @@ from typing import TYPE_CHECKING from dcs import Point -from game.ato.traveltime import TotEstimator from .flightstate import FlightState from ..starttype import StartType @@ -36,8 +35,7 @@ class Uninitialized(FlightState): @property def description(self) -> str: - estimator = TotEstimator(self.flight.package) - delay = estimator.mission_start_time(self.flight) + delay = self.flight.flight_plan.startup_time() if self.flight.start_type is StartType.COLD: action = "Starting up" elif self.flight.start_type is StartType.WARM: diff --git a/game/ato/traveltime.py b/game/ato/traveltime.py index 727c193e..79d73cdf 100644 --- a/game/ato/traveltime.py +++ b/game/ato/traveltime.py @@ -1,6 +1,5 @@ from __future__ import annotations -import logging import math from datetime import timedelta from typing import TYPE_CHECKING @@ -57,15 +56,6 @@ class TotEstimator: def __init__(self, package: Package) -> None: 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: if not self.package.flights: return timedelta(0) @@ -83,9 +73,9 @@ class TotEstimator: @staticmethod 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 their ingress point. @@ -106,10 +96,4 @@ class TotEstimator: time = flight.flight_plan.startup_time() finally: 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 diff --git a/game/sim/aircraftsimulation.py b/game/sim/aircraftsimulation.py index e83e9da2..c0550e85 100644 --- a/game/sim/aircraftsimulation.py +++ b/game/sim/aircraftsimulation.py @@ -16,7 +16,6 @@ from game.ato.flightstate import ( WaitingForStart, ) from game.ato.starttype import StartType -from game.ato.traveltime import TotEstimator from .combat import CombatInitiator, FrozenCombat from .simulationresults import SimulationResults @@ -74,8 +73,7 @@ class AircraftSimulation: def set_initial_flight_states(self) -> None: now = self.game.conditions.start_time for flight in self.iter_flights(): - estimator = TotEstimator(flight.package) - start_time = estimator.mission_start_time(flight) + start_time = flight.flight_plan.startup_time() if start_time <= timedelta(): self.set_active_flight_state(flight, now) else: diff --git a/qt_ui/models.py b/qt_ui/models.py index 3f2420db..51c2c87b 100644 --- a/qt_ui/models.py +++ b/qt_ui/models.py @@ -16,7 +16,6 @@ from game.ato.airtaaskingorder import AirTaskingOrder from game.ato.flight import Flight from game.ato.flighttype import FlightType from game.ato.package import Package -from game.ato.traveltime import TotEstimator from game.game import Game from game.server import EventStream from game.sim.gameupdateevents import GameUpdateEvents @@ -136,11 +135,11 @@ class PackageModel(QAbstractListModel): return flight 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.""" - estimator = TotEstimator(self.package) 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 return f"{flight} from {origin} in {delay}" diff --git a/qt_ui/widgets/QTopPanel.py b/qt_ui/widgets/QTopPanel.py index 28f7d1ea..d1ce2586 100644 --- a/qt_ui/widgets/QTopPanel.py +++ b/qt_ui/widgets/QTopPanel.py @@ -12,9 +12,9 @@ from PySide2.QtWidgets import ( import qt_ui.uiconstants as CONST from game import Game, persistency from game.ato.package import Package +from game.ato.traveltime import TotEstimator from game.profiling import logged_duration from game.utils import meters -from game.ato.traveltime import TotEstimator from qt_ui.models import GameModel from qt_ui.simcontroller import SimController from qt_ui.widgets.QBudgetBox import QBudgetBox @@ -156,9 +156,8 @@ class QTopPanel(QFrame): for package in self.game_model.ato_model.ato.packages: if not package.flights: continue - estimator = TotEstimator(package) 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) break return packages diff --git a/qt_ui/windows/mission/QFlightItem.py b/qt_ui/windows/mission/QFlightItem.py index b6380397..2a5f9a5d 100644 --- a/qt_ui/windows/mission/QFlightItem.py +++ b/qt_ui/windows/mission/QFlightItem.py @@ -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.traveltime import TotEstimator +from game.ato.package import Package from qt_ui.uiconstants import AIRCRAFT_ICONS @@ -17,6 +16,4 @@ class QFlightItem(QStandardItem): icon = QIcon((AIRCRAFT_ICONS[self.flight.unit_type.dcs_id])) self.setIcon(icon) self.setEditable(False) - estimator = TotEstimator(self.package) - delay = estimator.mission_start_time(flight) - self.setText(f"{flight} in {delay}") + self.setText(f"{flight} in {flight.flight_plan.startup_time()}") diff --git a/qt_ui/windows/mission/QPlannedFlightsView.py b/qt_ui/windows/mission/QPlannedFlightsView.py index c5579e16..f736a5ed 100644 --- a/qt_ui/windows/mission/QPlannedFlightsView.py +++ b/qt_ui/windows/mission/QPlannedFlightsView.py @@ -4,10 +4,9 @@ from PySide2.QtCore import QItemSelectionModel, QSize from PySide2.QtGui import QStandardItemModel from PySide2.QtWidgets import QAbstractItemView, QListView +from game.theater.controlpoint import ControlPoint from qt_ui.models import GameModel from qt_ui.windows.mission.QFlightItem import QFlightItem -from game.theater.controlpoint import ControlPoint -from game.ato.traveltime import TotEstimator class QPlannedFlightsView(QListView): @@ -52,4 +51,4 @@ class QPlannedFlightsView(QListView): @staticmethod 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() diff --git a/qt_ui/windows/mission/flight/settings/FlightAirfieldDisplay.py b/qt_ui/windows/mission/flight/settings/FlightAirfieldDisplay.py index 618f2286..a0a41586 100644 --- a/qt_ui/windows/mission/flight/settings/FlightAirfieldDisplay.py +++ b/qt_ui/windows/mission/flight/settings/FlightAirfieldDisplay.py @@ -5,7 +5,6 @@ from PySide2.QtWidgets import QGroupBox, QLabel, QMessageBox, QVBoxLayout from game import Game from game.ato.flight import Flight from game.ato.flightplans.planningerror import PlanningError -from game.ato.traveltime import TotEstimator from qt_ui.models import PackageModel from qt_ui.widgets.QLabeledWidget import QLabeledWidget 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 # is an invalid state for calling anything in TotEstimator. return - estimator = TotEstimator(self.package_model.package) - delay = estimator.mission_start_time(self.flight) - self.departure_time.setText(f"At T+{delay}") + self.departure_time.setText(f"At T+{self.flight.flight_plan.startup_time()}") def set_divert(self, index: int) -> None: old_divert = self.flight.divert