Browse Source

fix final tiled conversion for shared data (with ugly code)

Bastien Sevajol 6 years ago
parent
commit
4c7452a8de
5 changed files with 73 additions and 22 deletions
  1. 4 1
      sandbox/tile/run.py
  2. 31 18
      synergine2/share.py
  3. 10 2
      synergine2/simulation.py
  4. 2 1
      synergine2_xyz/move.py
  5. 26 0
      tests/test_share.py

+ 4 - 1
sandbox/tile/run.py View File

@@ -8,6 +8,7 @@ from random import seed
8 8
 synergine2_path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../'))
9 9
 sys.path.append(synergine2_path)
10 10
 
11
+from synergine2_xyz.move import MoveToMechanism, MoveToBehaviour
11 12
 from sandbox.tile.simulation.subject import Man
12 13
 from sandbox.tile.simulation.base import TileStrategySimulation
13 14
 from sandbox.tile.simulation.base import TileStrategySubjects
@@ -24,11 +25,13 @@ def main(map_dir_path: str, seed_value: int=42):
24 25
 
25 26
     config = Config()
26 27
     config.load_files(['sandbox/tile/config.yaml'])
27
-    logger = get_default_logger(level=logging.DEBUG)
28
+    logger = get_default_logger(level=logging.ERROR)
28 29
 
29 30
     map_file_path = 'sandbox/tile/{}.tmx'.format(os.path.join(map_dir_path, os.path.basename(map_dir_path)))
30 31
 
31 32
     simulation = TileStrategySimulation(config, map_file_path=map_file_path)
33
+    simulation.add_to_index(Man, MoveToBehaviour, MoveToMechanism)
34
+
32 35
     subjects = TileStrategySubjects(simulation=simulation)
33 36
 
34 37
     for position in ((0, 2),):

+ 31 - 18
synergine2/share.py View File

@@ -30,16 +30,17 @@ class TrackedDict(dict):
30 30
 
31 31
     def __init__(self, seq=None, **kwargs):
32 32
         self.key = kwargs.pop('key')
33
+        self.original_key = kwargs.pop('original_key')
33 34
         self.shared = kwargs.pop('shared')
34 35
         super().__init__(seq, **kwargs)
35 36
 
36 37
     def __setitem__(self, key, value):
37 38
         super().__setitem__(key, value)
38
-        self.shared.set(self.key, dict(self))
39
+        self.shared.set(self.key, dict(self), original_key=self.original_key)
39 40
 
40 41
     def setdefault(self, k, d=None):
41 42
         v = super().setdefault(k, d)
42
-        self.shared.set(self.key, dict(self))
43
+        self.shared.set(self.key, dict(self), original_key=self.original_key)
43 44
         return v
44 45
     # TODO: Cover all methods
45 46
 
@@ -49,12 +50,13 @@ class TrackedList(list):
49 50
 
50 51
     def __init__(self, seq=(), **kwargs):
51 52
         self.key = kwargs.pop('key')
53
+        self.original_key = kwargs.pop('original_key')
52 54
         self.shared = kwargs.pop('shared')
53 55
         super().__init__(seq)
54 56
 
55 57
     def append(self, p_object):
56 58
         super().append(p_object)
57
-        self.shared.set(self.key, list(self))
59
+        self.shared.set(self.key, list(self), original_key=self.original_key)
58 60
 
59 61
     # TODO: Cover all methods
60 62
 
@@ -86,15 +88,20 @@ class SharedDataManager(object):
86 88
         self.commit()
87 89
         self._data = {}
88 90
 
89
-    def set(self, key: str, value: typing.Any) -> None:
91
+    def set(self, key: str, value: typing.Any, original_key: str=None) -> None:
90 92
         try:
91
-            special_type = self._special_types[key]
92
-            value = special_type(value, key=key, shared=self)
93
+            special_type, original_key_ = self._special_types[key]
94
+            value = special_type(value, key=key, shared=self, original_key=original_key)
93 95
         except KeyError:
94
-            pass
96
+            try:
97
+                # TODO: Code degeu pour gerer les {id}_truc
98
+                special_type, original_key_ = self._special_types[original_key]
99
+                value = special_type(value, key=key, shared=self, original_key=original_key)
100
+            except KeyError:
101
+                pass
95 102
 
96 103
         self._data[key] = value
97
-        self._modified_keys.add(key)
104
+        self._modified_keys.add((key, original_key))
98 105
 
99 106
     def get(self, *key_args: typing.Union[str, float, int]) -> typing.Any:
100 107
         key = '_'.join([str(v) for v in key_args])
@@ -111,25 +118,31 @@ class SharedDataManager(object):
111 118
             special_type = None
112 119
 
113 120
             try:
114
-                special_type = self._special_types[key]
121
+                special_type, original_key = self._special_types[key]
115 122
             except KeyError:
116 123
                 pass
117 124
 
118 125
             if special_type:
119
-                self._data[key] = special_type(value, key=key, shared=self)
126
+                self._data[key] = special_type(value, key=key, shared=self, original_key=original_key)
120 127
             else:
121 128
                 self._data[key] = value
122 129
 
123 130
         return self._data[key]
124 131
 
125 132
     def commit(self) -> None:
126
-        for key in self._modified_keys:
133
+        for key, original_key in self._modified_keys:
127 134
             try:
