NLS Engine  v0.1
The Next Logical Step in game engine design.
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Defines
PhysicsModuleComponents.cpp
Go to the documentation of this file.
00001 
00011 #pragma once
00012 
00013 #include "PhysicsModule.h"
00014 
00015 // System Library Includes
00016 
00017 // Application Library Includes
00018 
00019 // Local Includes
00020 #include "../sharedbase/Entity.h"
00021 #include "../sharedbase/ComponentInterface.h"
00022 #include "../sharedbase/Envelope.h"
00023 
00024 #include "Components.h"
00025 #include "component/ComponentLinearVelocity.h"
00026 #include "component/ASTARMap.h"
00027 #include "component/collider/ColliderSphere.h"
00028 #include "component/GridMover.h"
00029 
00030 // Classes
00031 namespace Physics {
00032   /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00036   template<typename T>
00037   inline void getAttribute(const std::string type, std::map<std::string, boost::any> &attributes, const std::string key, boost::function<bool(T)> setter) {
00038     bool status = false;
00039     
00040     if (attributes.count(key) > 0) {
00041       try {
00042         status = setter(boost::any_cast < T > (attributes[key]));
00043       }
00044       catch (const boost::bad_any_cast &) {
00045         LOG(LOG_PRIORITY::INFO, type + " " + key + " set with invalid data type.");
00046       }
00047       
00048       if (!status) {
00049         LOG(LOG_PRIORITY::INFO, "Setter for " +  type + " " + key + " failed to set. (returned false)");
00050       }
00051     }
00052   }
00053 
00054   /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00058   template<typename T>
00059   inline std::pair<bool, T> getAttributeAlt(const std::string type, std::map<std::string, boost::any> &attributes, const std::string key) {
00060     bool status = false;
00061     T result;
00062     if (attributes.count(key) > 0) {
00063       try {
00064         result = boost::any_cast < T > (attributes[key]);
00065         status = true;
00066       }
00067       catch (const boost::bad_any_cast &) {
00068         LOG(LOG_PRIORITY::INFO, type + " " + key + " set with invalid data type.");
00069       }
00070     }
00071     return std::pair<bool, T>(status, result);
00072   }
00073 
00074   /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00075   // Called to create a component of type (type), with the set of attributes (attributes), and with parent entity (entity)
00076   void PhysicsModule::CreateComponent(std::string type, std::map<std::string, boost::any> &attributes, EntitySPTR entity) {
00077     /* * * * * * * * * * * * * * * * * * * * * * * * * */
00078     if (type == LINEAR_VELOCITY) {
00079       /* * * * * * * * * * * */
00080       // Create object.
00081       /* * * * * * * * * * * */
00082       ComponentLinearVelocity* object = new ComponentLinearVelocity(entity, this);
00083       
00084       /* * * * * * * * * * * */
00085       // Process each parameter.
00086       /* * * * * * * * * * * */
00087       getAttribute < LINEAR_VELOCITY__VELOCITY_TYPE > (
00088         type, attributes, LINEAR_VELOCITY__VELOCITY, std::bind1st(std::mem_fun(&ComponentLinearVelocity::SetVelocity), object)
00089       );
00090       
00091       /* * * * * * * * * * * */
00092       // Add to list(s).
00093       /* * * * * * * * * * * */
00094       // Add to the updateable list since this is an updateable.
00095       {
00096         Threading::WriteLock w_lock(this->updateableObjectsMutex);
00097         this->updateableObjects.insert(object);
00098       }
00099       
00100       // Add to the main list of components.
00101       {
00102         Threading::WriteLock w_lock(this->physicsComponentsMutex);
00103         this->physicsComponents.insert(object);
00104       }
00105     }
00106     /* * * * * * * * * * * * * * * * * * * * * * * * * */
00107     else if (type == "ASTARMap") {
00108       ASTARMap* astar = new ASTARMap(entity, this, this->msgrouter);
00109 
00110       getAttribute < EnvelopeSPTR > (
00111         type, attributes, "mapdata", std::bind1st(std::mem_fun(&ASTARMap::LoadMapData), astar)
00112         );
00113       getAttribute < EnvelopeSPTR > (
00114         type, attributes, "objectdata", std::bind1st(std::mem_fun(&ASTARMap::LoadObjectData), astar)
00115         );
00116 
00117       astar->FindPath(astar->start);
00118       
00119       // Add to the main list of components.
00120       {
00121         Threading::WriteLock w_lock(this->physicsComponentsMutex);
00122         this->physicsComponents.insert(astar);
00123       }
00124     }
00125     else if (type == "GridMover") {
00126       GridMover* gmove = new GridMover(entity, this, this->msgrouter);
00127 
00128       getAttribute < unsigned int > (
00129         type, attributes, "scale", std::bind1st(std::mem_fun(&GridMover::SetMovementScale), gmove)
00130         );
00131 
00132       getAttribute < float > (
00133         type, attributes, "delay", std::bind1st(std::mem_fun(&GridMover::SetPauseDelay), gmove)
00134         );
00135 
00136       getAttribute < EnvelopeSPTR > (
00137         type, attributes, "objectdata", std::bind1st(std::mem_fun(&GridMover::LoadObjectData), gmove)
00138         );
00139 
00140       EnvelopeSPTR env( boost::any_cast<EnvelopeSPTR>(attributes["path"]) );
00141       PointList* path = boost::any_cast<PointList*>(env->GetData(0));
00142 
00143       unsigned int handler = boost::any_cast<unsigned int>(attributes["pointenteractionhandler"]);
00144       gmove->AddPointActionHandler(0, handler);
00145 
00146       handler = boost::any_cast<unsigned int>(attributes["pointleaveactionhandler"]);
00147       gmove->AddPointActionHandler(1, handler);
00148 
00149       gmove->SetPath(path);
00150       {
00151         Threading::WriteLock w_lock(this->updateableObjectsMutex);
00152         this->updateableObjects.insert(gmove);
00153       }
00154       {
00155         Threading::WriteLock w_lock(this->physicsComponentsMutex);
00156         this->physicsComponents.insert(gmove);
00157       }
00158     }
00159     /* * * * * * * * * * * * * * * * * * * * * * * * * */
00160     else if (type == SPHERE_COLLIDER) {
00161       /* * * * * * * * * * * */
00162       // Create object.
00163       /* * * * * * * * * * * */
00164       ColliderSphere* object = new ColliderSphere(entity, this);
00165       
00166       /* * * * * * * * * * * */
00167       // Process each parameter.
00168       /* * * * * * * * * * * */
00169       getAttribute < SPHERE_COLLIDER__RADIUS_TYPE > (
00170         type, attributes, SPHERE_COLLIDER__RADIUS, std::bind1st(std::mem_fun(&ColliderSphere::SetRadius), object)
00171       );
00172       
00173       /* * * * * * * * * * * */
00174       // Add to list(s).
00175       /* * * * * * * * * * * */
00176       // Add to the collidable list since this is a collidable.
00177       {
00178         Threading::WriteLock w_lock(this->collidableObjectsMutex);
00179         this->collidableObjects.insert(object);
00180       }
00181       
00182       // Add to the main list of components.
00183       {
00184         Threading::WriteLock w_lock(this->physicsComponentsMutex);
00185         this->physicsComponents.insert(object);
00186       }
00187     }
00188     
00189   }
00190   
00191   /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00192   WHO_DELETES::TYPE PhysicsModule::RemoveComponent(ComponentInterface* component) {
00193     // Remove the requested component
00194     this->physicsComponents.erase(component);
00195     
00196     {
00197       Threading::UpgradeLock up_lock(this->collidableObjectsMutex);
00198       
00199       InterfaceCollider* collider = static_cast<InterfaceCollider*>(component);
00200       
00201       CollidableListType::const_iterator it = this->collidableObjects.find(collider);
00202       if (it != this->collidableObjects.end()) {
00203         Threading::UpgradeToUniqueLock unique_lock(up_lock);
00204         
00205         this->collidableObjects.erase(it);
00206       }
00207     }
00208     
00209     {
00210       Threading::UpgradeLock up_lock(this->updateableObjectsMutex);
00211       
00212       InterfaceUpdateable* updateable = static_cast<InterfaceUpdateable*>(component);
00213       
00214       UpdateableListType::const_iterator it = this->updateableObjects.find(updateable);
00215       if (it != this->updateableObjects.end()) {
00216         Threading::UpgradeToUniqueLock unique_lock(up_lock);
00217         
00218         this->updateableObjects.erase(it);
00219       }
00220     }
00221     
00222     return WHO_DELETES::CALLER; // Upstream deletion required
00223     //return WHO_DELETES::CALLEE; // Deletion accomplished here
00224   }
00225 }