Merge pull request #7612 from aws-lumberyard-dev/Atom/guthadam/removing_thumbnail_context_from_thumbnail_system

Removing thumbnail context from thumbnail system
monroegm-disable-blank-issue-2
Guthrie Adams 4 years ago committed by GitHub
commit 1b366fbad8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -21,7 +21,6 @@
#include <AzToolsFramework/AssetBrowser/AssetEntryChangeset.h> #include <AzToolsFramework/AssetBrowser/AssetEntryChangeset.h>
#include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntryCache.h> #include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntryCache.h>
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h> #include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/FolderThumbnail.h> #include <AzToolsFramework/AssetBrowser/Thumbnails/FolderThumbnail.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/SourceThumbnail.h> #include <AzToolsFramework/AssetBrowser/Thumbnails/SourceThumbnail.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h> #include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
@ -71,9 +70,9 @@ namespace AzToolsFramework
AssetBrowserInteractionNotificationBus::Handler::BusConnect(); AssetBrowserInteractionNotificationBus::Handler::BusConnect();
using namespace Thumbnailer; using namespace Thumbnailer;
ThumbnailerRequestBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(FolderThumbnailCache), ThumbnailContext::DefaultContext); ThumbnailerRequestBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(FolderThumbnailCache));
ThumbnailerRequestBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(SourceThumbnailCache), ThumbnailContext::DefaultContext); ThumbnailerRequestBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(SourceThumbnailCache));
ThumbnailerRequestBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(ProductThumbnailCache), ThumbnailContext::DefaultContext); ThumbnailerRequestBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(ProductThumbnailCache));
AzFramework::SocketConnection* socketConn = AzFramework::SocketConnection::GetInstance(); AzFramework::SocketConnection* socketConn = AzFramework::SocketConnection::GetInstance();
AZ_Assert(socketConn, "AzToolsFramework::AssetBrowser::AssetBrowserComponent requires a valid socket conection!"); AZ_Assert(socketConn, "AzToolsFramework::AssetBrowser::AssetBrowserComponent requires a valid socket conection!");

