Refactoring carousel: added a RlvBehaviourInfo::BHVR_BLOCKED behaviour flag to selectively block certain commands

-> currently only used for @setenv=n|y

--HG--
branch : RLVa
master
Kitty Barnett 2016-03-29 12:25:20 +02:00
parent 54e8d2fd52
commit cc93446ce7
3 changed files with 48 additions and 35 deletions

View File

@ -420,17 +420,18 @@ bool RlvHandler::notifyCommandHandlers(rlvCommandHandler f, const RlvCommand& rl
// Checked: 2009-11-25 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj)
{
#ifdef RLV_DEBUG
RLV_INFOS << "[" << rlvCmd.getObjectID() << "]: " << rlvCmd.asString() << RLV_ENDL;
#endif // RLV_DEBUG
RLV_DEBUGS << "[" << rlvCmd.getObjectID() << "]: " << rlvCmd.asString() << RLV_ENDL;
if (!rlvCmd.isValid())
{
#ifdef RLV_DEBUG
RLV_INFOS << "\t-> invalid syntax" << RLV_ENDL;
#endif // RLV_DEBUG
RLV_DEBUGS << "\t-> invalid syntax" << RLV_ENDL;
return RLV_RET_FAILED_SYNTAX;
}
if (rlvCmd.isBlocked())
{
RLV_DEBUGS << "\t-> blocked command" << RLV_ENDL;
return RLV_RET_FAILED_DISABLED;
}
// Using a stack for executing commands solves a few problems:
// - if we passed RlvObject::m_idObj for idObj somewhere and process a @clear then idObj points to invalid/cleared memory at the end
@ -447,9 +448,7 @@ ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj)
( (RLV_BHVR_SETDEBUG == rlvCmd.getBehaviourType()) || (RLV_BHVR_SETENV == rlvCmd.getBehaviourType()) ) )
{
// Some restrictions can only be held by one single object to avoid deadlocks
#ifdef RLV_DEBUG
RLV_INFOS << "\t- " << rlvCmd.getBehaviour() << " is already set by another object => discarding" << RLV_ENDL;
#endif // RLV_DEBUG
RLV_DEBUGS << "\t- " << rlvCmd.getBehaviour() << " is already set by another object => discarding" << RLV_ENDL;
eRet = RLV_RET_FAILED_LOCK;
break;
}
@ -467,9 +466,7 @@ ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj)
m_Objects.insert(std::pair<LLUUID, RlvObject>(idCurObj, rlvObj));
}
#ifdef RLV_DEBUG
RLV_INFOS << "\t- " << ( (fAdded) ? "adding behaviour" : "skipping duplicate" ) << RLV_ENDL;
#endif // RLV_DEBUG
RLV_DEBUGS << "\t- " << ( (fAdded) ? "adding behaviour" : "skipping duplicate" ) << RLV_ENDL;
if (fAdded) { // If FALSE then this was a duplicate, there's no need to handle those
if (!m_pGCTimer)
@ -490,10 +487,8 @@ ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj)
if (itObj != m_Objects.end())
fRemoved = itObj->second.removeCommand(rlvCmd);
#ifdef RLV_DEBUG
RLV_INFOS << "\t- " << ( (fRemoved) ? "removing behaviour"
: "skipping remove (unset behaviour or unknown object)") << RLV_ENDL;
#endif // RLV_DEBUG
RLV_DEBUGS << "\t- " << ( (fRemoved) ? "removing behaviour"
: "skipping remove (unset behaviour or unknown object)") << RLV_ENDL;
if (fRemoved) { // Don't handle non-sensical removes
eRet = processAddRemCommand(rlvCmd);
@ -501,9 +496,7 @@ ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj)
if (0 == itObj->second.m_Commands.size())
{
#ifdef RLV_DEBUG
RLV_INFOS << "\t- command list empty => removing " << idCurObj << RLV_ENDL;
#endif // RLV_DEBUG
RLV_DEBUGS << "\t- command list empty => removing " << idCurObj << RLV_ENDL;
m_Objects.erase(itObj);
}
}
@ -531,9 +524,7 @@ ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj)
m_OnCommand(rlvCmd, eRet, !fFromObj);
#ifdef RLV_DEBUG
RLV_INFOS << "\t--> command " << ((eRet & RLV_RET_SUCCESS) ? "succeeded" : "failed") << RLV_ENDL;
#endif // RLV_DEBUG
RLV_DEBUGS << "\t--> command " << ((eRet & RLV_RET_SUCCESS) ? "succeeded" : "failed") << RLV_ENDL;
m_CurCommandStack.pop(); m_CurObjectStack.pop();
return eRet;
@ -1327,16 +1318,6 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
case RLV_BHVR_DETACHTHISEXCEPT: // @detachthisexcept[:<option>]=n|y
eRet = onAddRemFolderLockException(rlvCmd, fRefCount);
break;
case RLV_BHVR_SETENV: // @setenv=n|y - Checked: 2011-09-04 (RLVa-1.4.1a) | Modified: RLVa-1.4.1a
{
if (RlvSettings::getNoSetEnv())
{
eRet = RLV_RET_FAILED_DISABLED;
break;
}
VERIFY_OPTION_REF(strOption.empty());
}
break;
case RLV_BHVR_ADDOUTFIT: // @addoutfit[:<layer>]=n|y - Checked: 2010-08-29 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c
case RLV_BHVR_REMOUTFIT: // @remoutfit[:<layer>]=n|y - Checked: 2010-08-29 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c
{

View File

@ -93,7 +93,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
addEntry(new RlvCommandGenericDefinition<RLV_TYPE_ADDREM, RLV_OPTION_NONE_OR_EXCEPTION>("sendim", RLV_BHVR_SENDIM, RlvBehaviourInfo::BHVR_STRICT));
addEntry(new RlvCommandGenericDefinition<RLV_TYPE_ADDREM, RLV_OPTION_EXCEPTION>("sendimto", RLV_BHVR_SENDIMTO, RlvBehaviourInfo::BHVR_STRICT));
addEntry(new RlvCommandGenericDefinition<RLV_TYPE_ADDREM, RLV_OPTION_NONE>("setdebug", RLV_BHVR_SETDEBUG));
addEntry(new RlvBehaviourInfo("setenv", RLV_BHVR_SETENV, RLV_TYPE_ADDREM));
addEntry(new RlvCommandGenericDefinition<RLV_TYPE_ADDREM, RLV_OPTION_NONE>("setenv", RLV_BHVR_SETENV));
addEntry(new RlvCommandGenericDefinition<RLV_TYPE_ADDREM, RLV_OPTION_NONE>("setgroup", RLV_BHVR_SETGROUP));
addEntry(new RlvBehaviourInfo("sharedunwear", RLV_BHVR_SHAREDUNWEAR, RLV_TYPE_ADDREM, RlvBehaviourInfo::BHVR_EXTENDED));
addEntry(new RlvBehaviourInfo("sharedwear", RLV_BHVR_SHAREDWEAR, RLV_TYPE_ADDREM, RlvBehaviourInfo::BHVR_EXTENDED));
@ -215,6 +215,10 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
m_Bhvr2InfoMap.insert(std::pair<ERlvBehaviour, const RlvBehaviourInfo*>(pBhvrInfo->getBehaviourType(), pBhvrInfo));
}
}
// Process blocked commands
if (RlvSettings::getNoSetEnv())
toggleBehaviourFlag("setenv", RLV_TYPE_ADDREM, RlvBehaviourInfo::BHVR_BLOCKED, true);
}
RlvBehaviourDictionary::~RlvBehaviourDictionary()
@ -282,6 +286,21 @@ bool RlvBehaviourDictionary::getHasStrict(ERlvBehaviour eBhvr) const
return (itBhvrInfo != m_Bhvr2InfoMap.cend()) && (itBhvrInfo->second->hasStrict());
}
void RlvBehaviourDictionary::toggleBehaviourFlag(const std::string& strBhvr, ERlvParamType eParamType, RlvBehaviourInfo::EBehaviourFlags eBhvrFlag, bool fEnable)
{
for (const rlv_string2info_map_t::value_type& bhvrInfo : boost::make_iterator_range(m_String2InfoMap.lower_bound(strBhvr), m_String2InfoMap.upper_bound(strBhvr)))
{
if (bhvrInfo.second->getParamTypeMask() & eParamType)
{
if (RlvBehaviourInfo* pBhvrInfo = const_cast<RlvBehaviourInfo*>(bhvrInfo.second))
{
pBhvrInfo->toggleBehaviourFlag(eBhvrFlag, fEnable);
}
break;
}
}
}
// ============================================================================
// RlvCommmand
//

