1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-31 14:36:39 +00:00

Avoid changing map when updating ptr

This is not necessary and has overhead.
This commit is contained in:
elsid 2022-05-20 23:07:50 +02:00
parent 58207fc1e3
commit 24712e2cb1
No known key found for this signature in database
GPG key ID: B845CB9FEE18AB40
6 changed files with 108 additions and 106 deletions

View file

@ -44,26 +44,26 @@ namespace MWRender
if (!mEnabled) if (!mEnabled)
return; return;
const auto group = mGroups.find(actor); const auto group = mGroups.find(actor.mRef);
if (group != mGroups.end()) if (group != mGroups.end())
mRootNode->removeChild(group->second); mRootNode->removeChild(group->second.mNode);
const auto newGroup = SceneUtil::createAgentPathGroup(path, halfExtents, start, end, settings.mRecast); auto newGroup = SceneUtil::createAgentPathGroup(path, halfExtents, start, end, settings.mRecast);
if (newGroup) if (newGroup)
{ {
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(newGroup, "debug"); MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(newGroup, "debug");
newGroup->setNodeMask(Mask_Debug); newGroup->setNodeMask(Mask_Debug);
mRootNode->addChild(newGroup); mRootNode->addChild(newGroup);
mGroups[actor] = newGroup; mGroups[actor.mRef] = Group {actor.mCell, std::move(newGroup)};
} }
} }
void ActorsPaths::remove(const MWWorld::ConstPtr& actor) void ActorsPaths::remove(const MWWorld::ConstPtr& actor)
{ {
const auto group = mGroups.find(actor); const auto group = mGroups.find(actor.mRef);
if (group != mGroups.end()) if (group != mGroups.end())
{ {
mRootNode->removeChild(group->second); mRootNode->removeChild(group->second.mNode);
mGroups.erase(group); mGroups.erase(group);
} }
} }
@ -72,9 +72,9 @@ namespace MWRender
{ {
for (auto it = mGroups.begin(); it != mGroups.end(); ) for (auto it = mGroups.begin(); it != mGroups.end(); )
{ {
if (it->first.getCell() == store) if (it->second.mCell == store)
{ {
mRootNode->removeChild(it->second); mRootNode->removeChild(it->second.mNode);
it = mGroups.erase(it); it = mGroups.erase(it);
} }
else else
@ -84,25 +84,23 @@ namespace MWRender
void ActorsPaths::updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) void ActorsPaths::updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated)
{ {
const auto it = mGroups.find(old); const auto it = mGroups.find(old.mRef);
if (it == mGroups.end()) if (it == mGroups.end())
return; return;
auto group = std::move(it->second); it->second.mCell = updated.mCell;
mGroups.erase(it);
mGroups.insert(std::make_pair(updated, std::move(group)));
} }
void ActorsPaths::enable() void ActorsPaths::enable()
{ {
std::for_each(mGroups.begin(), mGroups.end(), std::for_each(mGroups.begin(), mGroups.end(),
[&] (const Groups::value_type& v) { mRootNode->addChild(v.second); }); [&] (const Groups::value_type& v) { mRootNode->addChild(v.second.mNode); });
mEnabled = true; mEnabled = true;
} }
void ActorsPaths::disable() void ActorsPaths::disable()
{ {
std::for_each(mGroups.begin(), mGroups.end(), std::for_each(mGroups.begin(), mGroups.end(),
[&] (const Groups::value_type& v) { mRootNode->removeChild(v.second); }); [&] (const Groups::value_type& v) { mRootNode->removeChild(v.second.mNode); });
mEnabled = false; mEnabled = false;
} }
} }

View file

