From 60f93645aa2d5bd5d29da158fd3d90c317c39a64 Mon Sep 17 00:00:00 2001 From: Kitty Barnett <develop@catznip.com> Date: Sat, 4 Jun 2016 14:58:00 +0200 Subject: [PATCH] [FIXED] RlvHandler::hasBehaviourExcept() returns FALSE on modifier commands -> Example: issue @tplocal:50=n -> gRlvHandler.hasBehaviour(RLV_BHVR_TPLOCAL) will return true but gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOCAL, LLUUID::null) will return FALSE => since it's a modifier command it will be reference counted but that fact is lost on manual matching (tplocal=n != tplocal:<option>=n) so we keep track of reference counting in the command --HG-- branch : RLVa --- indra/newview/rlvhandler.cpp | 2 ++ indra/newview/rlvhelper.cpp | 14 ++++++++++++-- indra/newview/rlvhelper.h | 4 ++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index c1c4b7d8073..cbd54958e50 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -1251,6 +1251,7 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd) if (rlvCmd.isStrict()) addException(rlvCmd.getObjectID(), RLV_BHVR_PERMISSIVE, eBhvr); m_Behaviours[eBhvr]++; + rlvCmd.markRefCounted(); } else { @@ -1283,6 +1284,7 @@ ERlvCmdRet RlvCommandHandlerBaseImpl<RLV_TYPE_ADDREM>::processCommand(const RlvC if (rlvCmd.isStrict()) gRlvHandler.addException(rlvCmd.getObjectID(), RLV_BHVR_PERMISSIVE, eBhvr); gRlvHandler.m_Behaviours[eBhvr]++; + rlvCmd.markRefCounted(); } else { diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 4a4d8356b3f..d8baee2adf9 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -860,9 +860,19 @@ bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, bool fStrictOnly) const bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption, bool fStrictOnly) const { - for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) - if ( (itCmd->getBehaviourType() == eBehaviour) && (itCmd->getOption() == strOption) && ((!fStrictOnly) || (itCmd->isStrict())) ) + for (const RlvCommand& rlvCmd : m_Commands) + { + // The specified behaviour is contained within the current object if: + // - the (parsed) behaviour matches + // - the option matches (or we're checking for an empty option and the command was reference counted) + // - we're not matching on strict (or it is a strict command) + if ( (rlvCmd.getBehaviourType() == eBehaviour) && + ( (rlvCmd.getOption() == strOption) || ((strOption.empty()) && (rlvCmd.isRefCounted())) ) && + ( (!fStrictOnly) ||(rlvCmd.isStrict()) ) ) + { return true; + } + } return false; } diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index cfe64a48f52..41daab13603 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -369,12 +369,14 @@ class RlvCommand ERlvCmdRet getReturnType() const { return m_eRet; } bool hasOption() const { return !m_strOption.empty(); } bool isBlocked() const { return (m_pBhvrInfo) ? m_pBhvrInfo->isBlocked() : false; } + bool isRefCounted() const { return m_fRefCounted; } bool isStrict() const { return m_fStrict; } bool isValid() const { return m_fValid; } ERlvCmdRet processCommand() const { return (m_pBhvrInfo) ? m_pBhvrInfo->processCommand(*this) : RLV_RET_NO_PROCESSOR; } protected: static bool parseCommand(const std::string& strCommand, std::string& strBehaviour, std::string& strOption, std::string& strParam); + bool markRefCounted() const { return m_fRefCounted = true; } /* * Operators @@ -395,9 +397,11 @@ class RlvCommand std::string m_strOption; std::string m_strParam; ERlvCmdRet m_eRet; + mutable bool m_fRefCounted; friend class RlvHandler; friend class RlvObject; + template<ERlvParamType> friend struct RlvCommandHandlerBaseImpl; }; // ============================================================================ -- GitLab