Blender  V2.59
SCA_IObject.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: SCA_IObject.cpp 35169 2011-02-25 13:32:11Z jesterking $
00003  * ***** BEGIN GPL LICENSE BLOCK *****
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  *
00019  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00020  * All rights reserved.
00021  *
00022  * The Original Code is: all of this file.
00023  *
00024  * Contributor(s): none yet.
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00033 #include <iostream>
00034 #include <algorithm>
00035 
00036 #include "SCA_IObject.h"
00037 #include "SCA_ISensor.h"
00038 #include "SCA_IController.h"
00039 #include "SCA_IActuator.h"
00040 #include "MT_Point3.h"
00041 #include "ListValue.h"
00042 
00043 MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0);
00044 SG_QList SCA_IObject::m_activeBookmarkedControllers;
00045 
00046 SCA_IObject::SCA_IObject():
00047         CValue(),
00048         m_initState(0),
00049         m_state(0),
00050         m_firstState(NULL)
00051 {
00052         m_suspended = false;
00053 }
00054 
00055 SCA_IObject::~SCA_IObject()
00056 {
00057         SCA_SensorList::iterator its;
00058         for (its = m_sensors.begin(); !(its == m_sensors.end()); ++its)
00059         {
00060                 //Use Delete for sensor to ensure proper cleaning
00061                 (*its)->Delete();
00062                 //((CValue*)(*its))->Release();
00063         }
00064         SCA_ControllerList::iterator itc; 
00065         for (itc = m_controllers.begin(); !(itc == m_controllers.end()); ++itc)
00066         {
00067                 //Use Delete for controller to ensure proper cleaning (expression controller)
00068                 (*itc)->Delete();
00069                 //((CValue*)(*itc))->Release();
00070         }
00071         SCA_ActuatorList::iterator ita;
00072         for (ita = m_registeredActuators.begin(); !(ita==m_registeredActuators.end()); ++ita)
00073         {
00074                 (*ita)->UnlinkObject(this);
00075         }
00076         for (ita = m_actuators.begin(); !(ita==m_actuators.end()); ++ita)
00077         {
00078                 (*ita)->Delete();
00079         }
00080 
00081         SCA_ObjectList::iterator ito;
00082         for (ito = m_registeredObjects.begin(); !(ito==m_registeredObjects.end()); ++ito)
00083         {
00084                 (*ito)->UnlinkObject(this);
00085         }
00086 
00087         //T_InterpolatorList::iterator i;
00088         //for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
00089         //      delete *i;
00090         //}
00091 }
00092 
00093 void SCA_IObject::AddSensor(SCA_ISensor* act)
00094 {
00095         act->AddRef();
00096         m_sensors.push_back(act);
00097 }
00098 
00099 
00100 
00101 void SCA_IObject::AddController(SCA_IController* act)
00102 {
00103         act->AddRef();
00104         m_controllers.push_back(act);
00105 }
00106 
00107 
00108 
00109 void SCA_IObject::AddActuator(SCA_IActuator* act)
00110 {
00111         act->AddRef();
00112         m_actuators.push_back(act);
00113 }
00114 
00115 void SCA_IObject::RegisterActuator(SCA_IActuator* act)
00116 {
00117         // don't increase ref count, it would create dead lock
00118         m_registeredActuators.push_back(act);
00119 }
00120 
00121 void SCA_IObject::UnregisterActuator(SCA_IActuator* act)
00122 {
00123         SCA_ActuatorList::iterator ita;
00124         for (ita = m_registeredActuators.begin(); ita != m_registeredActuators.end(); ++ita)
00125         {
00126                 if ((*ita) == act) {
00127                         (*ita) = m_registeredActuators.back();
00128                         m_registeredActuators.pop_back();
00129                         break;
00130                 }
00131         }
00132 }
00133 
00134 void SCA_IObject::RegisterObject(SCA_IObject* obj)
00135 {
00136         // one object may be registered multiple times via constraint target
00137         // store multiple reference, this will serve as registration counter
00138         m_registeredObjects.push_back(obj);
00139 }
00140 
00141 void SCA_IObject::UnregisterObject(SCA_IObject* obj)
00142 {
00143         SCA_ObjectList::iterator ito;
00144         for (ito = m_registeredObjects.begin(); ito != m_registeredObjects.end(); ++ito)
00145         {
00146                 if ((*ito) == obj) {
00147                         (*ito) = m_registeredObjects.back();
00148                         m_registeredObjects.pop_back();
00149                         break;
00150                 }
00151         }
00152 }
00153 
00154 void SCA_IObject::ReParentLogic()
00155 {
00156         SCA_ActuatorList& oldactuators  = GetActuators();
00157         int act = 0;
00158         SCA_ActuatorList::iterator ita;
00159         for (ita = oldactuators.begin(); !(ita==oldactuators.end()); ++ita)
00160         {
00161                 SCA_IActuator* newactuator = (SCA_IActuator*) (*ita)->GetReplica();
00162                 newactuator->ReParent(this);
00163                 // actuators are initially not connected to any controller
00164                 newactuator->SetActive(false);
00165                 newactuator->ClrLink();
00166                 oldactuators[act++] = newactuator;
00167         }
00168 
00169         SCA_ControllerList& oldcontrollers = GetControllers();
00170         int con = 0;
00171         SCA_ControllerList::iterator itc;
00172         for (itc = oldcontrollers.begin(); !(itc==oldcontrollers.end()); ++itc)
00173         {
00174                 SCA_IController* newcontroller = (SCA_IController*)(*itc)->GetReplica();
00175                 newcontroller->ReParent(this);
00176                 newcontroller->SetActive(false);
00177                 oldcontrollers[con++]=newcontroller;
00178 
00179         }
00180         // convert sensors last so that actuators are already available for Actuator sensor
00181         SCA_SensorList& oldsensors = GetSensors();
00182         int sen = 0;
00183         SCA_SensorList::iterator its;
00184         for (its = oldsensors.begin(); !(its==oldsensors.end()); ++its)
00185         {
00186                 SCA_ISensor* newsensor = (SCA_ISensor*)(*its)->GetReplica();
00187                 newsensor->ReParent(this);
00188                 newsensor->SetActive(false);
00189                 // sensors are initially not connected to any controller
00190                 newsensor->ClrLink();
00191                 oldsensors[sen++] = newsensor;
00192         }
00193 
00194         // a new object cannot be client of any actuator
00195         m_registeredActuators.clear();
00196         m_registeredObjects.clear();
00197 }
00198 
00199 
00200 
00201 SCA_ISensor* SCA_IObject::FindSensor(const STR_String& sensorname)
00202 {
00203         SCA_ISensor* foundsensor = NULL;
00204 
00205         for (SCA_SensorList::iterator its = m_sensors.begin();!(its==m_sensors.end());++its)
00206         {
00207                 if ((*its)->GetName() == sensorname)
00208                 {
00209                         foundsensor = (*its);
00210                         break;
00211                 }
00212         }
00213         return foundsensor;
00214 }
00215 
00216 
00217 
00218 SCA_IController* SCA_IObject::FindController(const STR_String& controllername)
00219 {
00220         SCA_IController* foundcontroller = NULL;
00221 
00222         for (SCA_ControllerList::iterator itc = m_controllers.begin();!(itc==m_controllers.end());++itc)
00223         {
00224                 if ((*itc)->GetName() == controllername)
00225                 {
00226                         foundcontroller = (*itc);
00227                         break;
00228                 }       
00229         }
00230         return foundcontroller;
00231 }
00232 
00233 
00234 
00235 SCA_IActuator* SCA_IObject::FindActuator(const STR_String& actuatorname)
00236 {
00237         SCA_IActuator* foundactuator = NULL;
00238 
00239         for (SCA_ActuatorList::iterator ita = m_actuators.begin();!(ita==m_actuators.end());++ita)
00240         {
00241                 if ((*ita)->GetName() == actuatorname)
00242                 {
00243                         foundactuator = (*ita);
00244                         break;
00245                 }
00246         }
00247 
00248         return foundactuator;
00249 }
00250 
00251 
00252 void SCA_IObject::Suspend()
00253 {
00254         if ((!m_ignore_activity_culling) 
00255                 && (!m_suspended))  {
00256                 m_suspended = true;
00257                 /* flag suspend for all sensors */
00258                 SCA_SensorList::iterator i = m_sensors.begin();
00259                 while (i != m_sensors.end()) {
00260                         (*i)->Suspend();
00261                         ++i;
00262                 }
00263         }
00264 }
00265 
00266 
00267 
00268 void SCA_IObject::Resume(void)
00269 {
00270         if (m_suspended) {
00271                 m_suspended = false;
00272                 /* unflag suspend for all sensors */
00273                 SCA_SensorList::iterator i = m_sensors.begin();
00274                 while (i != m_sensors.end()) {
00275                         (*i)->Resume();
00276                         ++i;
00277                 }
00278         }
00279 }
00280 
00281 void SCA_IObject::SetState(unsigned int state)
00282 {
00283         unsigned int tmpstate;
00284         SCA_ControllerList::iterator contit;
00285 
00286         // we will update the state in two steps:
00287         // 1) set the new state bits that are 1
00288         // 2) clr the new state bits that are 0
00289         // This to ensure continuity if a sensor is attached to two states
00290         // that are switching state: no need to deactive and reactive the sensor 
00291         
00292         tmpstate = m_state | state;
00293         if (tmpstate != m_state)
00294         {
00295                 // update the status of the controllers
00296                 for (contit = m_controllers.begin(); contit != m_controllers.end(); ++contit)
00297                 {
00298                         (*contit)->ApplyState(tmpstate);
00299                 }
00300         }
00301         m_state = state;
00302         if (m_state != tmpstate)
00303         {
00304                 for (contit = m_controllers.begin(); contit != m_controllers.end(); ++contit)
00305                 {
00306                         (*contit)->ApplyState(m_state);
00307                 }
00308         }
00309 }
00310 
00311 #ifdef WITH_PYTHON
00312 
00313 /* ------------------------------------------------------------------------- */
00314 /* Python functions                                                          */
00315 /* ------------------------------------------------------------------------- */
00316 
00317 /* Integration hooks ------------------------------------------------------- */
00318 PyTypeObject SCA_IObject::Type = {
00319         PyVarObject_HEAD_INIT(NULL, 0)
00320         "SCA_IObject",
00321         sizeof(PyObjectPlus_Proxy),
00322         0,
00323         py_base_dealloc,
00324         0,
00325         0,
00326         0,
00327         0,
00328         py_base_repr,
00329         0,0,0,0,0,0,0,0,0,
00330         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
00331         0,0,0,0,0,0,0,
00332         Methods,
00333         0,
00334         0,
00335         &CValue::Type,
00336         0,0,0,0,0,0,
00337         py_base_new
00338 };
00339 
00340 PyMethodDef SCA_IObject::Methods[] = {
00341         //{"setOrientation", (PyCFunction) SCA_IObject::sPySetOrientation, METH_VARARGS},
00342         //{"getOrientation", (PyCFunction) SCA_IObject::sPyGetOrientation, METH_VARARGS},
00343         {NULL,NULL} //Sentinel
00344 };
00345 
00346 PyAttributeDef SCA_IObject::Attributes[] = {
00347         { NULL }        //Sentinel
00348 };
00349 
00350 #endif // WITH_PYTHON