Move unculled zones out of MapModel.

This commit is contained in:
Dan Albert 2022-02-22 19:37:43 -08:00
parent 95836a217c
commit 1c543666b5
8 changed files with 45 additions and 70 deletions

View File

@ -18,6 +18,7 @@ class GameUpdateEventsJs(BaseModel):
new_combats: list[FrozenCombatJs] = []
updated_combats: list[FrozenCombatJs] = []
navmesh_updates: set[bool] = set()
unculled_zones_updated: bool = False
@classmethod
def from_events(cls, events: GameUpdateEvents, game: Game) -> GameUpdateEventsJs:
@ -33,4 +34,5 @@ class GameUpdateEventsJs(BaseModel):
for c in events.updated_combats
],
navmesh_updates=events.navmesh_updates,
unculled_zones_updated=events.unculled_zones_updated,
)

View File

@ -1,5 +1,6 @@
from __future__ import annotations
from dcs.mapping import LatLng
from pydantic import BaseModel
from game.server.leaflet import LeafletPoly
@ -9,3 +10,8 @@ class MapZonesJs(BaseModel):
inclusion: list[LeafletPoly]
exclusion: list[LeafletPoly]
sea: list[LeafletPoly]
class UnculledZoneJs(BaseModel):
position: LatLng
radius: float

View File

@ -2,14 +2,14 @@ from fastapi import APIRouter, Depends, HTTPException, status
from game import Game
from game.server import GameContext
from .models import MapZonesJs
from .models import MapZonesJs, UnculledZoneJs
from ..leaflet import ShapelyUtil
router: APIRouter = APIRouter(prefix="/map-zones")
@router.get("/")
def get(game: Game = Depends(GameContext.get)) -> MapZonesJs:
@router.get("/terrain")
def get_terrain(game: Game = Depends(GameContext.get)) -> MapZonesJs:
zones = game.theater.landmap
if zones is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
@ -19,3 +19,13 @@ def get(game: Game = Depends(GameContext.get)) -> MapZonesJs:
exclusion=ShapelyUtil.polys_to_leaflet(zones.exclusion_zones, game.theater),
sea=ShapelyUtil.polys_to_leaflet(zones.sea_zones, game.theater),
)
@router.get("/unculled")
def get_unculled_zones(game: Game = Depends(GameContext.get)) -> list[UnculledZoneJs]:
return [
UnculledZoneJs(
position=zone.latlng(), radius=game.settings.perf_culling_distance * 1000
)
for zone in game.get_culling_zones()
]

View File

@ -16,6 +16,7 @@ class GameUpdateEvents:
self.updated_combats: list[FrozenCombat] = []
self.updated_flights: list[tuple[Flight, Point]] = []
self.navmesh_updates: set[bool] = set()
self.unculled_zones_updated: bool = False
@property
def empty(self) -> bool:
@ -26,6 +27,7 @@ class GameUpdateEvents:
self.updated_combats,
self.updated_flights,
self.navmesh_updates,
self.unculled_zones_updated,
]
)
@ -43,3 +45,6 @@ class GameUpdateEvents:
def update_navmesh(self, player: bool) -> None:
self.navmesh_updates.add(player)
def update_unculled_zones(self) -> None:
self.unculled_zones_updated = True

View File

@ -16,12 +16,13 @@ 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
from game.squadrons.squadron import Pilot, Squadron
from game.theater.missiontarget import MissionTarget
from game.transfers import PendingTransfers, TransferOrder
from game.ato.traveltime import TotEstimator
from qt_ui.simcontroller import SimController
from qt_ui.uiconstants import AIRCRAFT_ICONS
@ -279,7 +280,9 @@ class AtoModel(QAbstractListModel):
def on_packages_changed(self) -> None:
if self.game is not None:
self.game.compute_unculled_zones()
self.packages_changed.emit()
events = GameUpdateEvents()
events.update_unculled_zones()
EventStream.put_nowait(events)
def package_at_index(self, index: QModelIndex) -> Package:
"""Returns the package at the given index."""

View File

