Bastien Sevajol пре 6 година
родитељ
комит
630e1f06b6
4 измењених фајлова са 62 додато и 25 уклоњено
  1. 1 1
      synergine2/share.py
  2. 19 8
      synergine2/simulation.py
  3. 16 12
      synergine2_xyz/xyz.py
  4. 26 4
      tests/test_xyz.py

+ 1 - 1
synergine2/share.py Прегледај датотеку

@@ -176,7 +176,7 @@ class SharedDataManager(object):
176 176
             key_formatter = get_key
177 177
 
178 178
         def fget(self_):
179
-            return self.get(key)
179
+            return self.get(key_formatter(self_))
180 180
 
181 181
         def fset(self_, value_):
182 182
             try:

+ 19 - 8
synergine2/simulation.py Прегледај датотеку

@@ -52,13 +52,12 @@ class Subject(BaseObject):
52 52
         else:
53 53
             self.intentions = IntentionManager()
54 54
 
55
-        # TODO: Revoir le mechanisme de collection: utilité, usage avec les process, etc
56
-        # for collection in self.collections:
57
-        #     self.simulation.collections[collection].append(self)
58
-
59 55
     @property
60 56
     def id(self) -> int:
61
-        return self._id
57
+        try:
58
+            return self._id
59
+        except AttributeError:
60
+            pass
62 61
 
63 62
     def change_id(self, id_: int) -> None:
64 63
         self._id = id_
@@ -75,6 +74,9 @@ class Subject(BaseObject):
75 74
 
76 75
         subject_classes[self._id] = id(type(self))
77 76
 
77
+        for collection in self.collections:
78
+            self.simulation.collections.setdefault(collection, []).append(self.id)
79
+
78 80
     def __str__(self):
79 81
         return self.__repr__()
80 82
 
@@ -100,6 +102,10 @@ class Subjects(list):
100 102
         self._auto_expose = True
101 103
         super().__init__(*args, **kwargs)
102 104
 
105
+        if self.auto_expose:
106
+            for subject in self:
107
+                subject.expose()
108
+
103 109
     @property
104 110
     def auto_expose(self) -> bool:
105 111
         return self._auto_expose
@@ -135,6 +141,10 @@ class Subjects(list):
135 141
         if self.auto_expose:
136 142
             p_object.expose()
137 143
 
144
+    def extend(self, iterable):
145
+        for item in iterable:
146
+            self.append(item)
147
+
138 148
 
139 149
 class Simulation(BaseObject):
140 150
     accepted_subject_class = Subjects
@@ -143,13 +153,13 @@ class Simulation(BaseObject):
143 153
     subject_behaviours_index = shared.create('subject_behaviours_index', {})
144 154
     subject_mechanisms_index = shared.create('subject_mechanisms_index', {})
145 155
     subject_classes = shared.create('subject_classes', {})
156
+    collections = shared.create('collections', {})
146 157
 
147 158
     def __init__(
148 159
         self,
149 160
         config: Config,
150 161
     ):
151 162
         self.config = config
152
-        self.collections = collections.defaultdict(list)
153 163
         self._subjects = None  # type: Subjects
154 164
 
155 165
         # Should contain all usable class of Behaviors, Mechanisms, SubjectBehaviourSelectors,
@@ -172,9 +182,10 @@ class Simulation(BaseObject):
172 182
                 simulation=self,
173 183
             )
174 184
 
175
-    def add_to_index(self, class_: type) -> None:
185
+    def add_to_index(self, *classes: type) -> None:
176 186
         assert not self._index_locked
177
-        self._index[id(class_)] = class_
187
+        for class_ in classes:
188
+            self._index[id(class_)] = class_
178 189
 
179 190
     @property
180 191
     def index(self) -> typing.Dict[int, type]:

+ 16 - 12
synergine2_xyz/xyz.py Прегледај датотеку

@@ -5,6 +5,7 @@ from math import degrees
5 5
 from math import sqrt
6 6
 
7 7
 from synergine2.exceptions import SynergineException
8
+from synergine2.share import shared
8 9
 from synergine2.simulation import Subject
9 10
 
10 11
 """
@@ -115,21 +116,23 @@ class XYZSubjectMixinMetaClass(type):
115 116
 
116 117
 
117 118
 class XYZSubjectMixin(object, metaclass=XYZSubjectMixinMetaClass):
119
+    position = shared.create(['{id}', 'counter'], (0, 0, 0))
120
+
118 121
     def __init__(self, *args, **kwargs):
119 122
         """
120 123
         :param position: tuple with (x, y, z)