@ -75,7 +75,9 @@ namespace AzToolsFramework
bool foundIt = false; bool foundIt = false;
AZStd::string watchFolder; AZStd::string watchFolder;
AZ::Data::AssetInfo assetInfo; AZ::Data::AssetInfo assetInfo;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(foundIt, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, iconPath.toUtf8().constData(), assetInfo, watchFolder); AssetSystemRequestBus::BroadcastResult(
foundIt, &AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, iconPath.toUtf8().constData(), assetInfo,
watchFolder);
if (foundIt) if (foundIt)
{ {

@ -67,7 +67,8 @@ namespace AzToolsFramework
bool foundIt = false; bool foundIt = false;
AZStd::string watchFolder; AZStd::string watchFolder;
AZ::Data::AssetInfo assetInfo; AZ::Data::AssetInfo assetInfo;
AssetSystemRequestBus::BroadcastResult(foundIt, &AssetSystemRequestBus::Events::GetSourceInfoBySourceUUID, sourceKey->GetSourceUuid(), assetInfo, watchFolder); AssetSystemRequestBus::BroadcastResult(
foundIt, &AssetSystemRequestBus::Events::GetSourceInfoBySourceUUID, sourceKey->GetSourceUuid(), assetInfo, watchFolder);
QString iconPathToUse; QString iconPathToUse;
if (foundIt) if (foundIt)

@ -203,11 +203,6 @@ namespace AzToolsFramework
return selectionModel()->selectedIndexes(); return selectionModel()->selectedIndexes();
} }
void AssetBrowserTreeView::SetThumbnailContext(const char* thumbnailContext) const
{
m_delegate->SetThumbnailContext(thumbnailContext);
}
void AssetBrowserTreeView::SetShowSourceControlIcons(bool showSourceControlsIcons) void AssetBrowserTreeView::SetShowSourceControlIcons(bool showSourceControlsIcons)
{ {
m_delegate->SetShowSourceControlIcons(showSourceControlsIcons); m_delegate->SetShowSourceControlIcons(showSourceControlsIcons);

@ -73,7 +73,6 @@ namespace AzToolsFramework
void OnAssetBrowserComponentReady() override; void OnAssetBrowserComponentReady() override;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void SetThumbnailContext(const char* context) const;
void SetShowSourceControlIcons(bool showSourceControlsIcons); void SetShowSourceControlIcons(bool showSourceControlsIcons);
void UpdateAfterFilter(bool hasFilter, bool selectFirstValidEntry); void UpdateAfterFilter(bool hasFilter, bool selectFirstValidEntry);

@ -112,11 +112,6 @@ namespace AzToolsFramework
} }
} }
void EntryDelegate::SetThumbnailContext(const char* thumbnailContext)
{
m_thumbnailContext = thumbnailContext;
}
void EntryDelegate::SetShowSourceControlIcons(bool showSourceControl) void EntryDelegate::SetShowSourceControlIcons(bool showSourceControl)
{ {
m_showSourceControl = showSourceControl; m_showSourceControl = showSourceControl;
@ -125,8 +120,8 @@ namespace AzToolsFramework
int EntryDelegate::DrawThumbnail(QPainter* painter, const QPoint& point, const QSize& size, Thumbnailer::SharedThumbnailKey thumbnailKey) const int EntryDelegate::DrawThumbnail(QPainter* painter, const QPoint& point, const QSize& size, Thumbnailer::SharedThumbnailKey thumbnailKey) const
{ {
SharedThumbnail thumbnail; SharedThumbnail thumbnail;
ThumbnailerRequestsBus::BroadcastResult(thumbnail, &ThumbnailerRequests::GetThumbnail, thumbnailKey, m_thumbnailContext.c_str()); ThumbnailerRequestBus::BroadcastResult(thumbnail, &ThumbnailerRequests::GetThumbnail, thumbnailKey);
AZ_Assert(thumbnail, "The shared numbernail was not available from the ThumbnailerRequestsBus."); AZ_Assert(thumbnail, "The shared numbernail was not available from the ThumbnailerRequestBus.");
AZ_Assert(painter, "A null QPainter was passed in to DrawThumbnail."); AZ_Assert(painter, "A null QPainter was passed in to DrawThumbnail.");
if (!painter || !thumbnail || thumbnail->GetState() == Thumbnail::State::Failed) if (!painter || !thumbnail || thumbnail->GetState() == Thumbnail::State::Failed)
{ {

@ -11,7 +11,6 @@
#if !defined(Q_MOC_RUN) #if !defined(Q_MOC_RUN)
#include <AzCore/std/function/function_fwd.h> #include <AzCore/std/function/function_fwd.h>
#include <AzToolsFramework/Thumbnails/Thumbnail.h> #include <AzToolsFramework/Thumbnails/Thumbnail.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // 4251: class 'QScopedPointer<QBrushData,QBrushDataPointerDeleter>' needs to have dll-interface to be used by clients of class 'QBrush' AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // 4251: class 'QScopedPointer<QBrushData,QBrushDataPointerDeleter>' needs to have dll-interface to be used by clients of class 'QBrush'
// 4800: 'uint': forcing value to bool 'true' or 'false' (performance warning) // 4800: 'uint': forcing value to bool 'true' or 'false' (performance warning)
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
@ -50,14 +49,11 @@ namespace AzToolsFramework
QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override;
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
//! Set location where thumbnails are located for this instance of asset browser
void SetThumbnailContext(const char* thumbnailContext);
//! Set whether to show source control icons, this is still temporary mainly to support existing functionality of material browser //! Set whether to show source control icons, this is still temporary mainly to support existing functionality of material browser
void SetShowSourceControlIcons(bool showSourceControl); void SetShowSourceControlIcons(bool showSourceControl);
protected: protected:
int m_iconSize; int m_iconSize;
AZStd::string m_thumbnailContext = ThumbnailContext::DefaultContext;
bool m_showSourceControl = false; bool m_showSourceControl = false;
//! Draw a thumbnail and return its width //! Draw a thumbnail and return its width
int DrawThumbnail(QPainter* painter, const QPoint& point, const QSize& size, Thumbnailer::SharedThumbnailKey thumbnailKey) const; int DrawThumbnail(QPainter* painter, const QPoint& point, const QSize& size, Thumbnailer::SharedThumbnailKey thumbnailKey) const;

@ -23,7 +23,15 @@ namespace AzToolsFramework
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// ThumbnailKey // ThumbnailKey
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
bool ThumbnailKey::IsReady() const { return m_ready; } void ThumbnailKey::SetReady(bool ready)
{
m_ready = ready;
}
bool ThumbnailKey::IsReady() const
{
return m_ready;
}
bool ThumbnailKey::UpdateThumbnail() bool ThumbnailKey::UpdateThumbnail()
{ {
@ -75,10 +83,8 @@ namespace AzToolsFramework
if (m_state == State::Unloaded) if (m_state == State::Unloaded)
{ {
m_state = State::Loading; m_state = State::Loading;
QThreadPool* threadPool; QThreadPool* threadPool = {};
ThumbnailContextRequestBus::BroadcastResult( ThumbnailerRequestBus::BroadcastResult(threadPool, &ThumbnailerRequestBus::Handler::GetThreadPool);
threadPool,
&ThumbnailContextRequestBus::Handler::GetThreadPool);
QFuture<void> future = QtConcurrent::run(threadPool, [this](){ LoadThread(); }); QFuture<void> future = QtConcurrent::run(threadPool, [this](){ LoadThread(); });
m_watcher.setFuture(future); m_watcher.setFuture(future);
} }

@ -26,13 +26,11 @@ namespace AzToolsFramework
//! ThumbnailKey is used to locate thumbnails in thumbnail cache //! ThumbnailKey is used to locate thumbnails in thumbnail cache
/* /*
ThumbnailKey contains any kind of identifiable information to retrieve thumbnails (e.g. assetId, assetType, filename, etc.) ThumbnailKey contains any kind of identifiable information to retrieve thumbnails (e.g. assetId, assetType, filename, etc.)
To use thumbnail system, keep reference to your thumbnail key, and retrieve Thumbnail via ThumbnailerRequestsBus To use thumbnail system, keep reference to your thumbnail key, and retrieve Thumbnail via ThumbnailerRequestBus
*/ */
class ThumbnailKey class ThumbnailKey
: public QObject : public QObject
{ {
friend class ThumbnailContext;
Q_OBJECT Q_OBJECT
public: public:
AZ_RTTI(ThumbnailKey, "{43F20F6B-333D-4226-8E4F-331A62315255}"); AZ_RTTI(ThumbnailKey, "{43F20F6B-333D-4226-8E4F-331A62315255}");
@ -40,6 +38,8 @@ namespace AzToolsFramework
ThumbnailKey() = default; ThumbnailKey() = default;
virtual ~ThumbnailKey() = default; virtual ~ThumbnailKey() = default;
void SetReady(bool ready);
bool IsReady() const; bool IsReady() const;
virtual bool UpdateThumbnail(); virtual bool UpdateThumbnail();
@ -47,13 +47,13 @@ namespace AzToolsFramework
virtual size_t GetHash() const; virtual size_t GetHash() const;
virtual bool Equals(const ThumbnailKey* other) const; virtual bool Equals(const ThumbnailKey* other) const;
Q_SIGNALS: Q_SIGNALS:
//! Updated signal is dispatched whenever thumbnail data was changed. Anyone using this thumbnail should listen to this. //! Updated signal is dispatched whenever thumbnail data was changed. Anyone using this thumbnail should listen to this.
void ThumbnailUpdatedSignal() const; void ThumbnailUpdatedSignal() const;
//! Force update mapped thumbnails //! Force update mapped thumbnails
void UpdateThumbnailSignal() const; void UpdateThumbnailSignal() const;
private: private:
bool m_ready = false; bool m_ready = false;
}; };
@ -114,11 +114,14 @@ namespace AzToolsFramework
ThumbnailProvider() = default; ThumbnailProvider() = default;
virtual ~ThumbnailProvider() = default; virtual ~ThumbnailProvider() = default;
virtual bool GetThumbnail(SharedThumbnailKey key, SharedThumbnail& thumbnail) = 0; virtual bool GetThumbnail(SharedThumbnailKey key, SharedThumbnail& thumbnail) = 0;
//! Priority identifies ThumbnailProvider order in ThumbnailContext //! Priority identifies ThumbnailProvider order
//! Higher priority means this ThumbnailProvider will take precedence in generating a thumbnail when //! Higher priority means this ThumbnailProvider will take precedence in generating a thumbnail when a supplied ThumbnailKey is
//! a supplied ThumbnailKey is supported by multiple providers. //! supported by multiple providers.
virtual int GetPriority() const { return 0; } virtual int GetPriority() const
//! A unique ThumbnailProvider name identifying it in a ThumbnailContext {
return 0;
}
//! A unique ThumbnailProvider name identifyier
virtual const char* GetProviderName() const = 0; virtual const char* GetProviderName() const = 0;
}; };

@ -1,132 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <AzToolsFramework/Thumbnails/MissingThumbnail.h>
#include <AzToolsFramework/Thumbnails/LoadingThumbnail.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
AZ_PUSH_DISABLE_WARNING(4244 4251, "-Wunknown-warning-option") // 4251: 'QImageIOHandler::d_ptr': class 'QScopedPointer<QImageIOHandlerPrivate,QScopedPointerDeleter<T>>' needs to have dll-interface to be used by clients of class 'QImageIOHandler'
#include <AzQtComponents/Components/StyledBusyLabel.h>
AZ_POP_DISABLE_WARNING
namespace AzToolsFramework
{
namespace Thumbnailer
{
ThumbnailContext::ThumbnailContext()
: m_missingThumbnail(new MissingThumbnail())
, m_loadingThumbnail(new LoadingThumbnail())
, m_threadPool(this)
{
ThumbnailContextRequestBus::Handler::BusConnect();
}
ThumbnailContext::~ThumbnailContext()
{
ThumbnailContextRequestBus::Handler::BusDisconnect();
}
bool ThumbnailContext::IsLoading(SharedThumbnailKey key)
{
SharedThumbnail thumbnail;
for (auto& provider : m_providers)
{
if (provider->GetThumbnail(key, thumbnail))
{
return thumbnail->GetState() == Thumbnail::State::Unloaded ||
thumbnail->GetState() == Thumbnail::State::Loading;
}
}
return false;
}
void ThumbnailContext::RedrawThumbnail()
{
AzToolsFramework::AssetBrowser::AssetBrowserViewRequestBus::Broadcast(&AzToolsFramework::AssetBrowser::AssetBrowserViewRequests::Update);
}
QThreadPool* ThumbnailContext::GetThreadPool()
{
return &m_threadPool;
}
SharedThumbnail ThumbnailContext::GetThumbnail(SharedThumbnailKey key)
{
SharedThumbnail thumbnail;
// find provider who can handle supplied key
for (auto& provider : m_providers)
{
if (provider->GetThumbnail(key, thumbnail))
{
// if thumbnail is ready return it
if (thumbnail->GetState() == Thumbnail::State::Ready)
{
return thumbnail;
}
// if thumbnail is not loaded, start loading it, meanwhile return loading thumbnail
if (thumbnail->GetState() == Thumbnail::State::Unloaded)
{
// listen to the loading signal, so the anyone using it will update loading animation
connect(m_loadingThumbnail.data(), &Thumbnail::Updated, key.data(), &ThumbnailKey::ThumbnailUpdatedSignal);
AzQtComponents::StyledBusyLabel* busyLabel;
AzToolsFramework::AssetBrowser::AssetBrowserComponentRequestBus::BroadcastResult(busyLabel, &AzToolsFramework::AssetBrowser::AssetBrowserComponentRequests::GetStyledBusyLabel);
connect(busyLabel, &AzQtComponents::StyledBusyLabel::repaintNeeded, this, &ThumbnailContext::RedrawThumbnail);
// once the thumbnail is loaded, disconnect it from loading thumbnail
connect(thumbnail.data(), &Thumbnail::Updated, this , [this, key, thumbnail, busyLabel]()
{
disconnect(m_loadingThumbnail.data(), &Thumbnail::Updated, key.data(), &ThumbnailKey::ThumbnailUpdatedSignal);
disconnect(busyLabel, &AzQtComponents::StyledBusyLabel::repaintNeeded, this, &ThumbnailContext::RedrawThumbnail);
thumbnail->disconnect();
connect(thumbnail.data(), &Thumbnail::Updated, key.data(), &ThumbnailKey::ThumbnailUpdatedSignal);
connect(key.data(), &ThumbnailKey::UpdateThumbnailSignal, thumbnail.data(), &Thumbnail::Update);
key->m_ready = true;
Q_EMIT key->ThumbnailUpdatedSignal();
});
thumbnail->Load();
}
if (thumbnail->GetState() == Thumbnail::State::Failed)
{
return m_missingThumbnail;
}
return m_loadingThumbnail;
}
}
return m_missingThumbnail;
}
void ThumbnailContext::RegisterThumbnailProvider(SharedThumbnailProvider providerToAdd)
{
auto it = AZStd::find_if(m_providers.begin(), m_providers.end(), [providerToAdd](const SharedThumbnailProvider& provider)
{
return AZ::StringFunc::Equal(provider->GetProviderName(), providerToAdd->GetProviderName());
});
if (it != m_providers.end())
{
AZ_Error("ThumbnailContext", false, "Provider with name %s is already registered with context.", providerToAdd->GetProviderName());
return;
}
m_providers.insert(providerToAdd);
}
void ThumbnailContext::UnregisterThumbnailProvider(const char* providerName)
{
auto it = AZStd::remove_if(m_providers.begin(), m_providers.end(), [providerName](const SharedThumbnailProvider& provider)
{
return AZ::StringFunc::Equal(provider->GetProviderName(), providerName);
});
m_providers.erase(it, m_providers.end());
}
} // namespace Thumbnailer
} // namespace AzToolsFramework
#include "Thumbnails/moc_ThumbnailContext.cpp"

@ -1,86 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#if !defined(Q_MOC_RUN)
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/std/containers/set.h>
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
#include <QObject>
#include <QList>
#include <QThreadPool>
#endif
class QString;
class QPixmap;
namespace AzToolsFramework
{
namespace Thumbnailer
{
class ThumbnailProvider;
//! ThumbnailContext provides distinct thumbnail location for specific context
/*
There can be any number of contexts for every unique feature that may need different types of thumbnails.
For example 'AssetBrowser' context provides thumbnails specific to Asset Browser
'PreviewContext' may provide thumbnails for Preview Widget
'MaterialBrowser' may provide thumbnails for Material Browser
etc.
*/
class ThumbnailContext
: public QObject
, public ThumbnailContextRequestBus::Handler
{
Q_OBJECT
public:
AZ_CLASS_ALLOCATOR(ThumbnailContext, AZ::SystemAllocator, 0);
ThumbnailContext();
~ThumbnailContext() override;
//! Is the thumbnail currently loading or is about to load.
bool IsLoading(SharedThumbnailKey key);
//! Retrieve thumbnail by key, generate one if needed
SharedThumbnail GetThumbnail(SharedThumbnailKey key);
//! Add new thumbnail cache
void RegisterThumbnailProvider(SharedThumbnailProvider providerToAdd);
//! Remove thumbnail cache by name if found
void UnregisterThumbnailProvider(const char* providerName);
void RedrawThumbnail();
//! Default context used for most thumbnails
static constexpr const char* DefaultContext = "Default";
// ThumbnailContextRequestBus::Handler interface overrides...
QThreadPool* GetThreadPool() override;
private:
struct ProviderCompare {
bool operator() (const SharedThumbnailProvider& lhs, const SharedThumbnailProvider& rhs) const
{
// sorting in reverse, higher priority means the provider should be considered first
return lhs->GetPriority() > rhs->GetPriority();
}
};
//! Collection of thumbnail caches provided by this context
AZStd::multiset<SharedThumbnailProvider, ProviderCompare> m_providers;
//! Default missing thumbnail used when no thumbnail for given key can be found within this context
SharedThumbnail m_missingThumbnail;
//! Default loading thumbnail used when thumbnail is found by is not yet generated
SharedThumbnail m_loadingThumbnail;
//! There is only a limited number of threads on global threadPool, because there can be many thumbnails rendering at once
//! an individual threadPool is needed to avoid deadlocks
QThreadPool m_threadPool;
};
} // namespace Thumbnailer
} // namespace AzToolsFramework

@ -30,14 +30,13 @@ namespace AzToolsFramework
{ {
} }
void ThumbnailWidget::SetThumbnailKey(SharedThumbnailKey key, const char* contextName) void ThumbnailWidget::SetThumbnailKey(SharedThumbnailKey key)
{ {
if (m_key) if (m_key)
{ {
disconnect(m_key.data(), &ThumbnailKey::ThumbnailUpdatedSignal, this, &ThumbnailWidget::KeyUpdatedSlot); disconnect(m_key.data(), &ThumbnailKey::ThumbnailUpdatedSignal, this, &ThumbnailWidget::KeyUpdatedSlot);
} }
m_key = key; m_key = key;
m_contextName = contextName;
connect(m_key.data(), &ThumbnailKey::ThumbnailUpdatedSignal, this, &ThumbnailWidget::KeyUpdatedSlot); connect(m_key.data(), &ThumbnailKey::ThumbnailUpdatedSignal, this, &ThumbnailWidget::KeyUpdatedSlot);
repaint(); repaint();
} }
@ -65,7 +64,7 @@ namespace AzToolsFramework
{ {
// thumbnail instance is not stored locally, but retrieved each paintEvent since thumbnail mapped to a specific key may change // thumbnail instance is not stored locally, but retrieved each paintEvent since thumbnail mapped to a specific key may change
SharedThumbnail thumbnail; SharedThumbnail thumbnail;
ThumbnailerRequestsBus::BroadcastResult(thumbnail, &ThumbnailerRequests::GetThumbnail, m_key, m_contextName.c_str()); ThumbnailerRequestBus::BroadcastResult(thumbnail, &ThumbnailerRequests::GetThumbnail, m_key);
QPainter painter(this); QPainter painter(this);
// Scaling and centering pixmap within bounds to preserve aspect ratio // Scaling and centering pixmap within bounds to preserve aspect ratio

@ -32,7 +32,7 @@ namespace AzToolsFramework
~ThumbnailWidget() override = default; ~ThumbnailWidget() override = default;
//! Call this to set what thumbnail widget will display //! Call this to set what thumbnail widget will display
void SetThumbnailKey(SharedThumbnailKey key, const char* contextName = "Default"); void SetThumbnailKey(SharedThumbnailKey key);
//! Remove current thumbnail //! Remove current thumbnail
void ClearThumbnail(); void ClearThumbnail();
@ -44,7 +44,6 @@ namespace AzToolsFramework
private: private:
SharedThumbnailKey m_key; SharedThumbnailKey m_key;
AZStd::string m_contextName;
private Q_SLOTS: private Q_SLOTS:
void KeyUpdatedSlot(); void KeyUpdatedSlot();

@ -19,48 +19,30 @@ namespace AzToolsFramework
{ {
namespace Thumbnailer namespace Thumbnailer
{ {
//! Interaction with thumbnail context
class ThumbnailContextRequests
: public AZ::EBusTraits
{
public:
//! Get thread pool for drawing thumbnails
virtual QThreadPool* GetThreadPool() = 0;
};
using ThumbnailContextRequestBus = AZ::EBus<ThumbnailContextRequests>;
//! Interaction with thumbnailer //! Interaction with thumbnailer
class ThumbnailerRequests class ThumbnailerRequests
: public AZ::EBusTraits : public AZ::EBusTraits
{ {
public: public:
//! Add thumbnail context //! Add new thumbnail provider
virtual void RegisterContext(const char* contextName) = 0; virtual void RegisterThumbnailProvider(SharedThumbnailProvider provider) = 0;
//! Remove thumbnail context and all associated ThumbnailProviders
virtual void UnregisterContext(const char* contextName) = 0;
//! Return whether a given ThumbnailContext has been registered
virtual bool HasContext(const char* contextName) const = 0;
//! Add new thumbnail provider to ThumbnailContext
virtual void RegisterThumbnailProvider(SharedThumbnailProvider provider, const char* contextName) = 0;
//! Remove thumbnail provider from ThumbnailContext //! Remove thumbnail provider
virtual void UnregisterThumbnailProvider(const char* providerName, const char* contextName) = 0; virtual void UnregisterThumbnailProvider(const char* providerName) = 0;
//! Retrieve thumbnail by key, //! Retrieve thumbnail by key,
//! if no thumbnail matching found, one of ThumbnailProviders will attempt to create //! if no thumbnail matching found, one of ThumbnailProviders will attempt to create
//! If no compatible providers found, MissingThumbnail will be returned //! If no compatible providers found, MissingThumbnail will be returned
virtual SharedThumbnail GetThumbnail(SharedThumbnailKey thumbnailKey, const char* contextName) = 0; virtual SharedThumbnail GetThumbnail(SharedThumbnailKey thumbnailKey) = 0;
//! Return whether the thumbnail is loading. //! Return whether the thumbnail is loading.
virtual bool IsLoading(SharedThumbnailKey thumbnailKey, const char* contextName) = 0; virtual bool IsLoading(SharedThumbnailKey thumbnailKey) = 0;
//! Get thread pool for drawing thumbnails
virtual QThreadPool* GetThreadPool() = 0;
}; };
using ThumbnailerRequestBus = AZ::EBus<ThumbnailerRequests>; using ThumbnailerRequestBus = AZ::EBus<ThumbnailerRequests>;
using ThumbnailerRequestsBus = AZ::EBus<ThumbnailerRequests>; //deprecated
//! Request product thumbnail to be rendered //! Request product thumbnail to be rendered
class ThumbnailerRendererRequests class ThumbnailerRendererRequests

@ -6,11 +6,14 @@
* *
*/ */
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/Serialization/SerializeContext.h> #include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzQtComponents/Components/StyledBusyLabel.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/Thumbnails/LoadingThumbnail.h>
#include <AzToolsFramework/Thumbnails/MissingThumbnail.h>
#include <AzToolsFramework/Thumbnails/ThumbnailerComponent.h> #include <AzToolsFramework/Thumbnails/ThumbnailerComponent.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <QApplication> #include <QApplication>
#include <QStyle> #include <QStyle>
@ -19,8 +22,10 @@ namespace AzToolsFramework
{ {
namespace Thumbnailer namespace Thumbnailer
{ {
ThumbnailerComponent::ThumbnailerComponent() ThumbnailerComponent::ThumbnailerComponent()
: m_missingThumbnail(new MissingThumbnail())
, m_loadingThumbnail(new LoadingThumbnail())
, m_threadPool(this)
{ {
} }
@ -28,14 +33,13 @@ namespace AzToolsFramework
void ThumbnailerComponent::Activate() void ThumbnailerComponent::Activate()
{ {
RegisterContext(ThumbnailContext::DefaultContext); ThumbnailerRequestBus::Handler::BusConnect();
BusConnect();
} }
void ThumbnailerComponent::Deactivate() void ThumbnailerComponent::Deactivate()
{ {
BusDisconnect(); ThumbnailerRequestBus::Handler::BusDisconnect();
m_thumbnails.clear(); m_providers.clear();
} }
void ThumbnailerComponent::Reflect(AZ::ReflectContext* context) void ThumbnailerComponent::Reflect(AZ::ReflectContext* context)
@ -49,59 +53,114 @@ namespace AzToolsFramework
void ThumbnailerComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) void ThumbnailerComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{ {
incompatible.push_back(AZ_CRC("ThumbnailerService", 0x65422b97)); incompatible.push_back(AZ_CRC_CE("ThumbnailerService"));
} }
void ThumbnailerComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) void ThumbnailerComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{ {
provided.push_back(AZ_CRC("ThumbnailerService", 0x65422b97)); provided.push_back(AZ_CRC_CE("ThumbnailerService"));
} }
void ThumbnailerComponent::RegisterContext(const char* contextName) void ThumbnailerComponent::RegisterThumbnailProvider(SharedThumbnailProvider provider)
{ {
AZ_Assert(m_thumbnails.find(contextName) == m_thumbnails.end(), "Context %s already registered", contextName); auto it = AZStd::find_if(m_providers.begin(), m_providers.end(), [provider](const SharedThumbnailProvider& existingProvider)
m_thumbnails[contextName] = AZStd::make_shared<ThumbnailContext>(); {
} return AZ::StringFunc::Equal(provider->GetProviderName(), existingProvider->GetProviderName());
});
void ThumbnailerComponent::UnregisterContext(const char* contextName) if (it != m_providers.end())
{ {
AZ_Assert(m_thumbnails.find(contextName) != m_thumbnails.end(), "Context %s not registered", contextName); AZ_Error("ThumbnailerComponent", false, "Provider with name %s is already registered with context.", provider->GetProviderName());
m_thumbnails.erase(contextName); return;
}
m_providers.insert(provider);
} }
bool ThumbnailerComponent::HasContext(const char* contextName) const void ThumbnailerComponent::UnregisterThumbnailProvider(const char* providerName)
{ {
return m_thumbnails.find(contextName) != m_thumbnails.end(); AZStd::erase_if(
m_providers,
[providerName](const SharedThumbnailProvider& provider)
{
return AZ::StringFunc::Equal(provider->GetProviderName(), providerName);
});
} }
void ThumbnailerComponent::RegisterThumbnailProvider(SharedThumbnailProvider provider, const char* contextName) SharedThumbnail ThumbnailerComponent::GetThumbnail(SharedThumbnailKey key)
{ {
auto it = m_thumbnails.find(contextName); // find provider who can handle supplied key
AZ_Assert(it != m_thumbnails.end(), "Context %s not registered", contextName); for (auto& provider : m_providers)
it->second->RegisterThumbnailProvider(provider); {
SharedThumbnail thumbnail;
if (provider->GetThumbnail(key, thumbnail))
{
// if thumbnail is ready return it
if (thumbnail->GetState() == Thumbnail::State::Ready)
{
return thumbnail;
}
// if thumbnail is not loaded, start loading it, meanwhile return loading thumbnail
if (thumbnail->GetState() == Thumbnail::State::Unloaded)
{
// listen to the loading signal, so the anyone using it will update loading animation
AzQtComponents::StyledBusyLabel* busyLabel;
AssetBrowser::AssetBrowserComponentRequestBus::BroadcastResult(busyLabel, &AssetBrowser::AssetBrowserComponentRequests::GetStyledBusyLabel);
QObject::connect(m_loadingThumbnail.data(), &Thumbnail::Updated, key.data(), &ThumbnailKey::ThumbnailUpdatedSignal);
QObject::connect(busyLabel, &AzQtComponents::StyledBusyLabel::repaintNeeded, this, &ThumbnailerComponent::RedrawThumbnail);
// once the thumbnail is loaded, disconnect it from loading thumbnail
QObject::connect(thumbnail.data(), &Thumbnail::Updated, this , [this, key, thumbnail, busyLabel]()
{
QObject::disconnect(m_loadingThumbnail.data(), &Thumbnail::Updated, key.data(), &ThumbnailKey::ThumbnailUpdatedSignal);
QObject::disconnect(busyLabel, &AzQtComponents::StyledBusyLabel::repaintNeeded, this, &ThumbnailerComponent::RedrawThumbnail);
thumbnail->disconnect();
QObject::connect(thumbnail.data(), &Thumbnail::Updated, key.data(), &ThumbnailKey::ThumbnailUpdatedSignal);
QObject::connect(key.data(), &ThumbnailKey::UpdateThumbnailSignal, thumbnail.data(), &Thumbnail::Update);
key->SetReady(true);
Q_EMIT key->ThumbnailUpdatedSignal();
});
thumbnail->Load();
}
if (thumbnail->GetState() == Thumbnail::State::Failed)
{
return m_missingThumbnail;
}
return m_loadingThumbnail;
}
}
return m_missingThumbnail;
} }
void ThumbnailerComponent::UnregisterThumbnailProvider(const char* providerName, const char* contextName) bool ThumbnailerComponent::IsLoading(SharedThumbnailKey key)
{ {
auto it = m_thumbnails.find(contextName); for (auto& provider : m_providers)
AZ_Assert(it != m_thumbnails.end(), "Context %s not registered", contextName); {
it->second->UnregisterThumbnailProvider(providerName); SharedThumbnail thumbnail;
if (provider->GetThumbnail(key, thumbnail))
{
return thumbnail->GetState() == Thumbnail::State::Unloaded || thumbnail->GetState() == Thumbnail::State::Loading;
}
}
return false;
} }
SharedThumbnail ThumbnailerComponent::GetThumbnail(SharedThumbnailKey key, const char* contextName) QThreadPool* ThumbnailerComponent::GetThreadPool()
{ {
auto it = m_thumbnails.find(contextName); return &m_threadPool;
AZ_Assert(it != m_thumbnails.end(), "Context %s not registered", contextName);
return it->second->GetThumbnail(key);
} }
bool ThumbnailerComponent::IsLoading(SharedThumbnailKey key, const char* contextName) void ThumbnailerComponent::RedrawThumbnail()
{ {
auto it = m_thumbnails.find(contextName); AssetBrowser::AssetBrowserViewRequestBus::Broadcast(&AssetBrowser::AssetBrowserViewRequests::Update);
AZ_Assert(it != m_thumbnails.end(), "Context %s not registered", contextName);
return it->second->IsLoading(key);
} }
} // namespace Thumbnailer } // namespace Thumbnailer
} // namespace AzToolsFramework } // namespace AzToolsFramework

@ -7,19 +7,29 @@
*/ */
#pragma once #pragma once
#include <AzCore/Memory/SystemAllocator.h> #if !defined(Q_MOC_RUN)
#include <AzCore/Component/Component.h> #include <AzCore/Component/Component.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/std/containers/set.h>
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h> #include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
#include <QList>
#include <QObject>
#include <QThreadPool>
#endif
class QString;
class QPixmap;
namespace AzToolsFramework namespace AzToolsFramework
{ {
namespace Thumbnailer namespace Thumbnailer
{ {
class ThumbnailContext;
class ThumbnailerComponent class ThumbnailerComponent
: public AZ::Component : public AZ::Component
, public ThumbnailerRequestsBus::Handler , public ThumbnailerRequestBus::Handler
, public QObject
{ {
public: public:
AZ_COMPONENT(ThumbnailerComponent, "{80090CA5-6A3A-4554-B5FE-A6D74ECB2D84}") AZ_COMPONENT(ThumbnailerComponent, "{80090CA5-6A3A-4554-B5FE-A6D74ECB2D84}")
@ -27,28 +37,41 @@ namespace AzToolsFramework
ThumbnailerComponent(); ThumbnailerComponent();
virtual ~ThumbnailerComponent(); virtual ~ThumbnailerComponent();
////////////////////////////////////////////////////////////////////////// // AZ::Component overrides...
// AZ::Component
//////////////////////////////////////////////////////////////////////////
void Activate() override; void Activate() override;
void Deactivate() override; void Deactivate() override;
static void Reflect(AZ::ReflectContext* context); static void Reflect(AZ::ReflectContext* context);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
////////////////////////////////////////////////////////////////////////// // ThumbnailerRequestBus::Handler interface overrides...
// ThumbnailerRequests void RegisterThumbnailProvider(SharedThumbnailProvider provider) override;
////////////////////////////////////////////////////////////////////////// void UnregisterThumbnailProvider(const char* providerName) override;
void RegisterContext(const char* contextName) override; SharedThumbnail GetThumbnail(SharedThumbnailKey thumbnailKey) override;
void UnregisterContext(const char* contextName) override; bool IsLoading(SharedThumbnailKey thumbnailKey) override;
bool HasContext(const char* contextName) const override; QThreadPool* GetThreadPool() override;
void RegisterThumbnailProvider(SharedThumbnailProvider provider, const char* contextName) override;
void UnregisterThumbnailProvider(const char* providerName, const char* contextName) override; void RedrawThumbnail();
SharedThumbnail GetThumbnail(SharedThumbnailKey thumbnailKey, const char* contextName) override;
bool IsLoading(SharedThumbnailKey thumbnailKey, const char* contextName) override;
private: private:
AZStd::unordered_map<AZStd::string, AZStd::shared_ptr<ThumbnailContext>> m_thumbnails; struct ProviderCompare
{
bool operator()(const SharedThumbnailProvider& lhs, const SharedThumbnailProvider& rhs) const
{
// sorting in reverse, higher priority means the provider should be considered first
return lhs->GetPriority() > rhs->GetPriority();
}
};
//! Collection of thumbnail caches provided by this context
AZStd::multiset<SharedThumbnailProvider, ProviderCompare> m_providers;
//! Default missing thumbnail used when no thumbnail for given key can be found within this context
SharedThumbnail m_missingThumbnail;
//! Default loading thumbnail used when thumbnail is found by is not yet generated
SharedThumbnail m_loadingThumbnail;
//! There is only a limited number of threads on global threadPool, because there can be many thumbnails rendering at once
//! an individual threadPool is needed to avoid deadlocks
QThreadPool m_threadPool;
}; };
} // Thumbnailer } // Thumbnailer
} // namespace AssetBrowser } // namespace AssetBrowser

@ -9,7 +9,6 @@
#include <AzCore/std/smart_ptr/make_shared.h> #include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/Serialization/SerializeContext.h> #include <AzCore/Serialization/SerializeContext.h>
#include <AzToolsFramework/Thumbnails/ThumbnailerNullComponent.h> #include <AzToolsFramework/Thumbnails/ThumbnailerNullComponent.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <AzToolsFramework/Thumbnails/MissingThumbnail.h> #include <AzToolsFramework/Thumbnails/MissingThumbnail.h>
namespace AzToolsFramework namespace AzToolsFramework
@ -47,35 +46,27 @@ namespace AzToolsFramework
services.push_back(AZ_CRC("ThumbnailerService", 0x65422b97)); services.push_back(AZ_CRC("ThumbnailerService", 0x65422b97));
} }
void ThumbnailerNullComponent::RegisterContext(const char* /*contextName*/) void ThumbnailerNullComponent::RegisterThumbnailProvider(AzToolsFramework::Thumbnailer::SharedThumbnailProvider /*provider*/)
{ {
} }
void ThumbnailerNullComponent::UnregisterContext(const char* /*contextName*/) void ThumbnailerNullComponent::UnregisterThumbnailProvider(const char* /*providerName*/)
{ {
} }
bool ThumbnailerNullComponent::HasContext(const char* /*contextName*/) const AzToolsFramework::Thumbnailer::SharedThumbnail ThumbnailerNullComponent::GetThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey /*key*/)
{
return false;
}
void ThumbnailerNullComponent::RegisterThumbnailProvider(AzToolsFramework::Thumbnailer::SharedThumbnailProvider /*provider*/, const char* /*contextName*/)
{
}
void ThumbnailerNullComponent::UnregisterThumbnailProvider(const char* /*providerName*/, const char* /*contextName*/)
{ {
return m_nullThumbnail;
} }
AzToolsFramework::Thumbnailer::SharedThumbnail ThumbnailerNullComponent::GetThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey /*key*/, const char* /*contextName*/) bool ThumbnailerNullComponent::IsLoading(AzToolsFramework::Thumbnailer::SharedThumbnailKey /*thumbnailKey*/)
{ {
return m_nullThumbnail; return false;
} }
bool ThumbnailerNullComponent::IsLoading(AzToolsFramework::Thumbnailer::SharedThumbnailKey /*thumbnailKey*/, const char* /*contextName*/) QThreadPool* ThumbnailerNullComponent::GetThreadPool()
{ {
return false; return nullptr;
} }
} // namespace Thumbnailer } // namespace Thumbnailer
} // namespace AzToolsFramework } // namespace AzToolsFramework

@ -19,11 +19,9 @@ namespace AzToolsFramework
{ {
namespace Thumbnailer namespace Thumbnailer
{ {
class ThumbnailContext;
class ThumbnailerNullComponent class ThumbnailerNullComponent
: public AZ::Component : public AZ::Component
, public AzToolsFramework::Thumbnailer::ThumbnailerRequestsBus::Handler , public AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Handler
{ {
public: public:
AZ_COMPONENT(ThumbnailerNullComponent, "{8009D651-3FAA-9815-B99E-AF174A3B29D4}") AZ_COMPONENT(ThumbnailerNullComponent, "{8009D651-3FAA-9815-B99E-AF174A3B29D4}")
@ -42,13 +40,12 @@ namespace AzToolsFramework
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// ThumbnailerRequests // ThumbnailerRequests
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void RegisterContext(const char* contextName) override; void RegisterThumbnailProvider(AzToolsFramework::Thumbnailer::SharedThumbnailProvider provider) override;
void UnregisterContext(const char* contextName) override; void UnregisterThumbnailProvider(const char* providerName) override;
bool HasContext(const char* contextName) const override; AzToolsFramework::Thumbnailer::SharedThumbnail GetThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey) override;
void RegisterThumbnailProvider(AzToolsFramework::Thumbnailer::SharedThumbnailProvider provider, const char* contextName) override; bool IsLoading(AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey) override;
void UnregisterThumbnailProvider(const char* providerName, const char* contextName) override; QThreadPool* GetThreadPool() override;
AzToolsFramework::Thumbnailer::SharedThumbnail GetThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, const char* contextName) override;
bool IsLoading(AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, const char* contextName) override;
private: private:
AzToolsFramework::Thumbnailer::SharedThumbnail m_nullThumbnail; AzToolsFramework::Thumbnailer::SharedThumbnail m_nullThumbnail;
}; };

@ -52,7 +52,6 @@ AZ_POP_DISABLE_WARNING
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h> #include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/Thumbnails/ThumbnailWidget.h> #include <AzToolsFramework/Thumbnails/ThumbnailWidget.h>
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h> #include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h> #include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h> #include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
@ -1206,7 +1205,7 @@ namespace AzToolsFramework
SharedThumbnailKey thumbnailKey = MAKE_TKEY(AzToolsFramework::AssetBrowser::ProductThumbnailKey, assetID); SharedThumbnailKey thumbnailKey = MAKE_TKEY(AzToolsFramework::AssetBrowser::ProductThumbnailKey, assetID);
if (m_showThumbnail) if (m_showThumbnail)
{ {
m_thumbnail->SetThumbnailKey(thumbnailKey, Thumbnailer::ThumbnailContext::DefaultContext); m_thumbnail->SetThumbnailKey(thumbnailKey);
} }
return; return;
} }

@ -65,11 +65,11 @@ namespace AzToolsFramework
UpdateVisibility(); UpdateVisibility();
} }
void ThumbnailPropertyCtrl::SetThumbnailKey(Thumbnailer::SharedThumbnailKey key, const char* contextName) void ThumbnailPropertyCtrl::SetThumbnailKey(Thumbnailer::SharedThumbnailKey key)
{ {
m_key = key; m_key = key;
m_thumbnail->SetThumbnailKey(m_key, contextName); m_thumbnail->SetThumbnailKey(m_key);
m_thumbnailEnlarged->SetThumbnailKey(m_key, contextName); m_thumbnailEnlarged->SetThumbnailKey(m_key);
UpdateVisibility(); UpdateVisibility();
} }

@ -34,7 +34,7 @@ namespace AzToolsFramework
explicit ThumbnailPropertyCtrl(QWidget* parent = nullptr); explicit ThumbnailPropertyCtrl(QWidget* parent = nullptr);
//! Call this to set what thumbnail widget will display //! Call this to set what thumbnail widget will display
void SetThumbnailKey(Thumbnailer::SharedThumbnailKey key, const char* contextName = "Default"); void SetThumbnailKey(Thumbnailer::SharedThumbnailKey key);
//! Remove current thumbnail //! Remove current thumbnail
void ClearThumbnail(); void ClearThumbnail();

@ -86,8 +86,6 @@ set(FILES
Thumbnails/Thumbnail.cpp Thumbnails/Thumbnail.cpp
Thumbnails/Thumbnail.h Thumbnails/Thumbnail.h
Thumbnails/Thumbnail.inl Thumbnails/Thumbnail.inl
Thumbnails/ThumbnailContext.cpp
Thumbnails/ThumbnailContext.h
Thumbnails/ThumbnailerBus.h Thumbnails/ThumbnailerBus.h
Thumbnails/ThumbnailWidget.cpp Thumbnails/ThumbnailWidget.cpp
Thumbnails/ThumbnailWidget.h Thumbnails/ThumbnailWidget.h

@ -71,83 +71,4 @@ namespace UnitTest
AZ::Entity* m_testEntity = nullptr; AZ::Entity* m_testEntity = nullptr;
}; };
TEST_F(ThumbnailerTests, ThumbnailerComponent_RegisterUnregisterContext)
{
constexpr const char* contextName1 = "Context1";
constexpr const char* contextName2 = "Context2";
auto checkHasContext = [](const char* contextName)
{
bool hasContext = false;
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::BroadcastResult(hasContext, &AzToolsFramework::Thumbnailer::ThumbnailerRequests::HasContext, contextName);
return hasContext;
};
EXPECT_FALSE(checkHasContext(contextName1));
EXPECT_FALSE(checkHasContext(contextName2));
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName1);
EXPECT_TRUE(checkHasContext(contextName1));
EXPECT_FALSE(checkHasContext(contextName2));
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName2);
EXPECT_TRUE(checkHasContext(contextName1));
EXPECT_TRUE(checkHasContext(contextName2));
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::UnregisterContext, contextName1);
EXPECT_FALSE(checkHasContext(contextName1));
EXPECT_TRUE(checkHasContext(contextName2));
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::UnregisterContext, contextName2);
EXPECT_FALSE(checkHasContext(contextName1));
EXPECT_FALSE(checkHasContext(contextName2));
}
TEST_F(ThumbnailerTests, ThumbnailerComponent_Deactivate_ClearTumbnailContexts)
{
constexpr const char* contextName1 = "Context1";
constexpr const char* contextName2 = "Context2";
auto checkHasContext = [](const char* contextName)
{
bool hasContext = false;
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::BroadcastResult(hasContext, &AzToolsFramework::Thumbnailer::ThumbnailerRequests::HasContext, contextName);
return hasContext;
};
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName1);
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName2);
EXPECT_TRUE(checkHasContext(contextName1));
EXPECT_TRUE(checkHasContext(contextName2));
m_testEntity->Deactivate();
m_testEntity->Activate();
EXPECT_FALSE(checkHasContext(contextName1));
EXPECT_FALSE(checkHasContext(contextName2));
}
TEST_F(ThumbnailerTests, ThumbnailerComponent_RegisterContextTwice_Assert)
{
constexpr const char* contextName1 = "Context1";
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName1);
AZ_TEST_START_TRACE_SUPPRESSION;
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::RegisterContext, contextName1);
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
TEST_F(ThumbnailerTests, ThumbnailerComponent_UnregisterUnknownContext_Assert)
{
AZ_TEST_START_TRACE_SUPPRESSION;
AzToolsFramework::Thumbnailer::ThumbnailerRequestBus::Broadcast(&AzToolsFramework::Thumbnailer::ThumbnailerRequests::UnregisterContext, "ContextDoesNotExist");
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
}
} // namespace UnitTest } // namespace UnitTest

