77 lines
2.6 KiB
Python
77 lines
2.6 KiB
Python
import json
|
|
import sys
|
|
import warnings
|
|
from pathlib import Path
|
|
from typing import Iterable, Union, TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from multiprocessing.managers import ListProxy # noqa
|
|
|
|
__all__ = [
|
|
"generate_local",
|
|
]
|
|
|
|
|
|
def _generate_local_inner(games: Iterable[str],
|
|
dest: Union[Path, str],
|
|
results: "ListProxy[Union[Path, BaseException]]") -> None:
|
|
original_argv = sys.argv
|
|
warnings.simplefilter("ignore")
|
|
try:
|
|
from tempfile import TemporaryDirectory
|
|
|
|
if not isinstance(dest, Path):
|
|
dest = Path(dest)
|
|
|
|
with TemporaryDirectory() as players_dir:
|
|
with TemporaryDirectory() as output_dir:
|
|
import Generate
|
|
import Main
|
|
|
|
for n, game in enumerate(games, 1):
|
|
player_path = Path(players_dir) / f"{n}.yaml"
|
|
with open(player_path, "w", encoding="utf-8") as f:
|
|
f.write(json.dumps({
|
|
"name": f"Player{n}",
|
|
"game": game,
|
|
game: {"hard_mode": "true"},
|
|
"description": f"generate_local slot {n} ('Player{n}'): {game}",
|
|
}))
|
|
|
|
# this is basically copied from test/programs/test_generate.py
|
|
# uses a reproducible seed that is different for each set of games
|
|
sys.argv = [sys.argv[0], "--seed", str(hash(tuple(games))),
|
|
"--player_files_path", players_dir,
|
|
"--outputpath", output_dir]
|
|
Main.main(*Generate.main())
|
|
output_files = list(Path(output_dir).glob('*.zip'))
|
|
assert len(output_files) == 1
|
|
final_file = dest / output_files[0].name
|
|
output_files[0].rename(final_file)
|
|
results.append(final_file)
|
|
except BaseException as e:
|
|
results.append(e)
|
|
raise e
|
|
finally:
|
|
sys.argv = original_argv
|
|
|
|
|
|
def generate_local(games: Iterable[str], dest: Union[Path, str]) -> Path:
|
|
from multiprocessing import Manager, Process, set_start_method
|
|
|
|
try:
|
|
set_start_method("spawn")
|
|
except RuntimeError:
|
|
pass
|
|
|
|
manager = Manager()
|
|
results: "ListProxy[Union[Path, Exception]]" = manager.list()
|
|
|
|
p = Process(target=_generate_local_inner, args=(games, dest, results))
|
|
p.start()
|
|
p.join()
|
|
result = results[0]
|
|
if isinstance(result, BaseException):
|
|
raise Exception("Could not generate multiworld") from result
|
|
return result
|