@ -44,7 +44,13 @@ namespace MWRender
void disable(); void disable();
private: private:
using Groups = std::map<MWWorld::ConstPtr, osg::ref_ptr<osg::Group>>; struct Group
{
const MWWorld::CellStore* mCell;
osg::ref_ptr<osg::Group> mNode;
};
using Groups = std::map<const MWWorld::LiveCellRefBase*, Group>;
osg::ref_ptr<osg::Group> mRootNode; osg::ref_ptr<osg::Group> mRootNode;
Groups mGroups; Groups mGroups;

View file

@ -34,7 +34,7 @@ Objects::~Objects()
void Objects::insertBegin(const MWWorld::Ptr& ptr) void Objects::insertBegin(const MWWorld::Ptr& ptr)
{ {
assert(mObjects.find(ptr) == mObjects.end()); assert(mObjects.find(ptr.mRef) == mObjects.end());
osg::ref_ptr<osg::Group> cellnode; osg::ref_ptr<osg::Group> cellnode;
@ -73,7 +73,7 @@ void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh, bool
osg::ref_ptr<ObjectAnimation> anim (new ObjectAnimation(ptr, mesh, mResourceSystem, animated, allowLight)); osg::ref_ptr<ObjectAnimation> anim (new ObjectAnimation(ptr, mesh, mResourceSystem, animated, allowLight));
mObjects.insert(std::make_pair(ptr, anim)); mObjects.emplace(ptr.mRef, std::move(anim));
} }
void Objects::insertCreature(const MWWorld::Ptr &ptr, const std::string &mesh, bool weaponsShields) void Objects::insertCreature(const MWWorld::Ptr &ptr, const std::string &mesh, bool weaponsShields)
@ -89,7 +89,7 @@ void Objects::insertCreature(const MWWorld::Ptr &ptr, const std::string &mesh, b
else else
anim = new CreatureAnimation(ptr, mesh, mResourceSystem); anim = new CreatureAnimation(ptr, mesh, mResourceSystem);
if (mObjects.insert(std::make_pair(ptr, anim)).second) if (mObjects.emplace(ptr.mRef, anim).second)
ptr.getClass().getContainerStore(ptr).setContListener(static_cast<ActorAnimation*>(anim.get())); ptr.getClass().getContainerStore(ptr).setContListener(static_cast<ActorAnimation*>(anim.get()));
} }
@ -100,7 +100,7 @@ void Objects::insertNPC(const MWWorld::Ptr &ptr)
osg::ref_ptr<NpcAnimation> anim (new NpcAnimation(ptr, osg::ref_ptr<osg::Group>(ptr.getRefData().getBaseNode()), mResourceSystem)); osg::ref_ptr<NpcAnimation> anim (new NpcAnimation(ptr, osg::ref_ptr<osg::Group>(ptr.getRefData().getBaseNode()), mResourceSystem));
if (mObjects.insert(std::make_pair(ptr, anim)).second) if (mObjects.emplace(ptr.mRef, anim).second)
{ {
ptr.getClass().getInventoryStore(ptr).setInvListener(anim.get(), ptr); ptr.getClass().getInventoryStore(ptr).setInvListener(anim.get(), ptr);
ptr.getClass().getInventoryStore(ptr).setContListener(anim.get()); ptr.getClass().getInventoryStore(ptr).setContListener(anim.get());
@ -112,7 +112,7 @@ bool Objects::removeObject (const MWWorld::Ptr& ptr)
if(!ptr.getRefData().getBaseNode()) if(!ptr.getRefData().getBaseNode())
return true; return true;
PtrAnimationMap::iterator iter = mObjects.find(ptr); const auto iter = mObjects.find(ptr.mRef);
if(iter != mObjects.end()) if(iter != mObjects.end())
{ {
mObjects.erase(iter); mObjects.erase(iter);
@ -191,19 +191,14 @@ void Objects::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &cur)
objectNode->getParent(0)->removeChild(objectNode); objectNode->getParent(0)->removeChild(objectNode);
cellnode->addChild(objectNode); cellnode->addChild(objectNode);
PtrAnimationMap::iterator iter = mObjects.find(old); PtrAnimationMap::iterator iter = mObjects.find(old.mRef);
if(iter != mObjects.end()) if(iter != mObjects.end())
{ iter->second->updatePtr(cur);
osg::ref_ptr<Animation> anim = iter->second;
mObjects.erase(iter);
anim->updatePtr(cur);
mObjects[cur] = anim;
}
} }
Animation* Objects::getAnimation(const MWWorld::Ptr &ptr) Animation* Objects::getAnimation(const MWWorld::Ptr &ptr)
{ {
PtrAnimationMap::const_iterator iter = mObjects.find(ptr); PtrAnimationMap::const_iterator iter = mObjects.find(ptr.mRef);
if(iter != mObjects.end()) if(iter != mObjects.end())
return iter->second; return iter->second;
@ -212,7 +207,7 @@ Animation* Objects::getAnimation(const MWWorld::Ptr &ptr)
const Animation* Objects::getAnimation(const MWWorld::ConstPtr &ptr) const const Animation* Objects::getAnimation(const MWWorld::ConstPtr &ptr) const
{ {
PtrAnimationMap::const_iterator iter = mObjects.find(ptr); PtrAnimationMap::const_iterator iter = mObjects.find(ptr.mRef);
if(iter != mObjects.end()) if(iter != mObjects.end())
return iter->second; return iter->second;

View file

@ -50,8 +50,9 @@ public:
MWWorld::Ptr mPtr; MWWorld::Ptr mPtr;
}; };
class Objects{ class Objects
typedef std::map<MWWorld::ConstPtr,osg::ref_ptr<Animation> > PtrAnimationMap; {
using PtrAnimationMap = std::map<const MWWorld::LiveCellRefBase*, osg::ref_ptr<Animation>>;
typedef std::map<const MWWorld::CellStore*, osg::ref_ptr<osg::Group> > CellMap; typedef std::map<const MWWorld::CellStore*, osg::ref_ptr<osg::Group> > CellMap;
CellMap mCellSceneNodes; CellMap mCellSceneNodes;

View file

@ -371,15 +371,15 @@ namespace MWSound
StreamPtr sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer())); StreamPtr sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer()));
if(!sound) return; if(!sound) return;
mSaySoundsQueue.emplace(ptr, std::move(sound)); mSaySoundsQueue.emplace(ptr.mRef, SaySound {ptr.mCell, std::move(sound)});
} }
float SoundManager::getSaySoundLoudness(const MWWorld::ConstPtr &ptr) const float SoundManager::getSaySoundLoudness(const MWWorld::ConstPtr &ptr) const
{ {
SaySoundMap::const_iterator snditer = mActiveSaySounds.find(ptr); SaySoundMap::const_iterator snditer = mActiveSaySounds.find(ptr.mRef);
if(snditer != mActiveSaySounds.end()) if(snditer != mActiveSaySounds.end())
{ {
Stream *sound = snditer->second.get(); Stream *sound = snditer->second.mStream.get();
return mOutput->getStreamLoudness(sound); return mOutput->getStreamLoudness(sound);
} }
@ -399,15 +399,15 @@ namespace MWSound
StreamPtr sound = playVoice(decoder, osg::Vec3f(), true); StreamPtr sound = playVoice(decoder, osg::Vec3f(), true);
if(!sound) return; if(!sound) return;
mActiveSaySounds.emplace(MWWorld::ConstPtr(), std::move(sound)); mActiveSaySounds.emplace(nullptr, SaySound {nullptr, std::move(sound)});
} }
bool SoundManager::sayDone(const MWWorld::ConstPtr &ptr) const bool SoundManager::sayDone(const MWWorld::ConstPtr &ptr) const
{ {
SaySoundMap::const_iterator snditer = mActiveSaySounds.find(ptr); SaySoundMap::const_iterator snditer = mActiveSaySounds.find(ptr.mRef);
if(snditer != mActiveSaySounds.end()) if(snditer != mActiveSaySounds.end())
{ {
if(mOutput->isStreamPlaying(snditer->second.get())) if(mOutput->isStreamPlaying(snditer->second.mStream.get()))
return false; return false;
return true; return true;
} }
@ -416,18 +416,18 @@ namespace MWSound
bool SoundManager::sayActive(const MWWorld::ConstPtr &ptr) const bool SoundManager::sayActive(const MWWorld::ConstPtr &ptr) const
{ {
SaySoundMap::const_iterator snditer = mSaySoundsQueue.find(ptr); SaySoundMap::const_iterator snditer = mSaySoundsQueue.find(ptr.mRef);
if(snditer != mSaySoundsQueue.end()) if(snditer != mSaySoundsQueue.end())
{ {
if(mOutput->isStreamPlaying(snditer->second.get())) if(mOutput->isStreamPlaying(snditer->second.mStream.get()))
return true; return true;
return false; return false;
} }
snditer = mActiveSaySounds.find(ptr); snditer = mActiveSaySounds.find(ptr.mRef);
if(snditer != mActiveSaySounds.end()) if(snditer != mActiveSaySounds.end())
{ {
if(mOutput->isStreamPlaying(snditer->second.get())) if(mOutput->isStreamPlaying(snditer->second.mStream.get()))
return true; return true;
return false; return false;
} }
@ -437,17 +437,17 @@ namespace MWSound
void SoundManager::stopSay(const MWWorld::ConstPtr &ptr) void SoundManager::stopSay(const MWWorld::ConstPtr &ptr)
{ {
SaySoundMap::iterator snditer = mSaySoundsQueue.find(ptr); SaySoundMap::iterator snditer = mSaySoundsQueue.find(ptr.mRef);
if(snditer != mSaySoundsQueue.end()) if(snditer != mSaySoundsQueue.end())
{ {
mOutput->finishStream(snditer->second.get()); mOutput->finishStream(snditer->second.mStream.get());
mSaySoundsQueue.erase(snditer); mSaySoundsQueue.erase(snditer);
} }
snditer = mActiveSaySounds.find(ptr); snditer = mActiveSaySounds.find(ptr.mRef);
if(snditer != mActiveSaySounds.end()) if(snditer != mActiveSaySounds.end())
{ {
mOutput->finishStream(snditer->second.get()); mOutput->finishStream(snditer->second.mStream.get());
mActiveSaySounds.erase(snditer); mActiveSaySounds.erase(snditer);
} }
} }
@ -513,7 +513,7 @@ namespace MWSound
return nullptr; return nullptr;
Sound* result = sound.get(); Sound* result = sound.get();
mActiveSounds[MWWorld::ConstPtr()].emplace_back(std::move(sound), sfx); mActiveSounds[nullptr].mList.emplace_back(std::move(sound), sfx);
mSoundBuffers.use(*sfx); mSoundBuffers.use(*sfx);
return result; return result;
} }
@ -571,7 +571,10 @@ namespace MWSound
return nullptr; return nullptr;
Sound* result = sound.get(); Sound* result = sound.get();
mActiveSounds[ptr].emplace_back(std::move(sound), sfx); auto it = mActiveSounds.find(ptr.mRef);
if (it == mActiveSounds.end())
it = mActiveSounds.emplace(ptr.mRef, ActiveSound {ptr.mCell, {}}).first;
it->second.mList.emplace_back(std::move(sound), sfx);
mSoundBuffers.use(*sfx); mSoundBuffers.use(*sfx);
return result; return result;
} }
@ -606,7 +609,7 @@ namespace MWSound
return nullptr; return nullptr;
Sound* result = sound.get(); Sound* result = sound.get();
mActiveSounds[MWWorld::ConstPtr()].emplace_back(std::move(sound), sfx); mActiveSounds[nullptr].mList.emplace_back(std::move(sound), sfx);
mSoundBuffers.use(*sfx); mSoundBuffers.use(*sfx);
return result; return result;
} }
@ -619,10 +622,10 @@ namespace MWSound
void SoundManager::stopSound(Sound_Buffer *sfx, const MWWorld::ConstPtr &ptr) void SoundManager::stopSound(Sound_Buffer *sfx, const MWWorld::ConstPtr &ptr)
{ {
SoundMap::iterator snditer = mActiveSounds.find(ptr); SoundMap::iterator snditer = mActiveSounds.find(ptr.mRef);
if(snditer != mActiveSounds.end()) if(snditer != mActiveSounds.end())
{ {
for(SoundBufferRefPair &snd : snditer->second) for (SoundBufferRefPair &snd : snditer->second.mList)
{ {
if(snd.second == sfx) if(snd.second == sfx)
mOutput->finishSound(snd.first.get()); mOutput->finishSound(snd.first.get());
@ -643,54 +646,54 @@ namespace MWSound
void SoundManager::stopSound3D(const MWWorld::ConstPtr &ptr) void SoundManager::stopSound3D(const MWWorld::ConstPtr &ptr)
{ {
SoundMap::iterator snditer = mActiveSounds.find(ptr); SoundMap::iterator snditer = mActiveSounds.find(ptr.mRef);
if(snditer != mActiveSounds.end()) if(snditer != mActiveSounds.end())
{ {
for(SoundBufferRefPair &snd : snditer->second) for (SoundBufferRefPair &snd : snditer->second.mList)
mOutput->finishSound(snd.first.get()); mOutput->finishSound(snd.first.get());
} }
SaySoundMap::iterator sayiter = mSaySoundsQueue.find(ptr); SaySoundMap::iterator sayiter = mSaySoundsQueue.find(ptr.mRef);
if(sayiter != mSaySoundsQueue.end()) if(sayiter != mSaySoundsQueue.end())
mOutput->finishStream(sayiter->second.get()); mOutput->finishStream(sayiter->second.mStream.get());
sayiter = mActiveSaySounds.find(ptr); sayiter = mActiveSaySounds.find(ptr.mRef);
if(sayiter != mActiveSaySounds.end()) if(sayiter != mActiveSaySounds.end())
mOutput->finishStream(sayiter->second.get()); mOutput->finishStream(sayiter->second.mStream.get());
} }
void SoundManager::stopSound(const MWWorld::CellStore *cell) void SoundManager::stopSound(const MWWorld::CellStore *cell)
{ {
for(SoundMap::value_type &snd : mActiveSounds) for (auto& [ref, sound] : mActiveSounds)
{ {
if(!snd.first.isEmpty() && snd.first != MWMechanics::getPlayer() && snd.first.getCell() == cell) if (ref != nullptr && ref != MWMechanics::getPlayer().mRef && sound.mCell == cell)
{ {
for(SoundBufferRefPair &sndbuf : snd.second) for (SoundBufferRefPair& sndbuf : sound.mList)
mOutput->finishSound(sndbuf.first.get()); mOutput->finishSound(sndbuf.first.get());
} }
} }
for(SaySoundMap::value_type &snd : mSaySoundsQueue) for (const auto& [ref, sound] : mSaySoundsQueue)
{ {
if(!snd.first.isEmpty() && snd.first != MWMechanics::getPlayer() && snd.first.getCell() == cell) if (ref != nullptr && ref != MWMechanics::getPlayer().mRef && sound.mCell == cell)
mOutput->finishStream(snd.second.get()); mOutput->finishStream(sound.mStream.get());
} }
for(SaySoundMap::value_type &snd : mActiveSaySounds) for (const auto& [ref, sound]: mActiveSaySounds)
{ {
if(!snd.first.isEmpty() && snd.first != MWMechanics::getPlayer() && snd.first.getCell() == cell) if (ref != nullptr && ref != MWMechanics::getPlayer().mRef && sound.mCell == cell)
mOutput->finishStream(snd.second.get()); mOutput->finishStream(sound.mStream.get());
} }
} }
void SoundManager::fadeOutSound3D(const MWWorld::ConstPtr &ptr, void SoundManager::fadeOutSound3D(const MWWorld::ConstPtr &ptr,
const std::string& soundId, float duration) const std::string& soundId, float duration)
{ {
SoundMap::iterator snditer = mActiveSounds.find(ptr); SoundMap::iterator snditer = mActiveSounds.find(ptr.mRef);
if(snditer != mActiveSounds.end()) if(snditer != mActiveSounds.end())
{ {
Sound_Buffer *sfx = mSoundBuffers.lookup(Misc::StringUtils::lowerCase(soundId)); Sound_Buffer *sfx = mSoundBuffers.lookup(Misc::StringUtils::lowerCase(soundId));
if (sfx == nullptr) if (sfx == nullptr)
return; return;
for(SoundBufferRefPair &sndbuf : snditer->second) for (SoundBufferRefPair &sndbuf : snditer->second.mList)
{ {
if(sndbuf.second == sfx) if(sndbuf.second == sfx)
sndbuf.first->setFadeout(duration); sndbuf.first->setFadeout(duration);
@ -700,14 +703,14 @@ namespace MWSound
bool SoundManager::getSoundPlaying(const MWWorld::ConstPtr &ptr, const std::string& soundId) const bool SoundManager::getSoundPlaying(const MWWorld::ConstPtr &ptr, const std::string& soundId) const
{ {
SoundMap::const_iterator snditer = mActiveSounds.find(ptr); SoundMap::const_iterator snditer = mActiveSounds.find(ptr.mRef);
if(snditer != mActiveSounds.end()) if(snditer != mActiveSounds.end())
{ {
Sound_Buffer *sfx = mSoundBuffers.lookup(Misc::StringUtils::lowerCase(soundId)); Sound_Buffer *sfx = mSoundBuffers.lookup(Misc::StringUtils::lowerCase(soundId));
return std::find_if(snditer->second.cbegin(), snditer->second.cend(), return std::find_if(snditer->second.mList.cbegin(), snditer->second.mList.cend(),
[this,sfx](const SoundBufferRefPair &snd) -> bool [this,sfx](const SoundBufferRefPair &snd) -> bool
{ return snd.second == sfx && mOutput->isSoundPlaying(snd.first.get()); } { return snd.second == sfx && mOutput->isSoundPlaying(snd.first.get()); }
) != snditer->second.cend(); ) != snditer->second.mList.cend();
} }
return false; return false;
} }
@ -819,15 +822,15 @@ namespace MWSound
Sound_Buffer* sfx = mSoundBuffers.lookup(update.mId); Sound_Buffer* sfx = mSoundBuffers.lookup(update.mId);
if (mLastCell != cell) if (mLastCell != cell)
{ {
const auto snditer = mActiveSounds.find(MWWorld::ConstPtr()); const auto snditer = mActiveSounds.find(nullptr);
if (snditer != mActiveSounds.end()) if (snditer != mActiveSounds.end())
{ {
const auto pairiter = std::find_if( const auto pairiter = std::find_if(
snditer->second.begin(), snditer->second.end(), snditer->second.mList.begin(), snditer->second.mList.end(),
[this](const SoundBufferRefPairList::value_type &item) -> bool [this](const SoundBufferRefPairList::value_type &item) -> bool
{ return mNearWaterSound == item.first.get(); } { return mNearWaterSound == item.first.get(); }
); );
if (pairiter != snditer->second.end() && pairiter->second != sfx) if (pairiter != snditer->second.mList.end() && pairiter->second != sfx)
soundIdChanged = true; soundIdChanged = true;
} }
} }
@ -915,8 +918,8 @@ namespace MWSound
while(snditer != mActiveSounds.end()) while(snditer != mActiveSounds.end())
{ {
MWWorld::ConstPtr ptr = snditer->first; MWWorld::ConstPtr ptr = snditer->first;
SoundBufferRefPairList::iterator sndidx = snditer->second.begin(); SoundBufferRefPairList::iterator sndidx = snditer->second.mList.begin();
while(sndidx != snditer->second.end()) while(sndidx != snditer->second.mList.end())
{ {
Sound *sound = sndidx->first.get(); Sound *sound = sndidx->first.get();
@ -936,7 +939,7 @@ namespace MWSound
if (sound == mNearWaterSound) if (sound == mNearWaterSound)
mNearWaterSound = nullptr; mNearWaterSound = nullptr;
mSoundBuffers.release(*sndidx->second); mSoundBuffers.release(*sndidx->second);
sndidx = snditer->second.erase(sndidx); sndidx = snditer->second.mList.erase(sndidx);
} }
else else
{ {
@ -944,7 +947,7 @@ namespace MWSound
++sndidx; ++sndidx;
} }
} }
if(snditer->second.empty()) if(snditer->second.mList.empty())
snditer = mActiveSounds.erase(snditer); snditer = mActiveSounds.erase(snditer);
else else
++snditer; ++snditer;
@ -954,7 +957,7 @@ namespace MWSound
while(sayiter != mActiveSaySounds.end()) while(sayiter != mActiveSaySounds.end())
{ {
MWWorld::ConstPtr ptr = sayiter->first; MWWorld::ConstPtr ptr = sayiter->first;
Stream *sound = sayiter->second.get(); Stream *sound = sayiter->second.mStream.get();
if (sound->getIs3D()) if (sound->getIs3D())
{ {
if (!ptr.isEmpty()) if (!ptr.isEmpty())
@ -1047,7 +1050,7 @@ namespace MWSound
mOutput->startUpdate(); mOutput->startUpdate();
for(SoundMap::value_type &snd : mActiveSounds) for(SoundMap::value_type &snd : mActiveSounds)
{ {
for(SoundBufferRefPair &sndbuf : snd.second) for (SoundBufferRefPair& sndbuf : snd.second.mList)
{ {
Sound *sound = sndbuf.first.get(); Sound *sound = sndbuf.first.get();
sound->setBaseVolume(volumeFromType(sound->getPlayType())); sound->setBaseVolume(volumeFromType(sound->getPlayType()));
@ -1056,13 +1059,13 @@ namespace MWSound
} }
for(SaySoundMap::value_type &snd : mActiveSaySounds) for(SaySoundMap::value_type &snd : mActiveSaySounds)
{ {
Stream *sound = snd.second.get(); Stream *sound = snd.second.mStream.get();
sound->setBaseVolume(volumeFromType(sound->getPlayType())); sound->setBaseVolume(volumeFromType(sound->getPlayType()));
mOutput->updateStream(sound); mOutput->updateStream(sound);
} }
for(SaySoundMap::value_type &snd : mSaySoundsQueue) for(SaySoundMap::value_type &snd : mSaySoundsQueue)
{ {
Stream *sound = snd.second.get(); Stream *sound = snd.second.mStream.get();
sound->setBaseVolume(volumeFromType(sound->getPlayType())); sound->setBaseVolume(volumeFromType(sound->getPlayType()));
mOutput->updateStream(sound); mOutput->updateStream(sound);
} }
@ -1092,29 +1095,15 @@ namespace MWSound
void SoundManager::updatePtr(const MWWorld::ConstPtr &old, const MWWorld::ConstPtr &updated) void SoundManager::updatePtr(const MWWorld::ConstPtr &old, const MWWorld::ConstPtr &updated)
{ {
SoundMap::iterator snditer = mActiveSounds.find(old); SoundMap::iterator snditer = mActiveSounds.find(old.mRef);
if(snditer != mActiveSounds.end()) if(snditer != mActiveSounds.end())
{ snditer->second.mCell = updated.mCell;
SoundBufferRefPairList sndlist = std::move(snditer->second);
mActiveSounds.erase(snditer);
mActiveSounds.emplace(updated, std::move(sndlist));
}
SaySoundMap::iterator sayiter = mSaySoundsQueue.find(old); if (const auto it = mSaySoundsQueue.find(old.mRef); it != mSaySoundsQueue.end())
if(sayiter != mSaySoundsQueue.end()) it->second.mCell = updated.mCell;
{
StreamPtr stream = std::move(sayiter->second);
mSaySoundsQueue.erase(sayiter);
mSaySoundsQueue.emplace(updated, std::move(stream));
}
sayiter = mActiveSaySounds.find(old); if (const auto it = mActiveSaySounds.find(old.mRef); it != mActiveSaySounds.end())
if(sayiter != mActiveSaySounds.end()) it->second.mCell = updated.mCell;
{
StreamPtr stream = std::move(sayiter->second);
mActiveSaySounds.erase(sayiter);
mActiveSaySounds.emplace(updated, std::move(stream));
}
} }
// Default readAll implementation, for decoders that can't do anything // Default readAll implementation, for decoders that can't do anything
@ -1188,7 +1177,7 @@ namespace MWSound
for(SoundMap::value_type &snd : mActiveSounds) for(SoundMap::value_type &snd : mActiveSounds)
{ {
for(SoundBufferRefPair &sndbuf : snd.second) for (SoundBufferRefPair &sndbuf : snd.second.mList)
{ {
mOutput->finishSound(sndbuf.first.get()); mOutput->finishSound(sndbuf.first.get());
mSoundBuffers.release(*sndbuf.second); mSoundBuffers.release(*sndbuf.second);
@ -1199,11 +1188,11 @@ namespace MWSound
mNearWaterSound = nullptr; mNearWaterSound = nullptr;
for(SaySoundMap::value_type &snd : mSaySoundsQueue) for(SaySoundMap::value_type &snd : mSaySoundsQueue)
mOutput->finishStream(snd.second.get()); mOutput->finishStream(snd.second.mStream.get());
mSaySoundsQueue.clear(); mSaySoundsQueue.clear();
for(SaySoundMap::value_type &snd : mActiveSaySounds) for(SaySoundMap::value_type &snd : mActiveSaySounds)
mOutput->finishStream(snd.second.get()); mOutput->finishStream(snd.second.mStream.get());
mActiveSaySounds.clear(); mActiveSaySounds.clear();
for(StreamPtr& sound : mActiveTracks) for(StreamPtr& sound : mActiveTracks)

View file

@ -64,10 +64,23 @@ namespace MWSound
typedef std::pair<SoundPtr, Sound_Buffer*> SoundBufferRefPair; typedef std::pair<SoundPtr, Sound_Buffer*> SoundBufferRefPair;
typedef std::vector<SoundBufferRefPair> SoundBufferRefPairList; typedef std::vector<SoundBufferRefPair> SoundBufferRefPairList;
typedef std::map<MWWorld::ConstPtr,SoundBufferRefPairList> SoundMap;
struct ActiveSound
{
const MWWorld::CellStore* mCell = nullptr;
SoundBufferRefPairList mList;
};
typedef std::map<const MWWorld::LiveCellRefBase*, ActiveSound> SoundMap;
SoundMap mActiveSounds; SoundMap mActiveSounds;
typedef std::map<MWWorld::ConstPtr, StreamPtr> SaySoundMap; struct SaySound
{
const MWWorld::CellStore* mCell;
StreamPtr mStream;
};
typedef std::map<const MWWorld::LiveCellRefBase*, SaySound> SaySoundMap;
SaySoundMap mSaySoundsQueue; SaySoundMap mSaySoundsQueue;
SaySoundMap mActiveSaySounds; SaySoundMap mActiveSaySounds;