123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- # coding: utf-8
- import typing
- from _elementtree import Element
-
- from lxml import etree
-
- from synergine2.config import Config
- from synergine2.log import get_logger
-
- from opencombat.simulation.base import TileStrategySimulation
- from opencombat.simulation.subject import TileSubject
- from opencombat.strategy.team.model import TeamModel
- from opencombat.strategy.team.stash import TeamStash
- from opencombat.strategy.unit.stash import UnitStash
- from opencombat.util import get_class_from_string_path, pretty_xml
- from opencombat.xml import XmlValidator
-
-
- class Troop(object):
- def __init__(
- self,
- config: Config,
- state_root: Element,
- simulation: TileStrategySimulation,
- ) -> None:
- self._config = config
- self._state_root = state_root
- self._subjects = None # type: typing.List[TileSubject]
- self._simulation = simulation
- self._builder = TroopClassBuilder(config)
-
- @property
- def subjects(self) -> typing.List[TileSubject]:
- if self._subjects is None:
- self._subjects = self._get_computed_subjects()
-
- return self._subjects
-
- def _get_computed_subjects(self) -> typing.List[TileSubject]:
- units_file_path = self._config.get(
- 'global.units',
- 'opencombat/strategy/units.xml',
- )
- teams_file_path = self._config.get(
- 'global.teams',
- 'opencombat/strategy/teams.xml',
- )
-
- team_stash = self._builder.get_team_stash(
- units_file_path,
- teams_file_path,
- )
-
- # Parse team, build Subjects
- subjects = [] # type: typing.List[TileSubject]
- for troop in self._state_root.findall('troop'):
- country = troop.attrib['country']
- team_id = troop.attrib['team_id']
- team = team_stash.get_team(team_id, country)
-
- for unit in team.units:
- subject = unit.class_(self._config, self._simulation)
- properties = \
- self._simulation.get_default_properties_for_country(
- country,
- )
- subject.properties.update(properties)
- subjects.append(subject)
-
- return subjects
-
-
- class TroopDumper(object):
- def __init__(
- self,
- config: Config,
- ) -> None:
- self._config = config
- self._logger = get_logger('TroopDumper', config)
-
- def get_troop_dump(
- self,
- countries_troops: typing.Dict[str, typing.List[TeamModel]],
- ) -> str:
- troops_template = self._config.resolve(
- 'global.troops_template',
- 'opencombat/strategy/troops_template.xml',
- )
- with open(troops_template, 'r') as xml_file:
- template_str = xml_file.read()
-
- parser = etree.XMLParser(remove_blank_text=True)
- state_root = etree.fromstring(
- template_str.encode('utf-8'),
- parser,
- )
-
- for country, teams in countries_troops.items():
- for team in teams:
- troop_element = etree.SubElement(state_root, 'troop')
- troop_element.attrib['country'] = country
- troop_element.attrib['team_id'] = team.id
-
- return pretty_xml(
- etree.tostring(
- state_root,
- ).decode('utf-8'),
- )
-
-
- class TroopClassBuilder(object):
- def __init__(
- self,
- config: Config,
- ) -> None:
- self._logger = get_logger('TroopManagerBuilder', config)
- self._config = config
-
- def get_unit_stash(
- self,
- units_file_path: str,
- ) -> UnitStash:
- class_address = self._config.resolve(
- 'global.unit_stash',
- 'opencombat.strategy.unit.stash.UnitStash',
- )
- class_ = get_class_from_string_path(
- self._config,
- class_address,
- )
- return class_(
- self._config,
- units_file_path,
- )
-
- def get_team_stash(
- self,
- units_file_path: str,
- teams_file_path: str,
- ) -> TeamStash:
- class_address = self._config.resolve(
- 'global.team_stash',
- 'opencombat.strategy.team.stash.TeamStash',
- )
- class_ = get_class_from_string_path(
- self._config,
- class_address,
- )
-
- unit_stash = self.get_unit_stash(units_file_path)
- return class_(
- self._config,
- teams_file_path,
- unit_stash=unit_stash,
- )
-
- def get_troop_dumper(self) -> TroopDumper:
- class_address = self._config.resolve(
- 'global.troop_dumper',
- 'opencombat.strategy.troops.TroopDumper',
- )
- class_ = get_class_from_string_path(
- self._config,
- class_address,
- )
-
- return class_(
- self._config,
- )
-
-
- class TroopLoader(object):
- def __init__(
- self,
- config: Config,
- simulation: TileStrategySimulation,
- ) -> None:
- self._logger = get_logger('TroopLoader', config)
- self._config = config
- self._simulation = simulation
-
- schema_file_path = self._config.get(
- 'global.troop_schema',
- 'opencombat/strategy/troops.xsd',
- )
- self._xml_validator = XmlValidator(
- config,
- schema_file_path,
- )
-
- def get_troop(
- self,
- troop_file_path: str,
- ) -> Troop:
- return Troop(
- self._config,
- self._validate_and_return_state_element(troop_file_path),
- self._simulation,
- )
-
- def _validate_and_return_state_element(
- self,
- troop_file_path: str,
- ) -> Element:
- return self._xml_validator.validate_and_return(troop_file_path)
-
-
- class TroopConstructorBuilder(object):
- def __init__(
- self,
- config: Config,
- simulation: TileStrategySimulation,
- ) -> None:
- self._logger = get_logger('TroopConstructorBuilder', config)
- self._config = config
- self._simulation = simulation
-
- def get_troop_loader(
- self,
- ) -> TroopLoader:
- class_address = self._config.resolve(
- 'global.troop_loader',
- 'opencombat.strategy.troops.TroopLoader',
- )
- troop_loader_class = get_class_from_string_path(
- self._config,
- class_address,
- )
- return troop_loader_class(
- self._config,
- self._simulation,
- )
|