@ -59,10 +59,11 @@ namespace ImageProcessingAtom
void ImageThumbnail::LoadThread() void ImageThumbnail::LoadThread()
{ {
m_state = State::Loading;
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::Event( AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::Event(
AZ::RPI::StreamingImageAsset::RTTI_Type(), &AzToolsFramework::Thumbnailer::ThumbnailerRendererRequests::RenderThumbnail, AZ::RPI::StreamingImageAsset::RTTI_Type(), &AzToolsFramework::Thumbnailer::ThumbnailerRendererRequests::RenderThumbnail,
m_key, m_key, ImageThumbnailSize);
ImageThumbnailSize);
// wait for response from thumbnail renderer // wait for response from thumbnail renderer
m_renderWait.acquire(); m_renderWait.acquire();
} }
@ -70,6 +71,7 @@ namespace ImageProcessingAtom
void ImageThumbnail::ThumbnailRendered(const QPixmap& thumbnailImage) void ImageThumbnail::ThumbnailRendered(const QPixmap& thumbnailImage)
{ {
m_pixmap = thumbnailImage; m_pixmap = thumbnailImage;
m_state = State::Ready;
m_renderWait.release(); m_renderWait.release();
} }

@ -17,7 +17,6 @@
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h> #include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h> #include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/SourceThumbnail.h> #include <AzToolsFramework/AssetBrowser/Thumbnails/SourceThumbnail.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <ImageLoader/ImageLoaders.h> #include <ImageLoader/ImageLoaders.h>
#include <Processing/ImageConvert.h> #include <Processing/ImageConvert.h>
#include <Processing/ImageToProcess.h> #include <Processing/ImageToProcess.h>
@ -84,18 +83,15 @@ namespace ImageProcessingAtom
{ {
using namespace AzToolsFramework::Thumbnailer; using namespace AzToolsFramework::Thumbnailer;
ThumbnailerRequestsBus::Broadcast( ThumbnailerRequestBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(Thumbnails::ImageThumbnailCache));
&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(Thumbnails::ImageThumbnailCache),
ThumbnailContext::DefaultContext);
} }
void ImageThumbnailSystemComponent::TeardownThumbnails() void ImageThumbnailSystemComponent::TeardownThumbnails()
{ {
using namespace AzToolsFramework::Thumbnailer; using namespace AzToolsFramework::Thumbnailer;
ThumbnailerRequestsBus::Broadcast( ThumbnailerRequestBus::Broadcast(
&ThumbnailerRequests::UnregisterThumbnailProvider, Thumbnails::ImageThumbnailCache::ProviderName, &ThumbnailerRequests::UnregisterThumbnailProvider, Thumbnails::ImageThumbnailCache::ProviderName);
ThumbnailContext::DefaultContext);
} }
void ImageThumbnailSystemComponent::OnApplicationAboutToStop() void ImageThumbnailSystemComponent::OnApplicationAboutToStop()

