Spinning Topp Logo BlackTopp Studios
inc
debrismanager.cpp
Go to the documentation of this file.
1 // © Copyright 2010 - 2016 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine 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  The Mezzanine Engine 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 The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _debrismanager_cpp
41 #define _debrismanager_cpp
42 
43 /// @file
44 /// @brief This file contains the implementation for the manager that manages debris objects in a world.
45 
46 #include "debrismanager.h"
47 #include "rigiddebris.h"
48 #include "softdebris.h"
49 
50 #include "Physics/physicsmanager.h"
51 #include "entresol.h"
52 #include "world.h"
53 
54 namespace Mezzanine
55 {
56  ///////////////////////////////////////////////////////////////////////////////
57  // DebrisUpdateWorkUnit Methods
58 
60  { }
61 
63  { return *this; }
64 
66  TargetManager(Target) { }
67 
69  { }
70 
71  ///////////////////////////////////////////////////////////////////////////////
72  // Utility
73 
75  {
76  for( DebrisManager::DebrisIterator DebIt = this->TargetManager->Debriss.begin() ; DebIt != this->TargetManager->Debriss.end() ; ++DebIt )
77  {
78  (*DebIt)->_Update();
79  }
80  }
81 
82  ///////////////////////////////////////////////////////////////////////////////
83  // DebrisManager Methods
84 
85  const String DebrisManager::ImplementationName = "DefaultDebrisManager";
86  const ManagerBase::ManagerType DebrisManager::InterfaceType = ManagerBase::MT_DebrisManager;
87 
89  WorldManager(Creator)
90  {
91  this->AddDebrisFactory( new RigidDebrisFactory() );
92  this->AddDebrisFactory( new SoftDebrisFactory() );
93 
94  this->DebrisUpdateWork = new DebrisUpdateWorkUnit(this);
95  }
96 
97  DebrisManager::DebrisManager(World* Creator, const XML::Node& XMLNode) :
98  WorldManager(Creator)
99  {
100  /// @todo This class currently doesn't initialize anything from XML, if that changes this constructor needs to be expanded.
101 
102  this->AddDebrisFactory( new RigidDebrisFactory() );
103  this->AddDebrisFactory( new SoftDebrisFactory() );
104 
105  this->DebrisUpdateWork = new DebrisUpdateWorkUnit(this);
106  }
107 
109  {
110  this->Deinitialize();
111  this->DestroyAllDebris();
113 
114  delete this->DebrisUpdateWork;
115  }
116 
117  ///////////////////////////////////////////////////////////////////////////////
118  // Prefab Debris Type Creation
119 
120  RigidDebris* DebrisManager::CreateRigidDebris(const String& Name, const Real Mass, const Boole AddToWorld)
121  {
123  if( DebFactIt != this->DebrisFactories.end() ) {
124  RigidDebris* Ret = static_cast<RigidDebrisFactory*>( (*DebFactIt).second )->CreateRigidDebris( Name, Mass, this->ParentWorld );
125  this->Debriss.push_back( Ret );
126  if( AddToWorld ) {
127  Ret->AddToWorld();
128  }
129  return Ret;
130  }else{
131  MEZZ_EXCEPTION(ExceptionBase::INVALID_STATE_EXCEPTION,"Attempting to create a RigidDebris without it's factory registered.");
132  }
133  }
134 
135  RigidDebris* DebrisManager::CreateRigidDebris(const String& Name, const Real Mass, Graphics::Mesh* DebMesh, Physics::CollisionShape* DebShape, const Boole AddToWorld)
136  {
138  if( DebFactIt != this->DebrisFactories.end() ) {
139  RigidDebris* Ret = static_cast<RigidDebrisFactory*>( (*DebFactIt).second )->CreateRigidDebris( Name, Mass, DebMesh, DebShape, this->ParentWorld );
140  this->Debriss.push_back( Ret );
141  if( AddToWorld ) {
142  Ret->AddToWorld();
143  }
144  return Ret;
145  }else{
146  MEZZ_EXCEPTION(ExceptionBase::INVALID_STATE_EXCEPTION,"Attempting to create a RigidDebris without it's factory registered.");
147  }
148  }
149 
151  {
153  if( DebFactIt != this->DebrisFactories.end() ) {
154  RigidDebris* Ret = static_cast<RigidDebrisFactory*>( (*DebFactIt).second )->CreateRigidDebris( SelfRoot, this->ParentWorld );
155  this->Debriss.push_back( Ret );
156  return Ret;
157  }else{
158  MEZZ_EXCEPTION(ExceptionBase::INVALID_STATE_EXCEPTION,"Attempting to create a RigidDebris without it's factory registered.");
159  }
160  }
161 
162  SoftDebris* DebrisManager::CreateSoftDebris(const String& Name, const Real Mass, const Boole AddToWorld)
163  {
165  if( DebFactIt != this->DebrisFactories.end() ) {
166  SoftDebris* Ret = static_cast<SoftDebrisFactory*>( (*DebFactIt).second )->CreateSoftDebris( Name, Mass, this->ParentWorld );
167  this->Debriss.push_back( Ret );
168  if( AddToWorld ) {
169  Ret->AddToWorld();
170  }
171  return Ret;
172  }else{
173  MEZZ_EXCEPTION(ExceptionBase::INVALID_STATE_EXCEPTION,"Attempting to create a SoftDebris without it's factory registered.");
174  }
175  }
176 
178  {
180  if( DebFactIt != this->DebrisFactories.end() ) {
181  SoftDebris* Ret = static_cast<SoftDebrisFactory*>( (*DebFactIt).second )->CreateSoftDebris( SelfRoot, this->ParentWorld );
182  this->Debriss.push_back( Ret );
183  return Ret;
184  }else{
185  MEZZ_EXCEPTION(ExceptionBase::INVALID_STATE_EXCEPTION,"Attempting to create a SoftDebris without it's factory registered.");
186  }
187  }
188 
189  ///////////////////////////////////////////////////////////////////////////////
190  // Debris Management
191 
192  Debris* DebrisManager::CreateDebris(const String& TypeName, const String& InstanceName, const NameValuePairMap& Params, const Boole AddToWorld)
193  {
194  FactoryIterator DebFactIt = this->DebrisFactories.find( TypeName );
195  if( DebFactIt != this->DebrisFactories.end() ) {
196  Debris* Ret = (*DebFactIt).second->CreateDebris( InstanceName, this->ParentWorld, Params );
197  this->Debriss.push_back( Ret );
198  if( AddToWorld ) {
199  Ret->AddToWorld();
200  }
201  return Ret;
202  }else{
203  MEZZ_EXCEPTION(ExceptionBase::INVALID_STATE_EXCEPTION,"Attempting to create an Debris of unknown type.");
204  }
205  }
206 
208  {
209  FactoryIterator DebFactIt = this->DebrisFactories.find( SelfRoot.Name() );
210  if( DebFactIt != this->DebrisFactories.end() ) {
211  Debris* Ret = (*DebFactIt).second->CreateDebris( SelfRoot, this->ParentWorld );
212  this->Debriss.push_back( Ret );
213  return Ret;
214  }else{
215  MEZZ_EXCEPTION(ExceptionBase::INVALID_STATE_EXCEPTION,"Attempting to create a Debris of unknown type.");
216  }
217  }
218 
220  {
221  return this->Debriss.at(Index);
222  }
223 
225  {
226  for( ConstDebrisIterator DebIt = this->Debriss.begin() ; DebIt != this->Debriss.end() ; ++DebIt )
227  {
228  if( (*DebIt)->GetName() == Name )
229  return (*DebIt);
230  }
231  return NULL;
232  }
233 
235  {
236  return this->Debriss.size();
237  }
238 
240  {
241  DebrisIterator DebIt = ( Index < this->GetNumDebris() ? this->Debriss.begin() + Index : this->Debriss.end() );
242  if( DebIt != this->Debriss.end() )
243  {
244  FactoryIterator DebFactIt = this->DebrisFactories.find( (*DebIt)->GetDerivedSerializableName() );
245  if( DebFactIt != this->DebrisFactories.end() ) {
246  (*DebFactIt).second->DestroyDebris( (*DebIt) );
247  }else{
248  MEZZ_EXCEPTION(ExceptionBase::INVALID_STATE_EXCEPTION,"Attempting to destroy a Debris of unknown type.");
249  }
250 
251  this->Debriss.erase(DebIt);
252  }
253  }
254 
256  {
257  DebrisIterator DebIt = std::find( this->Debriss.begin(), this->Debriss.end(), ToBeDestroyed );
258  if( DebIt != this->Debriss.end() )
259  {
260  FactoryIterator DebFactIt = this->DebrisFactories.find( (*DebIt)->GetDerivedSerializableName() );
261  if( DebFactIt != this->DebrisFactories.end() ) {
262  (*DebFactIt).second->DestroyDebris( (*DebIt) );
263  }else{
264  MEZZ_EXCEPTION(ExceptionBase::INVALID_STATE_EXCEPTION,"Attempting to destroy a Debris of unknown type.");
265  }
266 
267  this->Debriss.erase(DebIt);
268  }
269  }
270 
272  {
273  for( DebrisIterator DebIt = this->Debriss.begin() ; DebIt != this->Debriss.end() ; ++DebIt )
274  {
275  FactoryIterator DebFactIt = this->DebrisFactories.find( (*DebIt)->GetDerivedSerializableName() );
276  if( DebFactIt != this->DebrisFactories.end() ) {
277  (*DebFactIt).second->DestroyDebris( (*DebIt) );
278  }else{
279  MEZZ_EXCEPTION(ExceptionBase::INVALID_STATE_EXCEPTION,"Attempting to destroy a Debris of unknown type.");
280  }
281  }
282  this->Debriss.clear();
283  }
284 
286  { return this->Debriss.begin(); }
287 
289  { return this->Debriss.end(); }
290 
292  { return this->Debriss.begin(); }
293 
295  { return this->Debriss.end(); }
296 
297  ///////////////////////////////////////////////////////////////////////////////
298  // DebrisFactory Management
299 
301  {
302  this->DebrisFactories.insert(std::pair<String,DebrisFactory*>(ToBeAdded->GetTypeName(),ToBeAdded));
303  }
304 
306  {
307  this->RemoveDebrisFactory(ToBeRemoved->GetTypeName());
308  }
309 
311  {
312  FactoryIterator DebFactIt = this->DebrisFactories.find(ImplName);
313  if( DebFactIt != this->DebrisFactories.end() )
314  { this->DebrisFactories.erase(DebFactIt); }
315  }
316 
318  {
319  this->DestroyDebrisFactory(ToBeDestroyed->GetTypeName());
320  }
321 
323  {
324  FactoryIterator DebFactIt = this->DebrisFactories.find(ImplName);
325  if( DebFactIt != this->DebrisFactories.end() ) {
326  delete DebFactIt->second;
327  this->DebrisFactories.erase(DebFactIt);
328  }
329  }
330 
332  {
333  for( FactoryIterator DebFactIt = this->DebrisFactories.begin() ; DebFactIt != this->DebrisFactories.end() ; ++DebFactIt )
334  { delete (*DebFactIt).second; }
335  this->DebrisFactories.clear();
336  }
337 
338  ///////////////////////////////////////////////////////////////////////////////
339  // Utility
340 
342  {
343  // Do nothing currently
344  }
345 
347  {
348  if( !this->Initialized ) {
350 
351  this->TheEntresol->GetScheduler().AddWorkUnitMain( this->DebrisUpdateWork, "DebrisUpdateWork" );
352  Physics::PhysicsManager* PhysicsMan = static_cast<Physics::PhysicsManager*>( this->ParentWorld->GetManager(ManagerBase::MT_PhysicsManager) );
353  if( PhysicsMan ) {
354  this->DebrisUpdateWork->AddDependency( PhysicsMan->GetSimulationWork() );
355  }
356 
357  this->Initialized = true;
358  }
359  }
360 
362  {
363  if( this->Initialized ) {
366 
367  this->Initialized = false;
368  }
369  }
370 
372  { return this->DebrisUpdateWork; }
373 
374  ///////////////////////////////////////////////////////////////////////////////
375  // Type Identifier Methods
376 
378  { return DebrisManager::InterfaceType; }
379 
382 
383  ///////////////////////////////////////////////////////////////////////////////
384  // DefaultDebrisManagerFactory Methods
385 
387  { }
388 
390  { }
391 
394 
396  { return DebrisManager::InterfaceType; }
397 
399  { return new DebrisManager(Creator); }
400 
402  { return new DebrisManager(Creator,XMLNode); }
403 
405  { delete ToBeDestroyed; }
406 }//Mezzanine
407 
408 #endif
DebrisManager * TargetManager
A pointer to the manager this work unit is processing.
Definition: debrismanager.h:76
virtual void AddDependency(iWorkUnit *NewDependency)
Force this WorkUnit to Start after another has completed.
Definition: workunit.cpp:99
This is the base class for all collision shapes.
virtual void DestroyDebrisFactory(DebrisFactory *ToBeDestroyed)
Removes and destroys a Debris factory in this manager.
WorldManager * GetManager(const Whole ManagerToGet)
This is will find the manager of a given type.
Definition: world.cpp:324
DebrisManager(World *Creator)
Class constructor.
virtual String GetImplementationTypeName() const
This Allows any manager name to be sent to a stream. Primarily used for logging.
DebrisUpdateWorkUnit & operator=(const DebrisUpdateWorkUnit &Other)
Protected assignment operator. THIS IS NOT ALLOWED.
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
virtual void Initialize()
Configures this manager for use prior to entering the main loop.
virtual void AddToWorld()=0
Adds the object to the World.
virtual void AddWorkUnitMain(iWorkUnit *MoreWork, const String &WorkUnitName)
Add a normal Mezzanine::Threading::iWorkUnit to this For fcheduling.
This file contains the declaration for the manager that manages debris objects in a world...
A deformable debris.
Definition: softdebris.h:62
ManagerType
A listing of Manager Types.
Definition: managerbase.h:65
virtual String GetTypeName() const =0
Gets the name of the Debris that is created by this factory.
DebrisContainer::iterator DebrisIterator
Iterator type for Debris instances stored by this class.
virtual ~DefaultDebrisManagerFactory()
Class destructor.
virtual void DestroyDebris(const Whole Index)
Destroys an Debris at the specified index.
virtual void RemoveWorkUnitMain(iWorkUnit *LessWork)
Remove a WorkUnit from the main pool of WorkUnits (and not from the groups of Affinity or MonpolyWork...
#define MEZZ_EXCEPTION(num, desc)
An easy way to throw exceptions with rich information.
Definition: exception.h:3048
This class is used to check and modify the properties of a graphics mesh.
Definition: mesh.h:63
static String GetSerializableName()
Get the name of the the XML tag the proxy class will leave behind as its instances are serialized...
virtual void Pause(const UInt32 PL)
Sets the pause state of this manager, or has no effect depending on the value passed in...
DebrisIterator EndDebris()
Gets an iterator to one passed the last Debris in this manager.
A base factory type for the creation of Debris objects.
Definition: debris.h:95
Threading::FrameScheduler & GetScheduler()
Gets the core structure responsible for scheduling work in the Entresol main loop.
Definition: entresol.cpp:495
A non-deformable debris.
Definition: rigiddebris.h:64
virtual void AddToWorld()
Adds the object to the World.
A base factory type for the creation of non-deformable Debris objects.
Definition: rigiddebris.h:216
float Real
A Datatype used to represent a real floating point number.
Definition: datatypes.h:141
A thread specific collection of double-buffered and algorithm specific resources. ...
virtual void DestroyAllDebris()
Destroys all Debriss currently within this manager.
This file contains the declaration for the debris class that does not deform.
virtual Whole GetNumDebris() const
Gets the number of Debriss stored in this manager.
A manager responsible for the storage and management of all Debris that exist in a world...
virtual Debris * GetDebris(const Whole Index) const
Gets an Debris by Index.
A light-weight handle for manipulating nodes in DOM tree.
Definition: node.h:89
A simple world object without a large structure ideal for representing loose small objects...
Definition: debris.h:54
DebrisContainer Debriss
Container storing all Debris belonging to this manager.
DebrisUpdateWorkUnit * GetDebrisUpdateWork()
Gets the work unit responsible for updating Debriss stored by this manager.
uint32_t UInt32
An 32-bit unsigned integer.
Definition: datatypes.h:126
String GetManagerImplName() const
Gets the name of the manager that is created by this factory.
FactoryMap::iterator FactoryIterator
Iterator type for DebrisFactory instances stored by this class.
virtual void DoWork(Threading::DefaultThreadSpecificStorage::Type &CurrentThreadStorage)
This does any required update of the Debris stored by it's manager.
Entresol * TheEntresol
The actual pointer to the Entresol core class.
Definition: managerbase.h:108
ManagerBase::ManagerType GetManagerType() const
Gets the type of manager that is created by this factory.
virtual void RemoveDebrisFactory(DebrisFactory *ToBeRemoved)
Removes a Debris factory from this manager.
DebrisUpdateWorkUnit * DebrisUpdateWork
The work unit that updates all the Debris stored by this manager.
FactoryMap DebrisFactories
A map containing all registered Debris type factories.
std::list< NameValuePair > NameValuePairList
This is a datatype mostly used for describing settings or parameters that can't be declared in advanc...
Definition: datatypes.h:206
DebrisIterator BeginDebris()
Gets an iterator to the first Debris in this manager.
Thrown when the available information should have worked but failed for unknown reasons.
Definition: exception.h:113
This is the base class for all managers that belong to a single world instance.
Definition: worldmanager.h:55
virtual void ClearDependencies()
Drop any information about what work units this one depends on.
Definition: workunit.cpp:110
virtual void DestroyAllDebrisFactories()
Destroys all Debris factories in this manager.
virtual void Initialize()
Configures this manager for use prior to entering the main loop.
This is simply a place for storing all the Physics Related functions.
This is a Mezzanine::Threading::iWorkUnit for the updating of Debris.
Definition: debrismanager.h:71
virtual ManagerType GetInterfaceType() const
This returns the type of this manager.
virtual ~DebrisManager()
Class destructor.
Threading::DefaultWorkUnit * GetSimulationWork()
Gets a pointer to the work unit that steps the simulation.
World * ParentWorld
A pointer to the world that created this manager.
Definition: worldmanager.h:60
virtual void AddDebrisFactory(DebrisFactory *ToBeAdded)
Adds/registers a Debris factory with this manager, allowing it to be constructed through this API...
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
Debris * CreateDebris(const String &TypeName, const String &InstanceName, const NameValuePairMap &Params, const Boole AddToWorld=true)
Creates a new Debris.
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
Definition: datatypes.h:151
static String GetSerializableName()
Get the name of the the XML tag the proxy class will leave behind as its instances are serialized...
Definition: softdebris.cpp:360
This class represents a world for objects to interact within.
Definition: world.h:74
DebrisUpdateWorkUnit(const DebrisUpdateWorkUnit &Other)
Protected copy constructor. THIS IS NOT ALLOWED.
A base factory type for the creation of deformable Debris objects.
Definition: softdebris.h:201
RigidDebris * CreateRigidDebris(const String &Name, const Real Mass, const Boole AddToWorld=true)
Creates a new RigidDebris.
virtual void AddToWorld()
Adds the object to the World.
Definition: softdebris.cpp:161
virtual ~DebrisUpdateWorkUnit()
Class destructor.
const Char8 * Name() const
ptrdiff_tGet the name of this Node.
static const String ImplementationName
A String containing the name of this manager implementation.
SoftDebris * CreateSoftDebris(const String &Name, const Real Mass, const Boole AddToWorld=true)
Creates a new SoftDebris.
virtual void Deinitialize()
Removes this manager from any necessary configuration so it can be safely disposed of...
DefaultDebrisManagerFactory()
Class constructor.
std::map< String, String > NameValuePairMap
This is a datatype mostly used for describing settings or parameters that can't be declared in advanc...
Definition: datatypes.h:209
void DestroyManager(WorldManager *ToBeDestroyed)
Destroys a Manager created by this factory.
DebrisContainer::const_iterator ConstDebrisIterator
Const Iterator type for Debris instances stored by this class.
WorldManager * CreateManager(World *Creator, const NameValuePairList &Params)
Creates a manager of the type represented by this factory.
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159
SoftDebris * CreateSoftDebris(const XML::Node &SelfRoot)
Creates a new SoftDebris.
This file contains the declaration for the debris class that will compress and deform.
Boole Initialized
Simple Boole indicating whether or not this manager has been initialized.
Definition: managerbase.h:111
static const ManagerBase::ManagerType InterfaceType
A ManagerType enum value used to describe the type of interface/functionality this manager provides...