another round of optimizations and cleanup including some I/O multithreading

also alias sprite names with their file names as that's an often done mistake
This commit is contained in:
Fabian Dill
2020-08-21 18:35:48 +02:00
parent 6d3a7487e0
commit 45268b18f3
3 changed files with 263 additions and 247 deletions

71
Main.py
View File

@@ -7,6 +7,7 @@ import os
import random
import time
import zlib
import concurrent.futures
from BaseClasses import World, CollectionState, Item, Region, Location, Shop
from Items import ItemFactory
@@ -244,16 +245,15 @@ def main(args, seed=None):
Patch.create_patch_file(rompath)
return player, team, bytes(rom.name).decode()
pool = concurrent.futures.ThreadPoolExecutor()
if not args.suppress_rom:
import concurrent.futures
futures = []
with concurrent.futures.ThreadPoolExecutor() as pool:
for team in range(world.teams):
for player in range(1, world.players + 1):
futures.append(pool.submit(_gen_rom, team, player))
for future in futures:
rom_name = future.result()
rom_names.append(rom_name)
rom_futures = []
for team in range(world.teams):
for player in range(1, world.players + 1):
rom_futures.append(pool.submit(_gen_rom, team, player))
def get_entrance_to_region(region: Region):
for entrance in region.entrances:
@@ -276,37 +276,42 @@ def main(args, seed=None):
precollected_items = [[] for player in range(world.players)]
for item in world.precollected_items:
precollected_items[item.player - 1].append(item.code)
multidata = zlib.compress(json.dumps({"names": parsed_names,
# backwards compat for < 2.4.1
"roms": [(slot, team, list(name.encode()))
for (slot, team, name) in rom_names],
"rom_strings": rom_names,
"remote_items": [player for player in range(1, world.players + 1) if
world.remote_items[player]],
"locations": [((location.address, location.player),
(location.item.code, location.item.player))
for location in world.get_filled_locations() if
type(location.address) is int],
"server_options": get_options()["server_options"],
"er_hint_data": er_hint_data,
"precollected_items": precollected_items,
"version": _version_tuple,
"tags": ["ER"]
}).encode("utf-8"), 9)
with open(output_path('%s.multidata' % outfilebase), 'wb') as f:
f.write(multidata)
def write_multidata(roms):
for future in roms:
rom_name = future.result()
rom_names.append(rom_name)
multidata = zlib.compress(json.dumps({"names": parsed_names,
# backwards compat for < 2.4.1
"roms": [(slot, team, list(name.encode()))
for (slot, team, name) in rom_names],
"rom_strings": rom_names,
"remote_items": [player for player in range(1, world.players + 1) if
world.remote_items[player]],
"locations": [((location.address, location.player),
(location.item.code, location.item.player))
for location in world.get_filled_locations() if
type(location.address) is int],
"server_options": get_options()["server_options"],
"er_hint_data": er_hint_data,
"precollected_items": precollected_items,
"version": _version_tuple,
"tags": ["ER"]
}).encode("utf-8"), 9)
with open(output_path('%s.multidata' % outfilebase), 'wb') as f:
f.write(multidata)
pool.submit(write_multidata, rom_futures)
if not args.skip_playthrough:
logger.info('Calculating playthrough.')
create_playthrough(world)
if args.create_spoiler:
pool.shutdown() # wait for all queued tasks to complete
if args.create_spoiler: # needs spoiler.hashes to be filled, that depend on rom_futures being done
world.spoiler.to_file(output_path('%s_Spoiler.txt' % outfilebase))
logger.info('Done. Enjoy.')
logger.debug('Total Time: %s', time.perf_counter() - start)
logger.info('Done. Enjoy. Total Time: %s', time.perf_counter() - start)
return world