@ -13,7 +13,6 @@
#include <AzQtComponents/Components/Widgets/LineEdit.h> #include <AzQtComponents/Components/Widgets/LineEdit.h>
#include <AzQtComponents/Components/Widgets/Text.h> #include <AzQtComponents/Components/Widgets/Text.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h> #include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <AzToolsFramework/Thumbnails/ThumbnailWidget.h> #include <AzToolsFramework/Thumbnails/ThumbnailWidget.h>
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h> #include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
@ -105,9 +104,7 @@ namespace AtomToolsFramework
AzToolsFramework::Thumbnailer::ThumbnailWidget* thumbnail = new AzToolsFramework::Thumbnailer::ThumbnailWidget(itemWidget); AzToolsFramework::Thumbnailer::ThumbnailWidget* thumbnail = new AzToolsFramework::Thumbnailer::ThumbnailWidget(itemWidget);
thumbnail->setFixedSize(m_tileSize); thumbnail->setFixedSize(m_tileSize);
thumbnail->SetThumbnailKey( thumbnail->SetThumbnailKey(MAKE_TKEY(AzToolsFramework::AssetBrowser::ProductThumbnailKey, selectableAsset.m_assetId));
MAKE_TKEY(AzToolsFramework::AssetBrowser::ProductThumbnailKey, selectableAsset.m_assetId),
AzToolsFramework::Thumbnailer::ThumbnailContext::DefaultContext);
thumbnail->updateGeometry(); thumbnail->updateGeometry();
itemWidget->layout()->addWidget(thumbnail); itemWidget->layout()->addWidget(thumbnail);

