Add tests for LaserCodeRegistry, clean up.

* Store a deque rather than an iterator so it can be pickled
* Remove mangling from staticmethod (and rename now that it's no longer
  a generator)
* Rename "get" to "alloc" to make the mutation clear
* Move to its own package (the changes I'm working on make this no
  longer mission generator specific)
* Remove useless exception class. It's never caught so the unique type
  isn't needed
This commit is contained in:
Dan Albert 2023-07-21 23:35:01 -07:00 committed by Raffson
parent 485229b92f
commit 279572ae09
No known key found for this signature in database
GPG Key ID: B0402B2C9B764D99
8 changed files with 29 additions and 22 deletions

View File

@ -0,0 +1 @@
from .lasercoderegistry import LaserCodeRegistry

View File

@ -1,30 +1,21 @@
from collections import deque
from typing import Iterator
class OutOfLaserCodesError(RuntimeError):
def __init__(self) -> None:
super().__init__(
f"All JTAC laser codes have been allocated. No available codes."
)
class LaserCodeRegistry:
def __init__(self) -> None:
self.allocated_codes: set[int] = set()
self.allocator: Iterator[int] = LaserCodeRegistry.__laser_code_generator()
self.available_codes = LaserCodeRegistry._all_valid_laser_codes()
def get_next_laser_code(self) -> int:
def alloc_laser_code(self) -> int:
try:
while (code := next(self.allocator)) in self.allocated_codes:
pass
code = self.available_codes.popleft()
self.allocated_codes.add(code)
return code
except StopIteration:
raise OutOfLaserCodesError
except IndexError:
raise RuntimeError("All laser codes have been allocated")
@staticmethod
def __laser_code_generator() -> Iterator[int]:
def _all_valid_laser_codes() -> deque[int]:
# Valid laser codes are as follows
# First digit is always 1
# Second digit is 5-7
@ -34,4 +25,4 @@ class LaserCodeRegistry:
# We start with the default of 1688 and wrap around when we reach the end
q.rotate(-q.index(1688))
return iter(q)
return q

View File

@ -21,7 +21,7 @@ from game.ato.flightstate import Completed, WaitingForStart
from game.ato.flighttype import FlightType
from game.ato.package import Package
from game.ato.starttype import StartType
from game.missiongenerator.lasercoderegistry import LaserCodeRegistry
from game.lasercodes import LaserCodeRegistry
from game.missiongenerator.missiondata import MissionData
from game.radio.radios import RadioRegistry
from game.radio.tacan import TacanRegistry

View File

@ -16,7 +16,7 @@ from dcs.unitgroup import FlyingGroup
from game.ato import Flight, FlightType
from game.callsigns import callsign_for_support_unit
from game.data.weapons import Pylon, WeaponType as WeaponTypeEnum
from game.missiongenerator.lasercoderegistry import LaserCodeRegistry
from game.lasercodes import LaserCodeRegistry
from game.missiongenerator.logisticsgenerator import LogisticsGenerator
from game.missiongenerator.missiondata import MissionData, AwacsInfo, TankerInfo
from game.radio.radios import RadioFrequency, RadioRegistry
@ -148,7 +148,7 @@ class FlightGroupConfigurator:
) -> None:
self.set_skill(unit, member)
if member.loadout.has_weapon_of_type(WeaponTypeEnum.TGP) and member.is_player:
laser_codes.append(self.laser_code_registry.get_next_laser_code())
laser_codes.append(self.laser_code_registry.alloc_laser_code())
else:
laser_codes.append(None)
settings = self.flight.coalition.game.settings

View File

@ -37,6 +37,7 @@ from game.ground_forces.ai_ground_planner import (
DISTANCE_FROM_FRONTLINE,
)
from game.ground_forces.combat_stance import CombatStance
from game.lasercodes import LaserCodeRegistry
from game.naming import namegen
from game.radio.radios import RadioRegistry
from game.theater.controlpoint import ControlPoint
@ -44,7 +45,6 @@ from game.unitmap import UnitMap
from game.utils import Heading
from .frontlineconflictdescription import FrontLineConflictDescription
from .groundforcepainter import GroundForcePainter
from .lasercoderegistry import LaserCodeRegistry
from .missiondata import JtacInfo, MissionData
from ..ato import FlightType
@ -152,7 +152,7 @@ class FlotGenerator:
if self.game.settings.plugins.get("ctld.fc3LaserCode"):
code = 1113
else:
code = self.laser_code_registry.get_next_laser_code()
code = self.laser_code_registry.alloc_laser_code()
utype = self.game.blue.faction.jtac_unit
if utype is None:

View File

@ -32,7 +32,7 @@ from .flotgenerator import FlotGenerator
from .forcedoptionsgenerator import ForcedOptionsGenerator
from .frontlineconflictdescription import FrontLineConflictDescription
from .kneeboard import KneeboardGenerator
from .lasercoderegistry import LaserCodeRegistry
from game.lasercodes import LaserCodeRegistry
from .luagenerator import LuaGenerator
from .missiondata import MissionData
from .tgogenerator import TgoGenerator

View File

View File

@ -0,0 +1,15 @@
from game.lasercodes.lasercoderegistry import LaserCodeRegistry
def test_initial_laser_codes() -> None:
reg = LaserCodeRegistry()
assert list(reg.available_codes)[:5] == [1688, 1687, 1686, 1685, 1684]
assert list(reg.available_codes)[-5:] == [1715, 1714, 1713, 1712, 1711]
assert len(reg.available_codes) == 192
def test_alloc_laser_code() -> None:
reg = LaserCodeRegistry()
assert reg.alloc_laser_code() == 1688
assert 1688 not in reg.available_codes
assert len(reg.available_codes) == 191