@ -23,7 +23,6 @@ from .groundobjectjs import GroundObjectJs
from .supplyroutejs import SupplyRouteJs
from .threatzonecontainerjs import ThreatZoneContainerJs
from .threatzonesjs import ThreatZonesJs
from .unculledzonejs import UnculledZone
# **EVERY PROPERTY NEEDS A NOTIFY SIGNAL**
@ -53,7 +52,6 @@ class MapModel(QObject):
flightsChanged = Signal()
frontLinesChanged = Signal()
threatZonesChanged = Signal()
unculledZonesChanged = Signal()
selectedFlightChanged = Signal(str)
def __init__(self, game_model: GameModel) -> None:
@ -68,7 +66,6 @@ class MapModel(QObject):
self._threat_zones = ThreatZoneContainerJs(
ThreatZonesJs.empty(), ThreatZonesJs.empty()
)
self._unculled_zones = []
self._selected_flight_index: Optional[Tuple[int, int]] = None
GameUpdateSignal.get_instance().game_loaded.connect(self.on_game_load)
@ -79,12 +76,6 @@ class MapModel(QObject):
GameUpdateSignal.get_instance().flight_selection_changed.connect(
self.set_flight_selection
)
self.game_model.ato_model_for(True).packages_changed.connect(
self.on_package_change
),
self.game_model.ato_model_for(False).packages_changed.connect(
self.on_package_change
),
self.reset()
def clear(self) -> None:
@ -96,7 +87,6 @@ class MapModel(QObject):
self._threat_zones = ThreatZoneContainerJs(
ThreatZonesJs.empty(), ThreatZonesJs.empty()
)
self._unculled_zones = []
self.cleared.emit()
def set_package_selection(self, index: int) -> None:
@ -160,7 +150,6 @@ class MapModel(QObject):
self.reset_atos()
self.reset_front_lines()
self.reset_threat_zones()
self.reset_unculled_zones()
def on_game_load(self, game: Optional[Game]) -> None:
if game is not None:
@ -292,17 +281,6 @@ class MapModel(QObject):
def threatZones(self) -> ThreatZoneContainerJs:
return self._threat_zones
def on_package_change(self) -> None:
self.reset_unculled_zones()
def reset_unculled_zones(self) -> None:
self._unculled_zones = list(UnculledZone.each_from_game(self.game))
self.unculledZonesChanged.emit()
@Property(list, notify=unculledZonesChanged)
def unculledZones(self) -> list[UnculledZone]:
return self._unculled_zones
@property
def game(self) -> Game:
if self.game_model.game is None:

View File

@ -1,33 +0,0 @@
from __future__ import annotations
from typing import Iterator
from PySide2.QtCore import Property, QObject, Signal
from game import Game
from game.server.leaflet import LeafletLatLon
class UnculledZone(QObject):
positionChanged = Signal()
radiusChanged = Signal()
def __init__(self, position: LeafletLatLon, radius: float) -> None:
super().__init__()
self._position = position
self._radius = radius
@Property(list, notify=positionChanged)
def position(self) -> LeafletLatLon:
return self._position
@Property(float, notify=radiusChanged)
def radius(self) -> float:
return self._radius
@classmethod
def each_from_game(cls, game: Game) -> Iterator[UnculledZone]:
for zone in game.get_culling_zones():
yield UnculledZone(
zone.latlng().as_list(), game.settings.perf_culling_distance * 1000
)

View File

@ -385,7 +385,6 @@ new QWebChannel(qt.webChannelTransport, function (channel) {
game.flightsChanged.connect(drawAircraft);
game.threatZonesChanged.connect(drawThreatZones);
game.mapZonesChanged.connect(drawMapZones);
game.unculledZonesChanged.connect(drawUnculledZones);
game.selectedFlightChanged.connect(updateSelectedFlight);
});
@ -402,6 +401,9 @@ function handleStreamedEvents(events) {
for (const player of events.navmesh_updates) {
drawNavmesh(player);
}
if (events.unculled_zones_updated) {
drawUnculledZones();
}
}
function recenterMap(center) {
@ -1124,7 +1126,7 @@ function drawMapZones() {
inclusionZones.clearLayers();
exclusionZones.clearLayers();
getJson("/map-zones").then((zones) => {
getJson("/map-zones/terrain").then((zones) => {
for (const zone of zones.sea) {
L.polygon(zone, {
color: "#344455",
@ -1157,7 +1159,8 @@ function drawMapZones() {
function drawUnculledZones() {
unculledZones.clearLayers();
for (const zone of game.unculledZones) {
getJson("/map-zones/unculled").then((zones) => {
for (const zone of zones) {
L.circle(zone.position, {
radius: zone.radius,
color: "#b4ff8c",
@ -1165,6 +1168,7 @@ function drawUnculledZones() {
interactive: false,
}).addTo(unculledZones);
}
});
}
function drawIpZones(id) {