Browse Source

Add a PathManager to permit override file usage prior

Bastien Sevajol 6 years ago
parent
commit
8cfdcc1bb5

+ 16 - 3
synergine2_cocos2d/actor.py View File

@@ -6,17 +6,19 @@ import pyglet
6 6
 import cocos
7 7
 from cocos import collision_model
8 8
 from cocos import euclid
9
+
10
+from synergine2.config import Config
9 11
 from synergine2.simulation import Subject
10 12
 from synergine2_cocos2d.animation import AnimatedInterface
13
+from synergine2_cocos2d.util import PathManager
11 14
 
12 15
 
13 16
 class Actor(AnimatedInterface, cocos.sprite.Sprite):
14 17
     animation_image_paths = {}  # type: typing.Dict[str, typing.List[str]]
15
-    animation_images = {}  # type: typing.Dict[str, typing.List[pyglet.image.TextureRegion]]
16 18
 
17 19
     def __init__(
18 20
         self,
19
-        image: pyglet.image.TextureRegion,
21
+        image_path: str,
20 22
         subject: Subject,
21 23
         position=(0, 0),
22 24
         rotation=0,
@@ -25,8 +27,14 @@ class Actor(AnimatedInterface, cocos.sprite.Sprite):
25 27
         color=(255, 255, 255),
26 28
         anchor=None,
27 29
         properties: dict=None,
30
+        config: Config=None,
28 31
         **kwargs
29 32
     ):
33
+        # Note: Parameter required, but we want to modify little as possible parent init
34
+        assert config, "Config is a required parameter"
35
+        self.path_manager = PathManager(config.resolve('global.include_path.graphics'))
36
+        image = pyglet.resource.image(self.path_manager.path(image_path))
37
+        self.animation_images = {}  # type: typing.Dict[str, typing.List[pyglet.image.TextureRegion]]  # nopep8
30 38
         super().__init__(
31 39
             image,
32 40
             position,
@@ -80,7 +88,12 @@ class Actor(AnimatedInterface, cocos.sprite.Sprite):
80 88
         for animation_name, animation_image_paths in self.animation_image_paths.items():
81 89
             self.animation_images[animation_name] = []
82 90
             for animation_image_path in animation_image_paths:
83
-                self.animation_images[animation_name].append(pyglet.resource.image(animation_image_path))
91
+                final_image_path = self.path_manager.path(animation_image_path)
92
+                self.animation_images[animation_name].append(
93
+                    pyglet.resource.image(
94
+                        final_image_path,
95
+                    )
96
+                )
84 97
 
85 98
     def get_images_for_animation(self, animation_name: str) -> typing.List[pyglet.image.TextureRegion]:
86 99
         return self.animation_images.get(animation_name)

+ 9 - 0
synergine2_cocos2d/exception.py View File

@@ -1,4 +1,5 @@
1 1
 # coding: utf-8
2
+from synergine2.exceptions import SynergineException
2 3
 
3 4
 
4 5
 class WorldException(Exception):
@@ -15,3 +16,11 @@ class OuterWorldPosition(PositionException):
15 16
 
16 17
 class InteractionNotFound(Exception):
17 18
     pass
19
+
20
+
21
+class MediaException(SynergineException):
22
+    pass
23
+
24
+
25
+class FileNotFound(SynergineException):
26
+    pass

+ 3 - 1
synergine2_cocos2d/gui.py View File

@@ -677,8 +677,10 @@ class MainLayer(ScrollableLayer):
677 677
 class SubjectMapper(object):
678 678
     def __init__(
679 679
         self,
680
+        config: Config,
680 681
         actor_class: typing.Type[Actor],
681 682
     ) -> None:
683
+        self.config = config
682 684
         self.actor_class = actor_class
683 685
 
684 686
     def append(
@@ -686,7 +688,7 @@ class SubjectMapper(object):
686 688
         subject: XYZSubjectMixin,
687 689
         layer_manager: LayerManager,
688 690
     ) -> None:
689
-        actor = self.actor_class(subject)
691
+        actor = self.actor_class(self.config, subject)
690 692
         pixel_position = layer_manager.grid_manager.get_world_position_of_grid_position(
691 693
             (subject.position[0], subject.position[1]),
692 694
         )

+ 42 - 0
synergine2_cocos2d/util.py View File

@@ -1,7 +1,49 @@
1 1
 # coding: utf-8
2 2
 import os
3
+import typing
4
+from os import path
5
+
6
+from synergine2_cocos2d.exception import FileNotFound
3 7
 
4 8
 
5 9
 def get_map_file_path_from_dir(map_dir_path: str) -> str:
6 10
     # TODO: path is temp here
7 11
     return '{}.tmx'.format(os.path.join(map_dir_path, os.path.basename(map_dir_path)))
12
+
13
+
14
+class PathManager(object):
15
+    def __init__(
16
+        self,
17
+        include_paths: typing.List[str],
18
+    ) -> None:
19
+        self._include_paths = []  # type: typing.List[str]
20
+        self.include_paths = include_paths
21
+
22
+    @property
23
+    def include_paths(self) -> typing.Tuple[str, ...]:
24
+        return tuple(self._include_paths)
25
+
26
+    @include_paths.setter
27
+    def include_paths(self, value: typing.List[str]) -> None:
28
+        self._include_paths = value
29
+        self._include_paths.sort(reverse=True)
30
+
31
+    def add_included_path(self, included_path: str) -> None:
32
+        self._include_paths.append(included_path)
33
+        self._include_paths.sort(reverse=True)
34
+
35
+    def path(self, file_path: str) -> str:
36
+        # Search in configured paths
37
+        for include_path in self._include_paths:
38
+            complete_file_path = path.join(include_path, file_path)
39
+            if path.isfile(complete_file_path):
40
+                return complete_file_path
41
+
42
+        # If not in include last chance in current dir
43
+        if path.isfile(file_path):
44
+            return file_path
45
+
46
+        raise FileNotFound('File "{}" not found in paths {}'.format(
47
+            file_path,
48
+            self._include_paths,
49
+        ))

+ 0 - 0
tests/fixtures/some_media/foo.txt View File


+ 0 - 0
tests/fixtures/some_media2/foo.txt View File


+ 18 - 0
tests/test_utils.py View File

@@ -1,5 +1,11 @@
1 1
 # coding: utf-8
2
+import os
3
+
4
+import pytest
5
+
2 6
 from synergine2.utils import ChunkManager
7
+from synergine2_cocos2d.exception import FileNotFound
8
+from synergine2_cocos2d.util import PathManager
3 9
 from tests import BaseTest
4 10
 
5 11
 
@@ -26,3 +32,15 @@ class TestUtils(BaseTest):
26 32
                 assert len(chunk) == 26
27 33
             else:
28 34
                 assert len(chunk) == 25
35
+
36
+    def test_path_manager(self):
37
+        path_manager = PathManager(['tests/fixtures/some_media'])
38
+        # file in thirst dir found
39
+        assert 'tests/fixtures/some_media/foo.txt' == path_manager.path('foo.txt')
40
+        # a non existing file is not found
41
+        with pytest.raises(FileNotFound):
42
+            path_manager.path('UNKNOWN')
43
+        # if add a folder to path manager paths
44
+        path_manager.add_included_path('tests/fixtures/some_media2')
45
+        # it is prior on path finding
46
+        assert 'tests/fixtures/some_media2/foo.txt' == path_manager.path('foo.txt')