@ -14,7 +14,6 @@
#include <AzFramework/API/ApplicationAPI.h> #include <AzFramework/API/ApplicationAPI.h>
#include <AzToolsFramework/API/EditorCameraBus.h> #include <AzToolsFramework/API/EditorCameraBus.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h> #include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <EditorCommonFeaturesSystemComponent.h> #include <EditorCommonFeaturesSystemComponent.h>
#include <SharedPreview/SharedThumbnail.h> #include <SharedPreview/SharedThumbnail.h>
#include <SkinnedMesh/SkinnedMeshDebugDisplay.h> #include <SkinnedMesh/SkinnedMeshDebugDisplay.h>
@ -217,8 +216,8 @@ namespace AZ
using namespace AzToolsFramework::Thumbnailer; using namespace AzToolsFramework::Thumbnailer;
using namespace LyIntegration; using namespace LyIntegration;
ThumbnailerRequestsBus::Broadcast( ThumbnailerRequestBus::Broadcast(
&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(SharedThumbnailCache), ThumbnailContext::DefaultContext); &ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(SharedThumbnailCache));
if (!m_thumbnailRenderer) if (!m_thumbnailRenderer)
{ {
@ -236,9 +235,7 @@ namespace AZ
using namespace AzToolsFramework::Thumbnailer; using namespace AzToolsFramework::Thumbnailer;
using namespace LyIntegration; using namespace LyIntegration;
ThumbnailerRequestsBus::Broadcast( ThumbnailerRequestBus::Broadcast(&ThumbnailerRequests::UnregisterThumbnailProvider, SharedThumbnailCache::ProviderName);
&ThumbnailerRequests::UnregisterThumbnailProvider, SharedThumbnailCache::ProviderName,
ThumbnailContext::DefaultContext);
m_thumbnailRenderer.reset(); m_thumbnailRenderer.reset();
m_previewerFactory.reset(); m_previewerFactory.reset();

@ -11,7 +11,6 @@
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h> #include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h> #include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
#include <AzToolsFramework/Thumbnails/Thumbnail.h> #include <AzToolsFramework/Thumbnails/Thumbnail.h>
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <SharedPreview/SharedPreviewUtils.h> #include <SharedPreview/SharedPreviewUtils.h>
#include <SharedPreview/SharedPreviewer.h> #include <SharedPreview/SharedPreviewer.h>
@ -51,7 +50,7 @@ namespace AZ
using namespace AzToolsFramework::Thumbnailer; using namespace AzToolsFramework::Thumbnailer;
auto thumbnailKey = entry->GetThumbnailKey(); auto thumbnailKey = entry->GetThumbnailKey();
m_ui->m_previewWidget->SetThumbnailKey(thumbnailKey, ThumbnailContext::DefaultContext); m_ui->m_previewWidget->SetThumbnailKey(thumbnailKey);
m_fileInfo = QString::fromUtf8(entry->GetName().c_str()); m_fileInfo = QString::fromUtf8(entry->GetName().c_str());
UpdateFileInfo(); UpdateFileInfo();
} }