128
-                special_type = self._special_types[key]
135
+                special_type, original_key = self._special_types[key]
129 136
                 value = special_type.base(self.get(key))
130 137
                 self._r.set(key, pickle.dumps(value))
131 138
             except KeyError:
132
-                self._r.set(key, pickle.dumps(self.get(key)))
139
+                # Code degeu pour gerer les {id}_truc
140
+                try:
141
+                    special_type, original_key = self._special_types[original_key]
142
+                    value = special_type.base(self.get(key))
143
+                    self._r.set(key, pickle.dumps(value))
144
+                except KeyError:
145
+                    self._r.set(key, pickle.dumps(self.get(key)))
133 146
         self._modified_keys = set()
134 147
 
135 148
     def refresh(self) -> None:
@@ -156,11 +169,11 @@ class SharedDataManager(object):
156 169
         indexes = indexes or []
157 170
 
158 171
         if type(value) is dict:
159
-            value = TrackedDict(value, key=key, shared=shared)
160
-            self._special_types[key] = TrackedDict
172
+            value = TrackedDict(value, key=key, shared=shared, original_key=key)
173
+            self._special_types[key] = TrackedDict, key
161 174
         elif type(value) is list:
162
-            value = TrackedList(value, key=key, shared=shared)
163
-            self._special_types[key] = TrackedList
175
+            value = TrackedList(value, key=key, shared=shared, original_key=key)
176
+            self._special_types[key] = TrackedList, key
164 177
 
165 178
         def get_key(obj):
166 179
             return key
@@ -186,7 +199,7 @@ class SharedDataManager(object):
186 199
             except UnknownSharedData:
187 200
                 pass  # If no shared data, no previous value to remove
188 201
 
189
-            self.set(key_formatter(self_), value_)
202
+            self.set(key_formatter(self_), value_, original_key=key)
190 203
 
191 204
             for index in indexes:
192 205
                 index.add(value_)

+ 10 - 2
synergine2/simulation.py View File

@@ -13,13 +13,21 @@ class Intention(object):
13 13
 
14 14
 
15 15
 class IntentionManager(object):
16
-    def __init__(self) -> None:
17
-        self.intentions = {}  # type: typing.Dict[typing.Type[Intention], Intention]
16
+    intentions = shared.create(['{id}', 'intentions'], {})  # type: typing.Dict[typing.Type[Intention], Intention]
17
+
18
+    def __init__(self):
19
+        self._id = id(self)
20
+        self.intentions = {}
21
+
22
+    @property
23
+    def id(self) -> int:
24
+        return self._id
18 25
 
19 26
     def set(self, intention: Intention) -> None:
20 27
         self.intentions[type(intention)] = intention
21 28
 
22 29
     def get(self, intention_type: typing.Type[Intention]) -> Intention:
30
+        # TODO: Raise specialised exception if KeyError
23 31
         return self.intentions[intention_type]
24 32
 
25 33
 

+ 2 - 1
synergine2_xyz/move.py View File

@@ -127,7 +127,7 @@ class MoveToBehaviour(SubjectBehaviour):
127 127
     def run(self, data):
128 128
         # TODO: on fait vraiment rien ici ? Note: meme si il n'y a pas de new_path, l'action doit s'effectuer
129 129
         # du moment qu'il y a une intention de move
130
-        move_to_data = data[self.move_to_mechanism]
130
+        move_to_data = data[self.move_to_mechanism.__name__]
131 131
         if move_to_data:
132 132
             return move_to_data
133 133
         return False
@@ -151,6 +151,7 @@ class MoveToBehaviour(SubjectBehaviour):
151 151
             new_position = move.path[move.path_progression]
152 152
             previous_position = self.subject.position
153 153
             self.subject.position = new_position
154
+            self.subject.intentions.set(move)
154 155
 
155 156
             return [MoveEvent(self.subject.id, previous_position, new_position)]
156 157
 

+ 26 - 0
tests/test_share.py View File

@@ -133,6 +133,32 @@ class TestShare(BaseTest):
133 133
         assert shared.get('data') == ['foo', 'bar', 'bAr']
134 134
         assert pickle.loads(shared._r.get('data')) == ['foo', 'bar', 'bAr']
135 135
 
136
+    def test_update_list_with_pointer__composite_key(self):
137
+        shared = share.SharedDataManager()
138
+
139
+        class Foo(object):
140
+            data = shared.create(['{id}', 'data'], [])
141
+
142
+            def __init__(self):
143
+                self.id = id(self)
144
+
145
+        foo = Foo()
146
+        foo.data = ['foo']
147
+
148
+        assert shared.get(str(id(foo)) + '_data') == ['foo']
149
+
150
+        foo.data.append('bar')
151
+        assert shared.get(str(id(foo)) + '_data') == ['foo', 'bar']
152
+
153
+        shared.commit()
154
+        assert shared.get(str(id(foo)) + '_data') == ['foo', 'bar']
155
+        assert pickle.loads(shared._r.get(str(id(foo)) + '_data')) == ['foo', 'bar']
156
+
157
+        foo.data.append('bAr')
158
+        shared.commit()
159
+        assert shared.get(str(id(foo)) + '_data') == ['foo', 'bar', 'bAr']
160
+        assert pickle.loads(shared._r.get(str(id(foo)) + '_data')) == ['foo', 'bar', 'bAr']
161
+
136 162
     def test_refresh_without_commit(self):
137 163
         shared = share.SharedDataManager()
138 164