Skip to content

Commit

Permalink
Ignore exceptions when loading MSTS data.
Browse files Browse the repository at this point in the history
  • Loading branch information
YoRyan committed Mar 19, 2020
1 parent f822e3c commit 71c9fa2
Showing 1 changed file with 31 additions and 21 deletions.
52 changes: 31 additions & 21 deletions autotable/mstsinstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def __init__(self, data: kf.Object):
self.latlon = _latlon(tile_x, tile_z, ew, ns)

def __init__(self, path: Path, encoding=ENCODING):
df = one(_echild(path, 'trk'))
df = one(_echildren(path, 'trk'))
with open(df, encoding=encoding) as fp:
d = kf.load(fp)
desc = d['Tr_RouteFile']
Expand All @@ -89,25 +89,18 @@ def stations(self) -> typ.Mapping[Station, typ.Iterable[PlatformItem]]:
d = kf.load(fp)
table = d['TrItemTable']

with ProcessPoolExecutor() as executor:
platforms = executor.map(Route.PlatformItem, table['PlatformItem'])
res = defaultdict(list)
for platform in platforms:
for platform in _pmap(table['PlatformItem'], Route.PlatformItem):
res[platform.station].append(platform)
return res

def station_names(self) -> typ.Iterable[Station]: return self.stations().keys()

@lru_cache(maxsize=1)
def train_paths(self) -> typ.Mapping[Ident, TrainPath]:
route_paths = _echild(_ichild(self.path, 'paths'), 'pat')
with ProcessPoolExecutor() as executor:
futures = []
for path in route_paths:
futures.append(
executor.submit(Route.TrainPath, path, encoding=self._encoding))
loaded_paths = [future.result() for future in as_completed(futures)]
return {path.id: path for path in loaded_paths}
route_paths = _echildren(_ichild(self.path, 'paths'), 'pat')
return {path.id: path for path
in _pmap(route_paths, Route.TrainPath, encoding=self._encoding)}

def train_path(self, id: str) -> TrainPath:
return self.train_paths()[Ident(id)]
Expand All @@ -130,37 +123,54 @@ def __init__(self, path: Path, encoding=ENCODING):

@lru_cache(maxsize=1)
def routes(self) -> typ.Mapping[Ident, Route]:
route_dirs = (child for child in _ichild(self.path, 'routes').iterdir()
if child.is_dir())
with ProcessPoolExecutor() as executor:
return {route.id: route for route in executor.map(Route, route_dirs)}
route_dirs = _dchildren(_ichild(self.path, 'routes'))
return {route.id: route for route in _pmap(route_dirs, Route)}

def route(self, id: str) -> Route:
return self.routes()[Ident(id)]

@lru_cache(maxsize=1)
def consists(self) -> typ.Mapping[Ident, Consist]:
con_files = \
_echild(_ichild(_ichild(self.path, 'trains'), 'consists'), 'con')
with ProcessPoolExecutor() as executor:
return {consist.id: consist
for consist in executor.map(Consist, con_files)}
_echildren(_ichild(_ichild(self.path, 'trains'), 'consists'), 'con')
return {consist.id: consist for consist in _pmap(con_files, Consist)}

def consist(self, id: str) -> Consist:
return self.consists()[Ident(id)]



_T = typ.TypeVar('_T')
_U = typ.TypeVar('_U')

def _pmap(inputs: typ.Iterable[_T], fn: typ.Callable[..., _U], *args, **kwargs) \
-> typ.Generator[_U, None, None]:
with ProcessPoolExecutor() as executor:
futures = [executor.submit(fn, input, *args, **kwargs) for input in inputs]
for future in as_completed(futures):
try:
result = future.result()
except:
pass # Just eat exceptions.
else:
yield result


def _ichild(path: Path, name: str) -> Path:
matches = (child for child in path.iterdir()
if child.name.casefold() == name.casefold())
return one(matches, too_short=FileNotFoundError, too_long=LookupError)


def _echild(path: Path, extension: str) -> typ.Iterable[Path]:
def _echildren(path: Path, extension: str) -> typ.Iterable[Path]:
suffix = f'.{extension.casefold()}'
return (child for child in path.iterdir() if child.suffix.casefold() == suffix)


def _dchildren(path: Path) -> typ.Iterable[Path]:
return (child for child in path.iterdir() if child.is_dir())


def _latlon(tile_x: int, tile_z: int, ew: float, ns: float) \
-> typ.Tuple[float, float]:
# Conversion is abridged from Open Rails (Orts.Common.WorldLatLon.ConvertWTC)
Expand Down

0 comments on commit 71c9fa2

Please sign in to comment.