1 /**
2  * Unit tests for system.d and IFamily
3  *
4  */
5 module engineFamilyIntegration_test;
6 
7 import ashd.core.component              : Component;
8 import ashd.core.componentMatchingFamily: ComponentMatchingFamily;
9 import ashd.core.engine                 : Engine, IFamily, Node, NodeList;
10 import ashd.core.entity                 : Entity;
11 
12 
13 import std.datetime  : dur, Duration, SysTime;
14 
15 
16 int main()
17 {
18     (new EngineAndFamilyIntegrationTests).testFamilyIsInitiallyEmpty();
19     (new EngineAndFamilyIntegrationTests).testNodeContainsEntityProperties();
20     (new EngineAndFamilyIntegrationTests).testCorrectEntityAddedToFamilyWhenAccessFamilyFirst();
21     (new EngineAndFamilyIntegrationTests).testCorrectEntityAddedToFamilyWhenAccessFamilySecond();
22     (new EngineAndFamilyIntegrationTests).testCorrectEntityAddedToFamilyWhenComponentsAdded();
23     (new EngineAndFamilyIntegrationTests).testIncorrectEntityNotAddedToFamilyWhenAccessFamilyFirst();
24     (new EngineAndFamilyIntegrationTests).testIncorrectEntityNotAddedToFamilyWhenAccessFamilySecond();
25     (new EngineAndFamilyIntegrationTests).testEntityRemovedFromFamilyWhenComponentRemovedAndFamilyAlreadyAccessed();
26     (new EngineAndFamilyIntegrationTests).testEntityRemovedFromFamilyWhenComponentRemovedAndFamilyNotAlreadyAccessed();
27     (new EngineAndFamilyIntegrationTests).testEntityRemovedFromFamilyWhenRemovedFromEngineAndFamilyAlreadyAccessed();
28     (new EngineAndFamilyIntegrationTests).testEntityRemovedFromFamilyWhenRemovedFromEngineAndFamilyNotAlreadyAccessed();
29     (new EngineAndFamilyIntegrationTests).familyContainsOnlyMatchingEntities();
30     (new EngineAndFamilyIntegrationTests).familyContainsAllMatchingEntities();
31     (new EngineAndFamilyIntegrationTests).releaseFamilyEmptiesNodeList();
32     (new EngineAndFamilyIntegrationTests).releaseFamilySetsNextNodeToNull();
33     (new EngineAndFamilyIntegrationTests).removeAllEntitiesDoesWhatItSays();
34 
35 
36     return 0;
37 }
38 
39 /**
40  * Tests the family class through the engine class. Left over from a previous 
41  * architecture but retained because all tests shoudl still pass.
42  */
43 public class EngineAndFamilyIntegrationTests
44 {
45     Engine mEngine;
46     ComponentMatchingFamily!MockNode mMockNodeFamily;
47 
48 
49     public this()
50     {
51         mEngine = new Engine();
52         mMockNodeFamily = new ComponentMatchingFamily!MockNode( mEngine );
53         mEngine.registerFamily!MockNode( mMockNodeFamily );
54     }
55 
56     public void testFamilyIsInitiallyEmpty()
57     {
58         NodeList nodes = mEngine.getNodeList!MockNode();
59         assert( nodes.head is null );
60     }
61 
62     public void testNodeContainsEntityProperties()
63     {
64         Entity entity = new Entity();
65         Point point   = new Point();
66         Matrix matrix = new Matrix();
67         entity.add( point );
68         entity.add( matrix );
69         
70         NodeList nodes = mEngine.getNodeList!MockNode( );
71         mEngine.addEntity( entity );
72         assert( nodes.head.entity.get!Point is point );
73         assert( nodes.head.entity.get!Matrix is matrix );
74     }
75 
76     public void testCorrectEntityAddedToFamilyWhenAccessFamilyFirst()
77     {
78         Entity entity = new Entity();
79         entity.add( new Point() );
80         entity.add( new Matrix() );
81         NodeList nodes = mEngine.getNodeList!MockNode();
82         mEngine.addEntity( entity );
83 
84         assert( nodes.head.entity is entity );
85     }
86 
87     public void testCorrectEntityAddedToFamilyWhenAccessFamilySecond()
88     {
89         Entity entity = new Entity();
90         entity.add( new Point() );
91         entity.add( new Matrix() );
92         mEngine.addEntity( entity );
93         NodeList nodes = mEngine.getNodeList!MockNode();
94         assert( nodes.head.entity is entity );
95     }
96 
97     public void testCorrectEntityAddedToFamilyWhenComponentsAdded()
98     {
99         Entity entity = new Entity();
100         mEngine.addEntity( entity );
101         NodeList nodes = mEngine.getNodeList!MockNode();
102         entity.add( new Point() );
103         entity.add( new Matrix() );
104         assert( nodes.head.entity is entity );
105     }
106 
107     public void testIncorrectEntityNotAddedToFamilyWhenAccessFamilyFirst()
108     {
109         Entity entity = new Entity();
110         NodeList nodes = mEngine.getNodeList!MockNode();
111         mEngine.addEntity( entity );
112         assert( nodes.head is null );
113     }
114 
115     public void testIncorrectEntityNotAddedToFamilyWhenAccessFamilySecond()
116     {
117         Entity entity = new Entity();
118         mEngine.addEntity( entity );
119         NodeList nodes = mEngine.getNodeList!MockNode();
120         assert( nodes.head is null );
121     }
122 
123     public void testEntityRemovedFromFamilyWhenComponentRemovedAndFamilyAlreadyAccessed()
124     {
125         Entity entity = new Entity();
126         entity.add( new Point() );
127         entity.add( new Matrix() );
128         mEngine.addEntity( entity );
129         NodeList nodes = mEngine.getNodeList!MockNode();
130         entity.remove!Point();
131         assert( nodes.head is null );
132     }
133 
134     public void testEntityRemovedFromFamilyWhenComponentRemovedAndFamilyNotAlreadyAccessed()
135     {
136         Entity entity = new Entity();
137         entity.add( new Point() );
138         entity.add( new Matrix() );
139         mEngine.addEntity( entity );
140         entity.remove!Point();
141         NodeList nodes = mEngine.getNodeList!MockNode();
142         assert( nodes.head is null );
143     }
144 
145     public void testEntityRemovedFromFamilyWhenRemovedFromEngineAndFamilyAlreadyAccessed()
146     {
147         Entity entity = new Entity();
148         entity.add( new Point() );
149         entity.add( new Matrix() );
150         mEngine.addEntity( entity );
151         NodeList nodes = mEngine.getNodeList!MockNode();
152         mEngine.removeEntity( entity );
153         assert( nodes.head is null );
154     }
155 
156     public void testEntityRemovedFromFamilyWhenRemovedFromEngineAndFamilyNotAlreadyAccessed()
157     {
158         Entity entity = new Entity();
159         entity.add( new Point() );
160         entity.add( new Matrix() );
161         mEngine.addEntity( entity );
162         mEngine.removeEntity( entity );
163         NodeList nodes = mEngine.getNodeList!MockNode();
164         assert( nodes.head is null );
165     }
166 
167     public void familyContainsOnlyMatchingEntities()
168     {
169         Entity[] entities;
170         for ( int i = 0; i < 5; ++i )
171         {
172             Entity entity = new Entity();
173             entity.add( new Point() );
174             entity.add( new Matrix() );
175             entities ~= entity;
176             mEngine.addEntity( entity );
177         }
178         
179         NodeList nodes = mEngine.getNodeList!MockNode();
180         Node node;
181         int i;
182         for( node = nodes.head; node; node = node.next )
183         {
184             assert( entities[i++] is node.entity );
185         }
186     }
187 
188     public void familyContainsAllMatchingEntities() 
189     {
190         Entity[] entities;
191         for ( int i = 0; i < 5; ++i )
192         {
193             Entity entity = new Entity();
194             entity.add( new Point() );
195             entity.add( new Matrix() );
196             entities ~= entity;
197             mEngine.addEntity( entity );
198         }
199         
200         NodeList nodes = mEngine.getNodeList!MockNode();
201         Node node;
202         int i;
203         for( node = nodes.head; node; node = node.next )
204         {
205             assert( entities[i++] is node.entity );
206         }
207         assert( i==5 );
208     }
209 
210     public void releaseFamilyEmptiesNodeList()
211     {
212         Entity entity = new Entity();
213         entity.add( new Point() );
214         entity.add( new Matrix() );
215         mEngine.addEntity( entity );
216         NodeList nodes = mEngine.getNodeList!MockNode();
217         mEngine.releaseNodeList!MockNode();
218         assert( nodes.head is null );
219     }
220 
221     public void releaseFamilySetsNextNodeToNull()
222     {
223         Entity[] entities;
224         for( int i = 0; i < 5; ++i )
225         {
226             Entity entity = new Entity();
227             entity.add( new Point() );
228             entity.add( new Matrix() );
229             entities ~= entity;
230             mEngine.addEntity( entity );
231         }
232         
233         NodeList nodes = mEngine.getNodeList!MockNode();
234         Node node = nodes.head.next;
235         mEngine.releaseNodeList!MockNode();
236         assert( node.next is null );
237     }
238 
239     public void removeAllEntitiesDoesWhatItSays()
240     {
241         Entity entity = new Entity();
242         entity.add( new Point() );
243         entity.add( new Matrix() );
244         mEngine.addEntity( entity );
245         entity = new Entity();
246         entity.add( new Point() );
247         entity.add( new Matrix() );
248         mEngine.addEntity( entity );
249         NodeList nodes = mEngine.getNodeList!MockNode();
250         mEngine.removeAllEntities();
251         assert( nodes.head is null );
252     }
253 
254 
255 } // EngineAndFamilyIntegrationTests
256 
257 class MockNode: Node
258 {
259     public Point point;
260     public Matrix matrix;
261 }
262 
263 class Point: Component
264 { 
265     int x; int y; 
266 }
267 
268 class Matrix: Component
269 {
270     int[2][2] data;
271 }
272 
273