View File

@ -39,6 +39,7 @@ public:
BHVR_SYNONYM = 0x0002, // Behaviour is a synonym of another
BHVR_EXTENDED = 0x0004, // Behaviour is part of the RLVa extended command set
BHVR_EXPERIMENTAL = 0x0008, // Behaviour is part of the RLVa experimental command set
BHVR_BLOCKED = 0x0010, // Behaviour is blocked
BHVR_GENERAL_MASK = 0x0FFF,
// Force-wear specific flags
@ -61,12 +62,14 @@ public:
U32 getBehaviourFlags() const { return m_nBhvrFlags; }
U32 getParamTypeMask() const { return m_maskParamType; }
bool hasStrict() const { return m_nBhvrFlags & BHVR_STRICT; }
bool isBlocked() const { return m_nBhvrFlags & BHVR_BLOCKED; }
bool isExperimental() const { return m_nBhvrFlags & BHVR_EXPERIMENTAL; }
bool isExtended() const { return m_nBhvrFlags & BHVR_EXTENDED; }
bool isSynonym() const { return m_nBhvrFlags & BHVR_SYNONYM; }
void toggleBehaviourFlag(EBehaviourFlags eBhvrFlag, bool fEnable);
virtual bool hasProcessor() const { return false; }
virtual ERlvCmdRet processCommand(const RlvCommand& rlvCmd, bool& fRefCount) const { return RLV_RET_UNKNOWN; }
virtual bool hasProcessor() const { return false; }
virtual ERlvCmdRet processCommand(const RlvCommand& rlvCmd, bool& fRefCount) const { return RLV_RET_UNKNOWN; }
protected:
std::string m_strBhvr;
@ -133,6 +136,7 @@ public:
bool getCommands(const std::string& strMatch, ERlvParamType eParamType, std::list<std::string>& cmdList) const;
bool getHasStrict(ERlvBehaviour eBhvr) const;
const std::string& getStringFromBehaviour(ERlvBehaviour eBhvr, ERlvParamType eParamType, bool fStrict = false) const;
void toggleBehaviourFlag(const std::string& strBhvr, ERlvParamType eParamType, RlvBehaviourInfo::EBehaviourFlags eBvhrFlag, bool fEnable);
/*
* Member variables
@ -170,6 +174,7 @@ public:
ERlvParamType getParamType() const { return m_eParamType; }
ERlvCmdRet getReturnType() const { return m_eRet; }
bool hasOption() const { return !m_strOption.empty(); }
bool isBlocked() const { return (m_pBhvrInfo) ? m_pBhvrInfo->isBlocked() : false; }
bool isStrict() const { return m_fStrict; }
bool isValid() const { return m_fValid; }
bool hasProcessor() const { return (m_pBhvrInfo) ? m_pBhvrInfo->hasProcessor() : false; }
@ -546,6 +551,14 @@ std::string rlvGetLastParenthesisedText(const std::string& strText, std::string:
// Inlined class member functions
//
inline void RlvBehaviourInfo::toggleBehaviourFlag(EBehaviourFlags eBhvrFlag, bool fEnable)
{
if (fEnable)
m_nBhvrFlags |= eBhvrFlag;
else
m_nBhvrFlags &= ~eBhvrFlag;
}
// Checked: 2009-09-19 (RLVa-1.0.3d)
inline std::string RlvCommand::asString() const
{