diff --git a/indra/newview/llvisualeffect.cpp b/indra/newview/llvisualeffect.cpp index ae1ea11695faccf0e24cf56238edf7f67ce0c4ba..3a4594ff09194b8dd01df3978af125c7e2796f7d 100644 --- a/indra/newview/llvisualeffect.cpp +++ b/indra/newview/llvisualeffect.cpp @@ -70,7 +70,6 @@ LLVector4 LLTweenableValueLerp<LLVector4>::get() LLVfxManager::LLVfxManager() { - } bool LLVfxManager::addEffect(LLVisualEffect* pEffectInst) @@ -81,7 +80,7 @@ bool LLVfxManager::addEffect(LLVisualEffect* pEffectInst) if (m_Effects.end() != itEffect) return false; - m_Effects.insert(pEffectInst); + m_Effects.insert(std::upper_bound(m_Effects.begin(), m_Effects.end(), pEffectInst, cmpEffect), pEffectInst); return true; } @@ -91,6 +90,20 @@ LLVisualEffect* LLVfxManager::getEffect(EVisualEffect eCode, const LLUUID& idEff return (m_Effects.end() != itEffect) ? *itEffect : nullptr; } +bool LLVfxManager::getEffects(std::list<LLVisualEffect*>& effectList, std::function<bool(const LLVisualEffect*)> fnFilter) +{ + effectList.clear(); + + auto itEffect = boost::make_filter_iterator(fnFilter, m_Effects.begin(), m_Effects.end()), + endEffect = boost::make_filter_iterator(fnFilter, m_Effects.end(), m_Effects.end()); + while (itEffect != endEffect) + { + effectList.push_back(*itEffect++); + } + + return effectList.size(); +} + bool LLVfxManager::removeEffect(EVisualEffect eCode, const LLUUID& idEffect) { auto itEffect = std::find_if(m_Effects.begin(), m_Effects.end(), [eCode, &idEffect](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode && pEffect->getId() == idEffect; }); @@ -104,33 +117,54 @@ bool LLVfxManager::removeEffect(EVisualEffect eCode, const LLUUID& idEffect) void LLVfxManager::runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams) { - // *TODO-Catz: once we're done, check whether iterating over the entire list still has negliable impact - auto pred = [eCode](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode; }; + runEffect([eCode](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode; }, pParams); +} + +void LLVfxManager::runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams) +{ + runEffect([eType](const LLVisualEffect* pEffect) { return pEffect->getType() == eType; }, pParams); +} - auto itEffect = boost::make_filter_iterator(pred, m_Effects.begin(), m_Effects.end()), - endEffect = boost::make_filter_iterator(pred, m_Effects.end(), m_Effects.end()); +void LLVfxManager::runEffect(std::function<bool(const LLVisualEffect*)> predicate, LLVisualEffectParams* pParams) +{ + // *TODO-Catz: once we're done, check whether iterating over the entire list still has negliable impact + auto itEffect = boost::make_filter_iterator(predicate, m_Effects.begin(), m_Effects.end()), + endEffect = boost::make_filter_iterator(predicate, m_Effects.end(), m_Effects.end()); while (itEffect != endEffect) { LLVisualEffect* pEffect = *itEffect++; - if (pParams) - pParams->step(itEffect == endEffect); - pEffect->run(pParams); + if (pEffect->getEnabled()) + { + if (pParams) + pParams->step(itEffect == endEffect); + pEffect->run(pParams); + } } } -void LLVfxManager::runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams) +void LLVfxManager::updateEffect(LLVisualEffect* pEffect, bool fEnabled, U32 nPriority) { - // *TODO-Catz: once we're done, check whether iterating over the entire list still has negliable impact - auto pred = [eType](const LLVisualEffect* pEffect) { return pEffect->getType() == eType; }; + llassert(m_Effects.end() != std::find(m_Effects.begin(), m_Effects.end(), pEffect)); + + if ( (pEffect->getEnabled() != fEnabled) || (pEffect->getPriority() != nPriority) ) + { + pEffect->setEnabled(fEnabled); + pEffect->setPriority(nPriority); + std::sort(m_Effects.begin(), m_Effects.end(), cmpEffect); + } +} - auto itEffect = boost::make_filter_iterator(pred, m_Effects.begin(), m_Effects.end()), - endEffect = boost::make_filter_iterator(pred, m_Effects.end(), m_Effects.end()); - for (; itEffect != endEffect; ++itEffect) +// static +bool LLVfxManager::cmpEffect(const LLVisualEffect* pLHS, const LLVisualEffect* pRHS) +{ + if (pLHS && pRHS) { - if (pParams) - pParams->step(itEffect == endEffect); - (*itEffect)->run(pParams); + // Sort by code, then priority, then memory address + return (pLHS->getCode() == pRHS->getCode()) ? (pLHS->getPriority() == pRHS->getPriority() ? pLHS < pRHS + : pLHS->getPriority() > pRHS->getPriority()) + : pLHS->getCode() < pRHS->getCode(); } + return (pLHS); } // ============================================================================ diff --git a/indra/newview/llvisualeffect.h b/indra/newview/llvisualeffect.h index 55fbd13468136e8d807846b35c65c4e260c1d4cc..959e0dbc836210406980b9e9b884fd73eb2439af 100644 --- a/indra/newview/llvisualeffect.h +++ b/indra/newview/llvisualeffect.h @@ -71,6 +71,7 @@ struct LLShaderEffectParams : LLVisualEffectParams class LLVisualEffect { + friend class LLVfxManager; public: LLVisualEffect(LLUUID id, EVisualEffect eCode, EVisualEffectType eType) : m_id(id), m_eCode(eCode), m_eType(eType) @@ -78,12 +79,17 @@ class LLVisualEffect virtual ~LLVisualEffect() {} EVisualEffect getCode() const { return m_eCode;} + bool getEnabled() const { return m_fEnabled; } const LLUUID& getId() const { return m_id;} U32 getPriority() const { return m_nPriority; } EVisualEffectType getType() const { return m_eType;} + void setEnabled(bool enable) { m_fEnabled = enable; } virtual void run(const LLVisualEffectParams* pParams) = 0; +protected: + void setPriority(U32 priority) { m_nPriority = priority; } + /* * Member variables */ @@ -91,7 +97,8 @@ class LLVisualEffect LLUUID m_id; EVisualEffect m_eCode; EVisualEffectType m_eType; - U32 m_nPriority; + bool m_fEnabled = true; + U32 m_nPriority = 0; }; // ============================================================================ @@ -161,18 +168,23 @@ class LLVfxManager : public LLSingleton<LLVfxManager> bool addEffect(LLVisualEffect* pEffectInst); LLVisualEffect* getEffect(EVisualEffect eCode, const LLUUID& idEffect) const; template<typename T> T* getEffect(const LLUUID& idEffect) const { return dynamic_cast<T*>(getEffect(T::EffectCode, idEffect)); } + bool getEffects(std::list<LLVisualEffect*>& effectList, std::function<bool(const LLVisualEffect*)> fnFilter); + template<typename T> bool getEffects(std::list<LLVisualEffect*>& effectList) { return getEffects(effectList, [](const LLVisualEffect* pEffect) { return pEffect->getCode() == T::EffectCode; }); } bool hasEffect(EVisualEffect eCode) const; bool removeEffect(EVisualEffect eCode, const LLUUID& idEffect); template<typename T> bool removeEffect(const LLUUID& idEffect) { return removeEffect(T::EffectCode, idEffect); } void runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams = nullptr); void runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams = nullptr); + void updateEffect(LLVisualEffect* pEffect, bool fEnabled, U32 nPriority); protected: + void runEffect(std::function<bool(const LLVisualEffect*)> fnFilter, LLVisualEffectParams* pParams); + static bool cmpEffect(const LLVisualEffect* pLHS, const LLVisualEffect* pRHS); /* * Member variables */ protected: - std::set<LLVisualEffect*> m_Effects; + std::vector<LLVisualEffect*> m_Effects; }; // ============================================================================