Browse Source

use texture cache for firing animation

Bastien Sevajol 6 years ago
parent
commit
a0fbc1f6c9
2 changed files with 60 additions and 22 deletions
  1. 45 22
      opencombat/gui/actor.py
  2. 15 0
      opencombat/gui/image.py

+ 45 - 22
opencombat/gui/actor.py View File

@@ -1,4 +1,5 @@
1 1
 # coding: utf-8
2
+import os
2 3
 import typing
3 4
 
4 5
 import time
@@ -52,6 +53,7 @@ class BaseActor(Actor):
52 53
     ) -> None:
53 54
         self._mode = MODE_MAN_STAND_UP
54 55
         self.weapon_image_applier = WeaponImageApplier(config, self)
56
+        self.firing_texture_cache = {}  # type: typing.Dict[str, typing.Dict[typing.List[pyglet.image.TextureRegion]]  # nopep8
55 57
         super().__init__(image_path, subject=subject, config=config)
56 58
 
57 59
         # Firing
@@ -95,6 +97,10 @@ class BaseActor(Actor):
95 97
     def weapons(self) -> typing.List[str]:
96 98
         return []
97 99
 
100
+    def build_textures_cache(self) -> None:
101
+        super().build_textures_cache()
102
+        self.build_firing_texture_cache()
103
+
98 104
     def get_default_appliable_images(self) -> typing.List[Image.Image]:
99 105
         if not self.weapons:
100 106
             return []
@@ -127,6 +133,29 @@ class BaseActor(Actor):
127 133
         except UnknownWeapon:
128 134
             return []
129 135
 
136
+    def build_firing_texture_cache(self) -> None:
137
+        cache_dir = self.config.resolve('global.cache_dir_path')
138
+        for mode in self.get_modes():
139
+            for weapon in self.weapons:
140
+                firing_images = self.image_cache_manager.firing_cache.get_list(
141
+                    mode,
142
+                    weapon,
143
+                )
144
+                for i, firing_image in enumerate(firing_images):
145
+                    image_name = '{}_firing_{}_{}_{}.png'.format(
146
+                        str(self.subject.id),
147
+                        mode,
148
+                        weapon,
149
+                        i,
150
+                    )
151
+                    cache_image_path = os.path.join(cache_dir, image_name)
152
+                    firing_image.save(cache_image_path)
153
+
154
+                    self.firing_texture_cache\
155
+                        .setdefault(mode, {})\
156
+                        .setdefault(weapon, [])\
157
+                        .append(pyglet.image.load(cache_image_path))
158
+
130 159
     def firing(self, firing: 'GuiFiringEvent') -> None:
131 160
         # FIXME: move some code ?
132 161
         now = time.time()
@@ -135,35 +164,29 @@ class BaseActor(Actor):
135 164
             firing.increment_animation_index()
136 165
 
137 166
             try:
138
-                image = self.image_cache_manager.firing_cache.get(
139
-                    mode=self.mode,
140
-                    weapon=firing.weapon,
141
-                    position=firing.animation_index,
142
-                )
143
-            except UnknownAnimationIndex:
144
-                image = self.image_cache_manager.firing_cache.get(
145
-                    mode=self.mode,
146
-                    weapon=firing.weapon,
147
-                    position=0,
148
-                )
149
-                firing.reset_animation_index()
150
-            except UnknownFiringAnimation as exc:
167
+                texture = self.firing_texture_cache\
168
+                    [self.mode]\
169
+                    [firing.weapon]\
170
+                    [firing.animation_index]
171
+            except KeyError:
151 172
                 self.logger.error(
152
-                    'No firing animation for actor {}({}): {}'.format(
173
+                    'No firing animation for actor {}({}) for mode "{}"'
174
+                    ' and weapon "{}"'.format(
153 175
                         self.__class__.__name__,
154 176
                         str(self.subject.id),
155
-                        str(exc),
177
+                        self.mode,
178
+                        firing.weapon,
156 179
                     )
157 180
                 )
158 181
                 return  # There is no firing animation defined
182
+            except IndexError:
183
+                texture = self.firing_texture_cache\
184
+                    [self.mode]\
185
+                    [firing.weapon]\
186
+                    [0]
187
+                firing.reset_animation_index()
159 188
 
160
-            # FIXME cache: prepare before firing
161
-            import uuid
162
-            tmp_path = '/tmp/{}.png'.format(str(uuid.uuid4()))
163
-            image.save(tmp_path)
164
-            pyglet_image = pyglet.image.load(tmp_path)
165
-
166
-            self.update_image(pyglet_image.get_texture())
189
+            self.update_image(texture)
167 190
 
168 191
 
169 192
 class Man(BaseActor):

+ 15 - 0
opencombat/gui/image.py View File

@@ -48,6 +48,21 @@ class FiringImageCache(ImageCache):
48 48
                 ),
49 49
             )
50 50
 
51
+    def get_list(
52
+        self,
53
+        mode: str,
54
+        weapon: str,
55
+    ) -> typing.List[Image.Image]:
56
+        try:
57
+            return self.cache[mode][weapon]
58
+        except KeyError:
59
+            raise UnknownFiringAnimation(
60
+                'Unknown firing animation for mode "{}" and weapon "{}"'.format(
61
+                    mode,
62
+                    weapon,
63
+                )
64
+            )
65
+
51 66
 
52 67
 class TileImageCacheManager(ImageCacheManager):
53 68
     def __init__(