def load_soundscript_manifest(self, cache_file: str=None) -> None: """Read the soundscript manifest, and read all mentioned scripts. If cache_file is provided, it should be a path to a file used to cache the file reading for later use. """ try: man = self.fsys.read_prop('scripts/game_sounds_manifest.txt') except FileNotFoundError: return cache_data = {} # type: Dict[str, Tuple[int, Property]] if cache_file is not None: # If the file doesn't exist or is corrupt, that's # fine. We'll just parse the soundscripts the slow # way. try: with open(cache_file) as f: old_cache = Property.parse(f, cache_file) if man['version'] != SOUND_CACHE_VERSION: raise LookupError except (FileNotFoundError, KeyValError, LookupError): pass else: for cache_prop in old_cache.find_children('Sounds'): cache_data[cache_prop.name] = ( cache_prop.int('cache_key'), cache_prop.find_key('files') ) # Regenerate from scratch each time - that way we remove old files # from the list. new_cache_sounds = Property('Sounds', []) new_cache_data = Property(None, [ Property('version', SOUND_CACHE_VERSION), new_cache_sounds, ]) else: new_cache_data = new_cache_sounds = None with self.fsys: for prop in man.find_children('game_sounds_manifest'): if not prop.name.endswith('_file'): continue try: cache_key, cache_files = cache_data[prop.value.casefold()] except KeyError: cache_key = -1 cache_files = None try: file = self.fsys[prop.value] except FileNotFoundError: LOGGER.warning('Soundscript "{}" does not exist!', prop.value) # Don't write anything into the cache, so we check this # every time. continue cur_key = file.cache_key() if cache_key != cur_key or cache_key == -1: sounds = self.load_soundscript(file, always_include=True) else: # Read from cache. sounds = [] for cache_prop in cache_files: sounds.append(cache_prop.real_name) self.soundscripts[cache_prop.real_name] = (prop.value, [ snd.value for snd in cache_prop ]) # The soundscripts in the manifests are always included, # since many would be part of the core code (physics, weapons, # ui, etc). Just keep those loaded, no harm since vanilla does. self.soundscript_files[file.path] = SoundScriptMode.INCLUDE if new_cache_sounds is not None: new_cache_sounds.append(Property(prop.value, [ Property('cache_key', str(cur_key)), Property('Files', [ Property(snd, [ Property('snd', raw) for raw in self.soundscripts[snd][1] ]) for snd in sounds ]) ])) if cache_file is not None: # Write back out our new cache with updated data. with srctools.AtomicWriter(cache_file) as f: for line in new_cache_data.export(): f.write(line)
def load_soundscript_manifest(self, cache_file: str = None) -> None: """Read the soundscript manifest, and read all mentioned scripts. If cache_file is provided, it should be a path to a file used to cache the file reading for later use. """ try: man = self.fsys.read_prop('scripts/game_sounds_manifest.txt') except FileNotFoundError: return cache_data = {} # type: Dict[str, Tuple[int, Property]] if cache_file is not None: try: f = open(cache_file) except FileNotFoundError: pass else: with f: old_cache = Property.parse(f, cache_file) for cache_prop in old_cache: cache_data[cache_prop.name] = ( cache_prop.int('cache_key'), cache_prop.find_key('files')) # Regenerate from scratch each time - that way we remove old files # from the list. new_cache_data = Property(None, []) else: new_cache_data = None with self.fsys: for prop in man.find_children('game_sounds_manifest'): if not prop.name.endswith('_file'): continue try: cache_key, cache_files = cache_data[prop.value.casefold()] except KeyError: cache_key = -1 cache_files = None file = self.fsys[prop.value] cur_key = file.cache_key() if cache_key != cur_key or cache_key == -1: sounds = self.load_soundscript(file, always_include=True) else: # Read from cache. sounds = [] for cache_prop in cache_files: sounds.append(cache_prop.real_name) self.soundscripts[cache_prop.real_name] = ( prop.value, [snd.value for snd in cache_prop]) # The soundscripts in the manifests are always included, # since many would be part of the core code (physics, weapons, # ui, etc). Just keep those loaded, no harm since vanilla does. self.soundscript_files[file.path] = SoundScriptMode.INCLUDE if new_cache_data is not None: new_cache_data.append( Property(prop.value, [ Property('cache_key', str(cur_key)), Property('Files', [ Property(snd, [ Property('snd', raw) for raw in self.soundscripts[snd][1] ]) for snd in sounds ]) ])) if cache_file is not None: # Write back out our new cache with updated data. with open(cache_file, 'w') as f: for line in new_cache_data.export(): f.write(line)
def load_soundscript_manifest(self, cache_file: str=None) -> None: """Read the soundscript manifest, and read all mentioned scripts. If cache_file is provided, it should be a path to a file used to cache the file reading for later use. """ try: man = self.fsys.read_prop('scripts/game_sounds_manifest.txt') except FileNotFoundError: return cache_data = {} # type: Dict[str, Tuple[int, Property]] if cache_file is not None: try: f = open(cache_file) except FileNotFoundError: pass else: with f: old_cache = Property.parse(f, cache_file) for cache_prop in old_cache: cache_data[cache_prop.name] = ( cache_prop.int('cache_key'), cache_prop.find_key('files') ) # Regenerate from scratch each time - that way we remove old files # from the list. new_cache_data = Property(None, []) else: new_cache_data = None with self.fsys: for prop in man.find_children('game_sounds_manifest'): if not prop.name.endswith('_file'): continue try: cache_key, cache_files = cache_data[prop.value.casefold()] except KeyError: cache_key = -1 cache_files = None file = self.fsys[prop.value] cur_key = file.cache_key() if cache_key != cur_key or cache_key == -1: sounds = self.load_soundscript(file, always_include=True) else: # Read from cache. sounds = [] for cache_prop in cache_files: sounds.append(cache_prop.real_name) self.soundscripts[cache_prop.real_name] = (prop.value, [ snd.value for snd in cache_prop ]) # The soundscripts in the manifests are always included, # since many would be part of the core code (physics, weapons, # ui, etc). Just keep those loaded, no harm since vanilla does. self.soundscript_files[file.path] = SoundScriptMode.INCLUDE if new_cache_data is not None: new_cache_data.append(Property(prop.value, [ Property('cache_key', str(cur_key)), Property('Files', [ Property(snd, [ Property('snd', raw) for raw in self.soundscripts[snd][1] ]) for snd in sounds ]) ])) if cache_file is not None: # Write back out our new cache with updated data. with open(cache_file, 'w') as f: for line in new_cache_data.export(): f.write(line)