comparison pytouhou/resource/loader.py @ 771:79c3f782dd41

Python: Replace the PBG3 loader with Rust’s
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Tue, 30 Aug 2022 18:41:50 +0200
parents d18c0bf11138
children
comparison
equal deleted inserted replaced
770:f6c287745a67 771:79c3f782dd41
13 ## 13 ##
14 14
15 import os 15 import os
16 from glob import glob 16 from glob import glob
17 from itertools import chain 17 from itertools import chain
18 from io import BytesIO
18 19
19 from pytouhou.formats import WrongFormatError 20 from pytouhou.formats import WrongFormatError
20 from pytouhou.formats.pbg3 import PBG3 21 from libtouhou import PBG3
21 from pytouhou.formats.std import Stage 22 from pytouhou.formats.std import Stage
22 from pytouhou.formats.ecl import ECL 23 from pytouhou.formats.ecl import ECL
23 from pytouhou.formats.anm0 import ANM0 24 from pytouhou.formats.anm0 import ANM0
24 from pytouhou.formats.msg import MSG 25 from pytouhou.formats.msg import MSG
25 from pytouhou.formats.sht import SHT 26 from pytouhou.formats.sht import SHT
44 45
45 def __exit__(self, type, value, traceback): 46 def __exit__(self, type, value, traceback):
46 return False 47 return False
47 48
48 49
50 @property
51 def file_list(self):
52 return self.list_files()
53
49 def list_files(self): 54 def list_files(self):
50 file_list = [] 55 file_list = []
51 for path in os.listdir(self.path): 56 for path in os.listdir(self.path):
52 if os.path.isfile(os.path.join(self.path, path)): 57 if os.path.isfile(os.path.join(self.path, path)):
53 file_list.append(path) 58 file_list.append(path)
60 65
61 66
62 class ArchiveDescription: 67 class ArchiveDescription:
63 _formats = {b'PBG3': PBG3} 68 _formats = {b'PBG3': PBG3}
64 69
65 def __init__(self, path, format_class, file_list=None):
66 self.path = path
67 self.format_class = format_class
68 self.file_list = file_list or []
69
70
71 def open(self):
72 if self.format_class is Directory:
73 return self.format_class(self.path)
74
75 file = open(self.path, 'rb')
76 instance = self.format_class.read(file)
77 return instance
78
79
80 @classmethod 70 @classmethod
81 def get_from_path(cls, path): 71 def get_from_path(cls, path):
82 if os.path.isdir(path): 72 if os.path.isdir(path):
83 instance = Directory(path) 73 instance = Directory(path)
84 file_list = instance.list_files() 74 file_list = instance.list_files()
85 return cls(path, Directory, file_list) 75 return instance
86 with open(path, 'rb') as file: 76 with open(path, 'rb') as file:
87 magic = file.read(4) 77 magic = file.read(4)
88 file.seek(0)
89 format_class = cls._formats[magic] 78 format_class = cls._formats[magic]
90 instance = format_class.read(file) 79 return format_class.from_filename(path)
91 file_list = instance.list_files()
92 return cls(path, format_class, file_list)
93 80
94 81
95 82
96 class Loader: 83 class Loader:
97 def __init__(self, game_dir=None): 84 def __init__(self, game_dir=None):
120 for name in archive_description.file_list: 107 for name in archive_description.file_list:
121 self.known_files[name] = archive_description 108 self.known_files[name] = archive_description
122 109
123 110
124 def get_file(self, name): 111 def get_file(self, name):
125 with self.known_files[name].open() as archive: 112 archive = self.known_files[name]
126 return archive.get_file(name) 113 file = archive.get_file(name)
114 if isinstance(file, bytes):
115 return BytesIO(file)
116 return file
127 117
128 118
129 def get_anm(self, name): 119 def get_anm(self, name):
130 if name in self.loaded_anms: 120 if name in self.loaded_anms:
131 logger.warning('ANM0 %s already loaded', name) 121 logger.warning('ANM0 %s already loaded', name)