delete is now thread safe
[physics.git] / src / entityManager.cpp
CommitLineData
e68f847b
PG
1/*
2 * Copyright (C) 2008 Patrik Gornicz, Gornicz_P (at) hotmail (dot) com.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
054d658f 18#include "entityManager.h"
a483ed75
PG
19#include "debug.h"
20
33b8c69b 21#include <set>
5829cb66 22#include <SDL/SDL.h>
33b8c69b 23
3bccd1d7
PG
24#include "locks/Mutex.h"
25#include "locks/Autolock.h"
26
054d658f
PG
27#include "Entities/Entity.h"
28#include "Entities/Particle.h"
29#include "Entities/PhysicsEntity.h"
30
0ac1dc80 31#include "collisionManager.h"
a823a800 32#include "effectManager.h"
54fe85c5 33
ad9f1fb6 34/// ***** Private Method Headers *****
617dcc71 35
ad9f1fb6
PG
36void updateParticles(float);
37void updatePhysics(float);
f342ff31
PG
38void clearUpParticles();
39void clearUpPhysics();
ad9f1fb6
PG
40
41/// ***** Private Variables *****
617dcc71 42
f72f4a59 43typedef std::set<Particle*> setPart;
ad9f1fb6
PG
44setPart particles_To_Add;
45setPart active_Particles;
46setPart particles_To_Remove;
ad9f1fb6 47
f72f4a59 48typedef std::set<PhysicsEntity*> setPhys;
ad9f1fb6
PG
49setPhys physics_To_Add;
50setPhys active_Physics;
51setPhys physics_To_Remove;
ad9f1fb6 52
3bccd1d7
PG
53Mutex particleSetLock;
54Mutex physicsEntitySetLock;
5829cb66 55
617dcc71 56/// ***** Initializers/Cleaners *****
ad9f1fb6 57
d388f0ec 58void manager::init()
ad9f1fb6 59{
3bccd1d7
PG
60 particleSetLock.init();
61 physicsEntitySetLock.init();
5829cb66 62
54fe85c5 63 collision::init();
ad9f1fb6 64}
d388f0ec 65void manager::clean()
ad9f1fb6 66{
54fe85c5 67 collision::clean();
5829cb66 68
3bccd1d7
PG
69 physicsEntitySetLock.clean();
70 particleSetLock.clean();
ad9f1fb6
PG
71}
72
617dcc71
PG
73/// ***** Public Methods *****
74
d388f0ec 75void manager::add(Entity* e)
ad9f1fb6
PG
76{
77 {
d388f0ec
PG
78 Particle* p = dynamic_cast<Particle*>(e);
79 if( p != 0 )
80 {
81 particles_To_Add.insert(p);
82 return;
83 }
ad9f1fb6
PG
84 }
85
86 {
d388f0ec
PG
87 PhysicsEntity* p = dynamic_cast<PhysicsEntity*>(e);
88 if( p != 0 )
89 {
90 physics_To_Add.insert(p);
91 return;
92 }
ad9f1fb6
PG
93 }
94
ca2d526e 95 DPF(0, "ENTITY TYPE NOT SUPPORTED BY addEntity()!!");
ad9f1fb6 96}
d388f0ec 97void manager::remove(Entity* e)
ad9f1fb6
PG
98{
99 {
f342ff31 100 Autolock lock( particleSetLock );
d388f0ec
PG
101 Particle* p = dynamic_cast<Particle*>(e);
102 if( p != 0 )
103 {
104 particles_To_Remove.insert(p);
105 return;
106 }
ad9f1fb6
PG
107 }
108
109 {
f342ff31 110 Autolock lock( physicsEntitySetLock );
d388f0ec
PG
111 PhysicsEntity* p = dynamic_cast<PhysicsEntity*>(e);
112 if( p != 0 )
113 {
114 physics_To_Remove.insert(p);
115 return;
116 }
ad9f1fb6
PG
117 }
118
ca2d526e 119 DPF(0, "ENTITY TYPE NOT SUPPORTED BY deleteEntity()!!");
ad9f1fb6
PG
120}
121
d388f0ec 122void manager::handleInput()
ad9f1fb6 123{
a823a800 124 effect::handleInput();
ad9f1fb6 125}
d388f0ec 126void manager::update(float time_step)
ad9f1fb6 127{
a823a800
PG
128 effect::update(time_step);
129
ad9f1fb6
PG
130 updateParticles(time_step);
131 updatePhysics(time_step);
132}
d388f0ec 133void manager::draw()
ad9f1fb6 134{
f342ff31 135 clearUpParticles();
3bccd1d7
PG
136 {
137 Autolock lock( particleSetLock );
138 DPF(0, "Particle Draw Start");
139
5829cb66
PG
140 // update active Particle*s
141 for( setPart::iterator it = active_Particles.begin();
142 it != active_Particles.end();
143 it++ )
144 {
145 (*it)->draw();
146 }
ad9f1fb6 147
3bccd1d7
PG
148 DPF(0, "Particle Draw End");
149 }
150
f342ff31 151 clearUpPhysics();
3bccd1d7
PG
152 {
153 Autolock lock( physicsEntitySetLock );
154 DPF(0, "Physics Draw Start");
155
5829cb66
PG
156 // update active PhysicsEntity*s
157 for( setPhys::iterator it = active_Physics.begin();
158 it != active_Physics.end();
159 it++ )
160 {
161 (*it)->draw();
162 }
3bccd1d7
PG
163
164 DPF(0, "Physics Draw End");
165 }
ad9f1fb6
PG
166}
167
168/// ***** Private Methods *****
617dcc71 169
ad9f1fb6
PG
170void updateParticles(float time_step)
171{
f342ff31 172 clearUpParticles();
ad9f1fb6
PG
173
174 // update active Particle*s
175 for( setPart::iterator it = active_Particles.begin();
176 it != active_Particles.end();
177 it++ )
178 {
179 (*it)->update(time_step);
180 }
181}
182void updatePhysics(float time_step)
183{
f342ff31 184 clearUpPhysics();
ad9f1fb6 185
54fe85c5 186 // apply collision math
2869e2e8 187 collision::update(active_Physics);
54fe85c5 188
ad9f1fb6
PG
189 // update active PhysicsEntity*s
190 for( setPhys::iterator it = active_Physics.begin();
191 it != active_Physics.end();
192 it++ )
193 {
194 (*it)->update(time_step);
195 }
196}
f342ff31
PG
197void clearUpParticles()
198{
199 Autolock lock( particleSetLock );
200
201 // add new Particle*s to Active
202 for( setPart::iterator it = particles_To_Add.begin();
203 it != particles_To_Add.end();
204 it++ )
205 {
206 DPF(0, "Particle Insert");
207 active_Particles.insert(*it);
208 }
209 particles_To_Add.clear();
210
211 // remove dead Particle*s from Active
212 for( setPart::iterator it = particles_To_Remove.begin();
213 it != particles_To_Remove.end();
214 it++ )
215 {
216 DPF(0, "Particle Delete");
217 active_Particles.erase(*it);
218 }
219 particles_To_Remove.clear();
220}
221void clearUpPhysics()
222{
223 Autolock lock( physicsEntitySetLock );
224
225 // add new PhysicsEntity*s to Active
226 for( setPhys::iterator it = physics_To_Add.begin();
227 it != physics_To_Add.end();
228 it++ )
229 {
230 DPF(0, "Physics Insert");
231 active_Physics.insert(*it);
232 }
233 physics_To_Add.clear();
234
235 // remove dead PhysicsEntity*s from Active
236 for( setPhys::iterator it = physics_To_Remove.begin();
237 it != physics_To_Remove.end();
238 it++ )
239 {
240 DPF(0, "Physics Delete");
241 active_Physics.erase(*it);
242 }
243 physics_To_Remove.clear();
244}