121 124
         """
122
-        self._position = kwargs.pop('position')
123
-        self.previous_direction = None
124
-        super().__init__(*args, **kwargs)
125
+        position = None
126
+        try:
127
+            position = kwargs.pop('position')
128
+        except KeyError:
129
+            pass
125 130
 
126
-    @property
127
-    def position(self):
128
-        return self._position
131
+        self.previous_direction = None  # TODO: shared
132
+        super().__init__(*args, **kwargs)
129 133
 
130
-    @position.setter
131
-    def position(self, value):
132
-        self._position = value
134
+        if position:
135
+            self.position = position
133 136
 
134 137
 
135 138
 class ProximityMixin(object):
@@ -152,8 +155,9 @@ class ProximityMixin(object):
152 155
             # TODO: Optimiser en calculant directement les positions alentours et
153 156
             # en regardant si elles sont occupés dans subjects.xyz par un subject
154 157
             # etant dans fell_collection
155
-            for subject in simulation.collections.get(feel_collection, []):
156
-                if subject == exclude_subject:
158
+            for subject_id in simulation.collections.get(feel_collection, []):
159
+                subject = simulation.get_or_create_subject(subject_id)
160
+                if subject.id == exclude_subject.id:
157 161
                     continue
158 162
 
159 163
                 if self.have_to_check_position_is_possible() and not simulation.is_possible_position(subject.position):
@@ -175,7 +179,7 @@ class ProximityMixin(object):
175 179
                         self.direction_round_decimals,
176 180
                     )
177 181
                     subjects.append({
178
-                        'subject': subject,
182
+                        'subject_id': subject.id,
179 183
                         'direction': direction,
180 184
                         'distance': distance,
181 185
                     })

+ 26 - 4
tests/test_xyz.py Прегледај датотеку

@@ -1,6 +1,7 @@
1 1
 # coding: utf-8
2 2
 # -*- coding: utf-8 -*-
3 3
 from synergine2.config import Config
4
+from synergine2.share import shared
4 5
 from synergine2.simulation import Subject
5 6
 from synergine2_xyz.mechanism import ProximitySubjectMechanism
6 7
 from synergine2_xyz.simulation import XYZSimulation
@@ -22,7 +23,13 @@ class MyProximityMechanism(ProximitySubjectMechanism):
22 23
 
23 24
 class TestXYZ(BaseTest):
24 25
     def test_proximity_mechanism_with_one(self):
26
+        shared.reset()
25 27
         simulation = XYZSimulation(Config())
28
+        simulation.add_to_index(
29
+            MyProximityMechanism,
30
+            MySubject,
31
+        )
32
+
26 33
         subject = MySubject(Config(), simulation, position=(0, 0, 0))
27 34
         other_subject = MySubject(Config(), simulation, position=(5, 0, 0))
28 35
 
@@ -30,6 +37,7 @@ class TestXYZ(BaseTest):
30 37
             [subject, other_subject],
31 38
             simulation=simulation,
32 39
         )
40
+        simulation.subjects.auto_expose = False
33 41
 
34 42
         proximity_mechanism = MyProximityMechanism(
35 43
             config=Config(),
@@ -42,13 +50,19 @@ class TestXYZ(BaseTest):
42 50
             subject=other_subject,
43 51
         )
44 52
         assert [{
45
-            'subject': other_subject,
53
+            'subject_id': other_subject.id,
46 54
             'direction': 90.0,
47 55
             'distance': 5.0,
48 56
         }] == proximity_mechanism.run()
49 57
 
50 58
     def test_proximity_mechanism_excluding(self):
59
+        shared.reset()
51 60
         simulation = XYZSimulation(Config())
61
+        simulation.add_to_index(
62
+            MyProximityMechanism,
63
+            MySubject,
64
+        )
65
+
52 66
         subject = MySubject(Config(), simulation, position=(0, 0, 0))
53 67
         other_subject = MySubject(Config(), simulation, position=(11, 0, 0))
54 68
 
@@ -56,6 +70,7 @@ class TestXYZ(BaseTest):
56 70
             [subject, other_subject],
57 71
             simulation=simulation,
58 72
         )
73
+        simulation.subjects.auto_expose = False
59 74
 
60 75
         proximity_mechanism = MyProximityMechanism(
61 76
             config=Config(),
@@ -71,7 +86,13 @@ class TestXYZ(BaseTest):
71 86
         assert [] == proximity_mechanism.run()
72 87
 
73 88
     def test_proximity_mechanism_with_multiple(self):
89
+        shared.reset()
74 90
         simulation = XYZSimulation(Config())
91
+        simulation.add_to_index(
92
+            MyProximityMechanism,
93
+            MySubject,
94
+        )
95
+
75 96
         subject = MySubject(Config(), simulation, position=(0, 0, 0))
76 97
         other_subjects = []
77 98
 
@@ -80,6 +101,7 @@ class TestXYZ(BaseTest):
80 101
 
81 102
         simulation.subjects = XYZSubjects([subject], simulation=simulation)
82 103
         simulation.subjects.extend(other_subjects)
104
+        simulation.subjects.auto_expose = False
83 105
 
84 106
         proximity_mechanism = MyProximityMechanism(
85 107
             config=Config(),
@@ -91,17 +113,17 @@ class TestXYZ(BaseTest):
91 113
         assert [
92 114
             {
93 115
                 'direction': 0,
94
-                'subject': other_subjects[0],
116
+                'subject_id': other_subjects[0].id,
95 117
                 'distance': 0.0,
96 118
             },
97 119
             {
98 120
                 'direction': 135.0,
99
-                'subject': other_subjects[1],
121
+                'subject_id': other_subjects[1].id,
100 122
                 'distance': 1.41
101 123
             },
102 124
             {
103 125
                 'direction': 135.0,
104
-                'subject': other_subjects[2],
126
+                'subject_id': other_subjects[2].id,
105 127
                 'distance': 2.83
106 128
             },
107 129
         ] == data