1 /*
2                                     __
3                                    / _|
4   __ _ _   _ _ __ ___  _ __ __ _  | |_ ___  ___ ___
5  / _` | | | | '__/ _ \| '__/ _` | |  _/ _ \/ __/ __|
6 | (_| | |_| | | | (_) | | | (_| | | || (_) \__ \__ \
7  \__,_|\__,_|_|  \___/|_|  \__,_| |_| \___/|___/___/
8 
9 Copyright (C) 2019 Aurora Free Open Source Software.
10 Copyright (C) 2019 João Lourenço <joao@aurorafoss.org>
11 
12 This file is part of the Aurora Free Open Source Software. This
13 organization promote free and open source software that you can
14 redistribute and/or modify under the terms of the GNU Lesser General
15 Public License Version 3 as published by the Free Software Foundation or
16 (at your option) any later version approved by the Aurora Free Open Source
17 Software Organization. The license is available in the package root path
18 as 'LICENSE' file. Please review the following information to ensure the
19 GNU Lesser General Public License version 3 requirements will be met:
20 https://www.gnu.org/licenses/lgpl.html .
21 
22 Alternatively, this file may be used under the terms of the GNU General
23 Public License version 3 or later as published by the Free Software
24 Foundation. Please review the following information to ensure the GNU
25 General Public License requirements will be met:
26 https://www.gnu.org/licenses/gpl-3.0.html.
27 
28 NOTE: All products, services or anything associated to trademarks and
29 service marks used or referenced on this file are the property of their
30 respective companies/owners or its subsidiaries. Other names and brands
31 may be claimed as the property of others.
32 
33 For more info about intellectual property visit: aurorafoss.org or
34 directly send an email to: contact (at) aurorafoss.org .
35 */
36 
37 module aurorafw.entity.world;
38 
39 import aurorafw.entity.entity;
40 import aurorafw.entity.entitymanager;
41 import aurorafw.entity.icomponent;
42 import aurorafw.entity.componentmanager;
43 import aurorafw.entity.systemmanager;
44 import aurorafw.entity.system;
45 
46 version(unittest) import aurorafw.unit.assertion;
47 
48 
49 final class World
50 {
51 	@safe pure
52 	public this()
53 	{
54 		_component = new ComponentManager();
55 		_entity = new EntityManager();
56 		_system = new SystemManager(_entity);
57 	}
58 
59 
60 	@safe pure
61 	public EntityManager entity() { return _entity; } @property
62 
63 
64 	@safe pure
65 	public ComponentManager component() { return _component; } @property
66 
67 
68 	@safe pure
69 	public SystemManager system() { return _system; } @property
70 
71 
72 	@safe pure
73 	public void update()
74 	{
75 		_system.update;
76 	}
77 
78 
79 	@safe pure
80 	public void update(S : System)()
81 	{
82 		_system.update!S;
83 	}
84 
85 
86 	private EntityManager _entity;
87 	private ComponentManager _component;
88 	private SystemManager _system;
89 }
90 
91 
92 version(unittest)
93 {
94 	private class unittest_FooSystem : System
95 	{
96 		override public void update() { this.updatePolicy = UpdatePolicy.Manual; }
97 	}
98 
99 	private class unittest_BarSystem : System
100 	{
101 		@safe pure
102 		public this() { super(UpdatePolicy.Manual); }
103 
104 		override public void update() { this.updatePolicy = UpdatePolicy.Automatic; }
105 	}
106 
107 
108 	private class unittest_FooComponent : IComponent
109 	{
110 		int a;
111 	}
112 
113 	private class unittest_FooBarSystem : System
114 	{
115 		override public void update()
116 		{
117 			Entity[] arr = this.manager.entity.getAllWith!(unittest_FooComponent);
118 
119 			foreach(Entity e; arr)
120 			{
121 				e.modify!unittest_FooComponent(5);
122 			}
123 		}
124 	}
125 }
126 
127 
128 ///
129 @safe pure
130 @("World: System update")
131 unittest
132 {
133 	World world = new World();
134 
135 	unittest_FooSystem fooSys = new unittest_FooSystem();
136 	unittest_BarSystem barSys = new unittest_BarSystem();
137 	world.system.create(fooSys);
138 	world.system.create(barSys);
139 
140 	world.update(); // Only updates systems with Automatic Update Policy
141 
142 	assertEquals(fooSys.updatePolicy, fooSys.UpdatePolicy.Manual); // Got updated
143 	assertEquals(barSys.updatePolicy, barSys.UpdatePolicy.Manual); // Didn't get updated
144 
145 	world.system.update!unittest_BarSystem; // Every system can be updated manualy
146 
147 	assertEquals(barSys.updatePolicy, barSys.UpdatePolicy.Automatic); // Got updated
148 }
149 
150 
151 ///
152 @safe pure
153 @("World: Main loop")
154 unittest
155 {
156 	World world = new World();
157 
158 	world.system.create(new unittest_FooBarSystem);
159 	Entity e = world.entity.create();
160 	e.add!unittest_FooComponent;
161 
162 	world.update();
163 
164 	assertEquals(5, e.get!unittest_FooComponent.a); // Component variable modified in the update method
165 }
166 
167 
168 ///
169 @safe pure
170 @("World: Component Manager getter")
171 unittest
172 {
173 	World world = new World();
174 
175 	assertTrue(world._component is world.component);
176 }