diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index e7f445054e..e8e7f2b721 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -241,6 +241,8 @@ public: CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim); virtual ~CharacterController(); + const MWWorld::Ptr& getPtr() const { return mPtr; }; + void handleTextKey(const std::string &groupname, SceneUtil::TextKeyMap::ConstIterator key, const SceneUtil::TextKeyMap& map) override; // Be careful when to call this, see comment in Actors diff --git a/apps/openmw/mwmechanics/objects.cpp b/apps/openmw/mwmechanics/objects.cpp index 2b5157b4ec..c77521d06e 100644 --- a/apps/openmw/mwmechanics/objects.cpp +++ b/apps/openmw/mwmechanics/objects.cpp @@ -13,55 +13,43 @@ namespace MWMechanics { -Objects::~Objects() -{ - for(auto& object : mObjects) - { - delete object.second; - object.second = nullptr; - } -} - void Objects::addObject(const MWWorld::Ptr& ptr) { removeObject(ptr); MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr); - if(anim) mObjects.insert(std::make_pair(ptr, new CharacterController(ptr, anim))); + if (anim == nullptr) + return; + + const auto it = mObjects.emplace(mObjects.end(), ptr, anim); + mIndex.emplace(ptr.getBase(), it); } void Objects::removeObject(const MWWorld::Ptr& ptr) { - PtrControllerMap::iterator iter = mObjects.find(ptr); - if(iter != mObjects.end()) + const auto iter = mIndex.find(ptr.getBase()); + if (iter != mIndex.end()) { - delete iter->second; - mObjects.erase(iter); + mObjects.erase(iter->second); + mIndex.erase(iter); } } void Objects::updateObject(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) { - PtrControllerMap::iterator iter = mObjects.find(old); - if(iter != mObjects.end()) - { - CharacterController *ctrl = iter->second; - mObjects.erase(iter); - - ctrl->updatePtr(ptr); - mObjects.insert(std::make_pair(ptr, ctrl)); - } + const auto iter = mIndex.find(old.getBase()); + if (iter != mIndex.end()) + iter->second->updatePtr(ptr); } void Objects::dropObjects (const MWWorld::CellStore *cellStore) { - PtrControllerMap::iterator iter = mObjects.begin(); - while(iter != mObjects.end()) + for (auto iter = mObjects.begin(); iter != mObjects.end();) { - if(iter->first.getCell()==cellStore) + if (iter->getPtr().getCell() == cellStore) { - delete iter->second; - mObjects.erase(iter++); + mIndex.erase(iter->getPtr().getBase()); + iter = mObjects.erase(iter); } else ++iter; @@ -72,8 +60,8 @@ void Objects::update(float duration, bool paused) { if(!paused) { - for(auto& object : mObjects) - object.second->update(duration); + for (CharacterController& object : mObjects) + object.update(duration); } else { @@ -82,15 +70,15 @@ void Objects::update(float duration, bool paused) if(mode != MWGui::GM_Container) return; - for(auto& object : mObjects) + for (CharacterController& object : mObjects) { - if (object.first.getType() != ESM::Container::sRecordId) + if (object.getPtr().getType() != ESM::Container::sRecordId) continue; - if (object.second->isAnimPlaying("containeropen")) + if (object.isAnimPlaying("containeropen")) { - object.second->update(duration); - MWBase::Environment::get().getWorld()->updateAnimatedCollisionShape(object.first); + object.update(duration); + MWBase::Environment::get().getWorld()->updateAnimatedCollisionShape(object.getPtr()); } } } @@ -98,23 +86,23 @@ void Objects::update(float duration, bool paused) bool Objects::onOpen(const MWWorld::Ptr& ptr) { - PtrControllerMap::iterator iter = mObjects.find(ptr); - if(iter != mObjects.end()) + const auto iter = mIndex.find(ptr.getBase()); + if (iter != mIndex.end()) return iter->second->onOpen(); return true; } void Objects::onClose(const MWWorld::Ptr& ptr) { - PtrControllerMap::iterator iter = mObjects.find(ptr); - if(iter != mObjects.end()) + const auto iter = mIndex.find(ptr.getBase()); + if (iter != mIndex.end()) iter->second->onClose(); } bool Objects::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist) { - PtrControllerMap::iterator iter = mObjects.find(ptr); - if(iter != mObjects.end()) + const auto iter = mIndex.find(ptr.getBase()); + if (iter != mIndex.end()) { return iter->second->playGroup(groupName, mode, number, persist); } @@ -126,24 +114,22 @@ bool Objects::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& gro } void Objects::skipAnimation(const MWWorld::Ptr& ptr) { - PtrControllerMap::iterator iter = mObjects.find(ptr); - if(iter != mObjects.end()) + const auto iter = mIndex.find(ptr.getBase()); + if (iter != mIndex.end()) iter->second->skipAnim(); } void Objects::persistAnimationStates() { - for (PtrControllerMap::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) - iter->second->persistAnimationState(); + for (CharacterController& object : mObjects) + object.persistAnimationState(); } -void Objects::getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out) +void Objects::getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out) const { - for (PtrControllerMap::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) - { - if ((position - iter->first.getRefData().getPosition().asVec3()).length2() <= radius*radius) - out.push_back(iter->first); - } + for (const CharacterController& object : mObjects) + if ((position - object.getPtr().getRefData().getPosition().asVec3()).length2() <= radius * radius) + out.push_back(object.getPtr()); } } diff --git a/apps/openmw/mwmechanics/objects.hpp b/apps/openmw/mwmechanics/objects.hpp index ba39fdbd4f..a6b2d7c675 100644 --- a/apps/openmw/mwmechanics/objects.hpp +++ b/apps/openmw/mwmechanics/objects.hpp @@ -1,9 +1,12 @@ #ifndef GAME_MWMECHANICS_ACTIVATORS_H #define GAME_MWMECHANICS_ACTIVATORS_H +#include "character.hpp" + #include #include #include +#include namespace osg { @@ -18,17 +21,12 @@ namespace MWWorld namespace MWMechanics { - class CharacterController; - class Objects { - typedef std::map PtrControllerMap; - PtrControllerMap mObjects; + std::list mObjects; + std::map::iterator> mIndex; public: - Objects() = default; - ~Objects(); - void addObject (const MWWorld::Ptr& ptr); ///< Register an animated object @@ -51,7 +49,7 @@ namespace MWMechanics void skipAnimation(const MWWorld::Ptr& ptr); void persistAnimationStates(); - void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector& out); + void getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out) const; std::size_t size() const {