diff --git a/libraries/ui/src/ui/types/ContextAwareProfile.cpp b/libraries/ui/src/ui/types/ContextAwareProfile.cpp index f74e8754c9..210e1f36b1 100644 --- a/libraries/ui/src/ui/types/ContextAwareProfile.cpp +++ b/libraries/ui/src/ui/types/ContextAwareProfile.cpp @@ -12,7 +12,9 @@ #include "ContextAwareProfile.h" #include +#include #include +#include #include #include @@ -20,20 +22,63 @@ static const QString RESTRICTED_FLAG_PROPERTY = "RestrictFileAccess"; -ContextAwareProfile::ContextAwareProfile(QQmlContext* context) : - ContextAwareProfileParent(context), _context(context) { +QReadWriteLock ContextAwareProfile::_contextMapProtect; +ContextAwareProfile::ContextMap ContextAwareProfile::_contextMap; + +ContextAwareProfile::ContextAwareProfile(QQmlContext* context) : ContextAwareProfileParent(context), _context(context) { assert(context); + + { // register our object for future updates + QWriteLocker guard(&_contextMapProtect); + ContextMap::iterator setLookup = _contextMap.find(_context); + if (setLookup == _contextMap.end()) { + setLookup = _contextMap.insert(_context, ContextAwareProfileSet()); + } + assert(setLookup != _contextMap.end()); + ContextAwareProfileSet& profileSet = setLookup.value(); + assert(profileSet.find(this) == profileSet.end()); + profileSet.insert(this); + } + + _isRestricted.store(isRestrictedGetProperty()); } +ContextAwareProfile::~ContextAwareProfile() { + // deregister our object + QWriteLocker guard(&_contextMapProtect); + ContextMap::iterator setLookup = _contextMap.find(_context); + assert(setLookup != _contextMap.end()); + if (setLookup != _contextMap.end()) { + ContextAwareProfileSet& profileSet = setLookup.value(); + assert(profileSet.find(this) != profileSet.end()); + profileSet.remove(this); + if (profileSet.isEmpty()) { + _contextMap.erase(setLookup); + } + } +} void ContextAwareProfile::restrictContext(QQmlContext* context, bool restrict) { + + // set the QML property context->setContextProperty(RESTRICTED_FLAG_PROPERTY, restrict); + + // broadcast the new value to any registered ContextAwareProfile objects + QReadLocker guard(&_contextMapProtect); + ContextMap::const_iterator setLookup = _contextMap.find(context); + if (setLookup != _contextMap.end()) { + const ContextAwareProfileSet& profileSet = setLookup.value(); + for (ContextAwareProfileSet::const_iterator profileIterator = profileSet.begin(); + profileIterator != profileSet.end(); profileIterator++) { + (*profileIterator)->_isRestricted.store(restrict); + } + } } -bool ContextAwareProfile::isRestrictedInternal() { +bool ContextAwareProfile::isRestrictedGetProperty() { if (QThread::currentThread() != thread()) { bool restrictedResult = false; - BLOCKING_INVOKE_METHOD(this, "isRestrictedInternal", Q_RETURN_ARG(bool, restrictedResult)); + BLOCKING_INVOKE_METHOD(this, "isRestrictedGetProperty", Q_RETURN_ARG(bool, restrictedResult)); return restrictedResult; } @@ -48,10 +93,5 @@ bool ContextAwareProfile::isRestrictedInternal() { } bool ContextAwareProfile::isRestricted() { - auto now = usecTimestampNow(); - if (now > _cacheExpiry) { - _cachedValue = isRestrictedInternal(); - _cacheExpiry = now + MAX_CACHE_AGE; - } - return _cachedValue; + return _isRestricted.load(); } diff --git a/libraries/ui/src/ui/types/ContextAwareProfile.h b/libraries/ui/src/ui/types/ContextAwareProfile.h index 3192d2be54..486ac5481a 100644 --- a/libraries/ui/src/ui/types/ContextAwareProfile.h +++ b/libraries/ui/src/ui/types/ContextAwareProfile.h @@ -11,7 +11,11 @@ #ifndef hifi_ContextAwareProfile_h #define hifi_ContextAwareProfile_h -#include +#include +#include +#include +#include +#include #if !defined(Q_OS_ANDROID) #include @@ -26,8 +30,6 @@ using ContextAwareProfileParent = QObject; using RequestInterceptorParent = QObject; #endif -#include - class QQmlContext; class ContextAwareProfile : public ContextAwareProfileParent { @@ -35,7 +37,7 @@ class ContextAwareProfile : public ContextAwareProfileParent { public: static void restrictContext(QQmlContext* context, bool restrict = true); bool isRestricted(); - Q_INVOKABLE bool isRestrictedInternal(); + Q_INVOKABLE bool isRestrictedGetProperty(); protected: class RequestInterceptor : public RequestInterceptorParent { @@ -47,10 +49,17 @@ protected: }; ContextAwareProfile(QQmlContext* parent); + ~ContextAwareProfile(); + +private: + typedef QSet ContextAwareProfileSet; + typedef QHash ContextMap; + QQmlContext* _context{ nullptr }; - bool _cachedValue{ false }; - quint64 _cacheExpiry{ 0 }; - constexpr static quint64 MAX_CACHE_AGE = MSECS_PER_SECOND; + std::atomic _isRestricted{ false }; + + static QReadWriteLock _contextMapProtect; + static ContextMap _contextMap; }; #endif // hifi_FileTypeProfile_h