Mercurial > touhou
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) |