diff options
Diffstat (limited to 'source/gameengine/GameLogic/SCA_LogicManager.cpp')
-rw-r--r-- | source/gameengine/GameLogic/SCA_LogicManager.cpp | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp new file mode 100644 index 00000000000..a29d6d19729 --- /dev/null +++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp @@ -0,0 +1,461 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * Regulates the top-level logic behaviour for one scene. + */ +#include "Value.h" +#include "SCA_LogicManager.h" + +#include "SCA_ISensor.h" +#include "SCA_IController.h" +#include "SCA_IActuator.h" +#include "SCA_EventManager.h" + +#include <set> + +SCA_LogicManager::SCA_LogicManager() +{ +} + + + +SCA_LogicManager::~SCA_LogicManager() +{ + for (vector<SCA_EventManager*>::iterator it = m_eventmanagers.begin();!(it==m_eventmanagers.end());it++) + { + delete (*it); + } + m_eventmanagers.clear(); + m_sensorcontrollermapje.clear(); + + int numgameobj = m_mapStringToGameObjects.size(); + for (int i = 0; i < numgameobj; i++) + { + CValue** gameobjptr = m_mapStringToGameObjects.at(i); + assert(gameobjptr); + if (gameobjptr) + (*gameobjptr)->Release(); + + } + + /*for (int i=0;i<m_sensorcontrollermap.size();i++) + { + vector<SCA_IController*>* controllerarray = *(m_sensorcontrollermap[i]); + delete controllerarray; + } + */ +} + + +/* +// this kind of fixes bug 398 but breakes games, so better leave it out for now. +// a removed object's gameobject (and logicbricks and stuff) didn't get released +// because it was still in the m_mapStringToGameObjects map. +void SCA_LogicManager::RemoveGameObject(const STR_String& gameobjname) +{ + int numgameobj = m_mapStringToGameObjects.size(); + for (int i = 0; i < numgameobj; i++) + { + CValue** gameobjptr = m_mapStringToGameObjects.at(i); + assert(gameobjptr); + + if (gameobjptr) + { + if ((*gameobjptr)->GetName() == gameobjname) + (*gameobjptr)->Release(); + } + } + + m_mapStringToGameObjects.remove(gameobjname); +} +*/ + + +void SCA_LogicManager::RegisterEventManager(SCA_EventManager* eventmgr) +{ + m_eventmanagers.push_back(eventmgr); +} + + + +void SCA_LogicManager::RegisterGameObjectName(const STR_String& gameobjname, + CValue* gameobj) +{ + STR_HashedString mn = gameobjname; + m_mapStringToGameObjects.insert(mn,gameobj); +} + + + +CValue* SCA_LogicManager::GetGameObjectByName(const STR_String& gameobjname) +{ + STR_HashedString mn = "OB"+gameobjname; + CValue** gameptr = m_mapStringToGameObjects[mn]; + + if (gameptr) + return *gameptr; + + return NULL; +} + + + +void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor) +{ + m_sensorcontrollermapje.erase(sensor); + + for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin(); + !(ie==m_eventmanagers.end());ie++) + { + (*ie)->RemoveSensor(sensor); + } +} + + + +void SCA_LogicManager::RemoveDestroyedActuator(SCA_IActuator* actuator) +{ + + m_removedActuators.push_back(SmartActuatorPtr(actuator,0)); + // take care that no controller can use this actuator again ! + + std::map<SCA_ISensor*,controllerlist>::const_iterator sit; + for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit) + { + controllerlist contlist = (*sit).second; + for (list<SCA_IController*>::const_iterator c= contlist.begin();!(c==contlist.end());c++) + { + (*c)->UnlinkActuator(actuator); + } + } +} + + + +void SCA_LogicManager::RegisterToSensor(SCA_IController* controller,SCA_ISensor* sensor) +{ + m_sensorcontrollermapje[sensor].push_back(controller); + controller->LinkToSensor(sensor); +} + + + +void SCA_LogicManager::RegisterToActuator(SCA_IController* controller,SCA_IActuator* actua) +{ + controller->LinkToActuator(actua); +} + + + +void SCA_LogicManager::BeginFrame(double curtime,double deltatime) +{ + for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin(); + !(ie==m_eventmanagers.end());ie++) + { + (*ie)->NextFrame(curtime,deltatime); + } + + // for this frame, look up for activated sensors, and build the collection of triggered controllers + int numsensors = this->m_activatedsensors.size(); + + set<SmartControllerPtr> triggeredControllerSet; + + for (vector<SCA_ISensor*>::const_iterator is=m_activatedsensors.begin(); + !(is==m_activatedsensors.end());is++) + { + SCA_ISensor* sensor = *is; + controllerlist contlist = m_sensorcontrollermapje[sensor]; + for (list<SCA_IController*>::const_iterator c= contlist.begin(); + !(c==contlist.end());c++) + { + SCA_IController* contr = *c;//controllerarray->at(c); + triggeredControllerSet.insert(SmartControllerPtr(contr,0)); + } + //sensor->SetActive(false); + } + + + int numtriggered = triggeredControllerSet.size(); + for (set<SmartControllerPtr>::iterator tit=triggeredControllerSet.begin(); + !(tit==triggeredControllerSet.end());tit++) + { + (*tit)->Trigger(this); + } + triggeredControllerSet.clear(); +} + + + +void SCA_LogicManager::UpdateFrame(double curtime,double deltatime) +{ + vector<SmartActuatorPtr>::iterator ra; + for (ra = m_removedActuators.begin(); + !(ra == m_removedActuators.end());ra++) + { + m_activeActuators.erase(*ra); + (*ra)->SetActive(false); + } + m_removedActuators.clear(); + + for (set<SmartActuatorPtr>::iterator ia = m_activeActuators.begin();!(ia==m_activeActuators.end());ia++) + { + //SCA_IActuator* actua = *ia; + if (!(*ia)->Update(curtime,deltatime)) + { + //*ia = m_activeactuators.back(); + m_removedActuators.push_back(*ia); + + (*ia)->SetActive(false); + //m_activeactuators.pop_back(); + } + } + + for ( ra = m_removedActuators.begin(); + !(ra == m_removedActuators.end());ra++) + { + m_activeActuators.erase(*ra); + (*ra)->SetActive(false); + } + m_removedActuators.clear(); +} + + + +void* SCA_LogicManager::GetActionByName (const STR_String& actname) +{ + STR_HashedString an = "AC"+actname; + void** actptr = m_mapStringToActions[an]; + + if (actptr) + return *actptr; + + return NULL; +} + + + +void* SCA_LogicManager::GetMeshByName(const STR_String& meshname) +{ + STR_HashedString mn = "ME"+meshname; + void** meshptr = m_mapStringToMeshes[mn]; + + if (meshptr) + return *meshptr; + + return NULL; +} + + + +void SCA_LogicManager::RegisterMeshName(const STR_String& meshname,void* mesh) +{ + STR_HashedString mn = meshname; + m_mapStringToMeshes.insert(mn,mesh); +} + + + +void SCA_LogicManager::RegisterActionName(const STR_String& actname,void* action) +{ + STR_HashedString an = actname; + m_mapStringToActions.insert(an, action); +} + + + +void SCA_LogicManager::EndFrame() +{ + for (vector<SCA_ISensor*>::const_iterator is=m_activatedsensors.begin(); + !(is==m_activatedsensors.end());is++) + { + SCA_ISensor* sensor = *is; + sensor->SetActive(false); + } + m_activatedsensors.clear(); + + for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin(); + !(ie==m_eventmanagers.end());ie++) + { + (*ie)->EndFrame(); + } + + +} + + + +void SCA_LogicManager::AddActivatedSensor(SCA_ISensor* sensor) +{ + // each frame, only add sensor once, and to avoid a seek, or bloated container + // hold a flag in each sensor, with the 'framenr' + if (!sensor->IsActive()) + { + sensor->SetActive(true); + m_activatedsensors.push_back(sensor); + } +} + + + +void SCA_LogicManager::AddActiveActuator(SCA_IActuator* actua,CValue* event) +{ + if (!actua->IsActive()) + { + actua->SetActive(true); + m_activeActuators.insert(SmartActuatorPtr(actua,0)); + } + actua->AddEvent(event->AddRef()); +} + + + +SCA_EventManager* SCA_LogicManager::FindEventManager(int eventmgrtype) +{ + // find an eventmanager of a certain type + SCA_EventManager* eventmgr = NULL; + + for (vector<SCA_EventManager*>::const_iterator i= + m_eventmanagers.begin();!(i==m_eventmanagers.end());i++) + { + SCA_EventManager* emgr = *i; + if (emgr->GetType() == eventmgrtype) + { + eventmgr = emgr; + break; + } + } + return eventmgr; +} + + + +SmartActuatorPtr::SmartActuatorPtr(const SmartActuatorPtr& other) +{ + this->m_actuator = other.m_actuator; + this->m_actuator->AddRef(); +} + + + +SmartActuatorPtr::SmartActuatorPtr(SCA_IActuator* actua,int dummy) +: m_actuator(actua) +{ + actua->AddRef(); +} + + + +SmartActuatorPtr::~SmartActuatorPtr() +{ + m_actuator->Release(); +} + + + +bool SmartActuatorPtr::operator <(const SmartActuatorPtr& other) const +{ + + return m_actuator->LessComparedTo(*other); +} + + + +bool SmartActuatorPtr::operator ==(const SmartActuatorPtr& other) const +{ + bool result2 = other->LessComparedTo(m_actuator); + return (m_actuator->LessComparedTo(*other) && result2); +} + + + +SCA_IActuator* SmartActuatorPtr::operator->() const +{ + return m_actuator; +} + + + +SCA_IActuator* SmartActuatorPtr::operator*() const +{ + return m_actuator; +} + + + +SmartControllerPtr::SmartControllerPtr(const SmartControllerPtr& copy) +{ + this->m_controller = copy.m_controller; + this->m_controller->AddRef(); +} + + + +SmartControllerPtr::SmartControllerPtr(SCA_IController* contr,int dummy) +: m_controller(contr) +{ + m_controller->AddRef(); +} + + + +SmartControllerPtr::~SmartControllerPtr() +{ + m_controller->Release(); +} + + + +bool SmartControllerPtr::operator <(const SmartControllerPtr& other) const +{ + return m_controller->LessComparedTo(*other); +} + + + +bool SmartControllerPtr::operator ==(const SmartControllerPtr& other) const +{ + return (m_controller->LessComparedTo(*other) && other->LessComparedTo(m_controller)); +} + + + +SCA_IController* SmartControllerPtr::operator->() const +{ + return m_controller; +} + + + +SCA_IController* SmartControllerPtr::operator*() const +{ + return m_controller; +} + + |