renamed libpg to libbear
[physics.git] / src / entityManager.cpp
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
18 #include "entityManager.h"
19
20 #include <bear/debug.h>
21 #include <bear/Lock.h>
22 #include <bear/Autolock.h>
23 using namespace bear;
24
25 #include <set>
26 #include <SDL/SDL.h>
27
28 #include "Entities/Entity.h"
29 #include "Entities/Particle.h"
30 #include "Entities/PhysicsEntity.h"
31
32 #include "collisionManager.h"
33 #include "effectManager.h"
34
35 /// ***** Private Method Headers *****
36
37 static void updateParticles(float);
38 static void updatePhysics(float);
39 static void addOrRemoveParticles();
40 static void addOrRemovePhysics();
41
42 /// ***** Private Variables *****
43
44 typedef std::set<Particle*> setPart;
45 static setPart particles_To_Add;
46 static setPart active_Particles;
47 static setPart particles_To_Remove;
48
49 typedef std::set<PhysicsEntity*> setPhys;
50 static setPhys physics_To_Add;
51 static setPhys active_Physics;
52 static setPhys physics_To_Remove;
53
54 static Lock muSetPart;
55 static Lock muSetPhys;
56
57 /// ***** Initializers/Cleaners *****
58
59 void manager::init()
60 {
61     muSetPart.init();
62     muSetPhys.init();
63
64     collision::init();
65 }
66 void manager::clean()
67 {
68     collision::clean();
69
70     muSetPhys.fini();
71     muSetPart.fini();
72 }
73
74 /// ***** Public Methods *****
75
76 void manager::add(Entity* pe)
77 {
78     DASSERT(pe != NULL);
79
80     {
81         Particle* pp = dynamic_cast<Particle*>(pe);
82         if( pp != NULL )
83         {
84             particles_To_Add.insert(pp);
85             return;
86         }
87     }
88
89     {
90         PhysicsEntity* ppe = dynamic_cast<PhysicsEntity*>(pe);
91         if( ppe != NULL )
92         {
93             physics_To_Add.insert(ppe);
94             return;
95         }
96     }
97
98     DPF(0, "ENTITY TYPE NOT SUPPORTED BY addEntity()!!");
99 }
100 void manager::remove(Entity* pe)
101 {
102     DASSERT(pe != NULL);
103
104     {
105         Autolock lock( &muSetPart );
106         Particle* p = dynamic_cast<Particle*>(pe);
107         if( p != NULL )
108         {
109             particles_To_Remove.insert(p);
110             return;
111         }
112     }
113
114     {
115         Autolock lock( &muSetPhys );
116         PhysicsEntity* ppe = dynamic_cast<PhysicsEntity*>(pe);
117         if( ppe != NULL )
118         {
119             physics_To_Remove.insert(ppe);
120             return;
121         }
122     }
123
124     DPF(0, "ENTITY TYPE NOT SUPPORTED BY deleteEntity()!!");
125 }
126
127 void manager::handleInput()
128 {
129     effect::handleInput();
130 }
131 void manager::update(float time_step)
132 {
133     effect::update(time_step);
134
135     updateParticles(time_step);
136     updatePhysics(time_step);
137 }
138 void manager::draw()
139 {
140     {
141         Autolock lock( &muSetPart );
142
143         addOrRemoveParticles();
144
145         // draw active Particle*s
146         for( setPart::iterator it = active_Particles.begin();
147              it != active_Particles.end();
148              it++ )
149         {
150             (*it)->draw();
151         }
152     }
153
154     {
155         Autolock lock( &muSetPhys );
156
157         addOrRemovePhysics();
158
159         // draw active PhysicsEntity*s
160         for( setPhys::iterator it = active_Physics.begin();
161              it != active_Physics.end();
162              it++ )
163         {
164             (*it)->draw();
165         }
166     }
167 }
168
169 /// ***** Private Methods *****
170
171 void updateParticles(float time_step)
172 {
173     addOrRemoveParticles();
174
175     // update active Particle*s
176     for( setPart::iterator it = active_Particles.begin();
177          it != active_Particles.end();
178          it++ )
179     {
180         (*it)->update(time_step);
181     }
182 }
183 void updatePhysics(float time_step)
184 {
185     addOrRemovePhysics();
186
187     // apply collision math
188     collision::update(active_Physics);
189
190     // update active PhysicsEntity*s
191     for( setPhys::iterator it = active_Physics.begin();
192          it != active_Physics.end();
193          it++ )
194     {
195         (*it)->update(time_step);
196     }
197 }
198 void addOrRemoveParticles()
199 {
200     Autolock lock( &muSetPart );
201
202     // add new Particle*s to Active
203     for( setPart::iterator it = particles_To_Add.begin();
204          it != particles_To_Add.end();
205          it++ )
206     {
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         active_Particles.erase(*it);
217     }
218     particles_To_Remove.clear();
219 }
220 void addOrRemovePhysics()
221 {
222     Autolock lock( &muSetPhys );
223
224     // add new PhysicsEntity*s to Active
225     for( setPhys::iterator it = physics_To_Add.begin();
226          it != physics_To_Add.end();
227          it++ )
228     {
229         active_Physics.insert(*it);
230     }
231     physics_To_Add.clear();
232
233     // remove dead PhysicsEntity*s from Active
234     for( setPhys::iterator it = physics_To_Remove.begin();
235          it != physics_To_Remove.end();
236          it++ )
237     {
238         active_Physics.erase(*it);
239     }
240     physics_To_Remove.clear();
241 }