@ -35,8 +35,15 @@ namespace AZ
m_state = State::Failed; m_state = State::Failed;
} }
SharedThumbnail::~SharedThumbnail()
{
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler::BusDisconnect();
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
}
void SharedThumbnail::LoadThread() void SharedThumbnail::LoadThread()
{ {
m_state = State::Loading;
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::QueueEvent( AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::QueueEvent(
m_assetInfo.m_assetType, &AzToolsFramework::Thumbnailer::ThumbnailerRendererRequests::RenderThumbnail, m_key, m_assetInfo.m_assetType, &AzToolsFramework::Thumbnailer::ThumbnailerRendererRequests::RenderThumbnail, m_key,
SharedThumbnailSize); SharedThumbnailSize);
@ -45,15 +52,10 @@ namespace AZ
m_renderWait.acquire(); m_renderWait.acquire();
} }
SharedThumbnail::~SharedThumbnail()
{
AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Handler::BusDisconnect();
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
}
void SharedThumbnail::ThumbnailRendered(const QPixmap& thumbnailImage) void SharedThumbnail::ThumbnailRendered(const QPixmap& thumbnailImage)
{ {
m_pixmap = thumbnailImage; m_pixmap = thumbnailImage;
m_state = State::Ready;
m_renderWait.release(); m_renderWait.release();
} }

Loading…
Cancel
Save