Integrating up through commit 90f050496

This commit is contained in:
alexpete
2021-04-07 14:03:29 -07:00
parent 8f2ed080a9
commit c2cbd430fe
2694 changed files with 285622 additions and 176874 deletions
@@ -28,7 +28,7 @@
#include <AzToolsFramework/Thumbnails/ThumbnailContext.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/FolderThumbnail.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/SourceThumbnail.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/AssetBrowserProductThumbnail.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
#include <AzToolsFramework/AssetBrowser/AssetPicker/AssetPickerDialog.h>
#include <AzToolsFramework/Slice/SliceUtilities.h>
@@ -17,7 +17,7 @@
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/AssetBrowser/Entries/ProductAssetBrowserEntry.h>
#include <AzToolsFramework/AssetDatabase/AssetDatabaseConnection.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/AssetBrowserProductThumbnail.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
#include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntryCache.h>
#include <QVariant>
@@ -120,13 +120,14 @@ namespace AzToolsFramework
void ProductAssetBrowserEntry::ThumbnailUpdated()
{
// if source is displaying product's thumbnail, then it needs to also listen to its ThumbnailUpdated
if (m_parentAssetEntry)
if (EntryCache* cache = EntryCache::GetInstance())
{
if (EntryCache* cache = EntryCache::GetInstance())
// if source is displaying product's thumbnail, then it needs to also listen to its ThumbnailUpdated
if (m_parentAssetEntry)
{
cache->m_dirtyThumbnailsSet.insert(m_parentAssetEntry);
}
cache->m_dirtyThumbnailsSet.insert(this);
}
}
@@ -207,6 +207,7 @@ namespace AzToolsFramework
auto source = azrtti_cast<SourceAssetBrowserEntry*>(itFile->second);
source->m_sourceId = sourceWithFileIdEntry.second.m_sourceID;
source->m_sourceUuid = sourceWithFileIdEntry.second.m_sourceGuid;
source->PathsUpdated(); // update thumbnailkey to valid uuid
EntryCache::GetInstance()->m_sourceUuidMap[source->m_sourceUuid] = source;
EntryCache::GetInstance()->m_sourceIdMap[source->m_sourceId] = source;
return true;
@@ -170,7 +170,7 @@ namespace AzToolsFramework
SharedThumbnailKey SourceAssetBrowserEntry::CreateThumbnailKey()
{
return MAKE_TKEY(SourceThumbnailKey, m_fullPath.c_str());
return MAKE_TKEY(SourceThumbnailKey, m_sourceUuid);
}
SharedThumbnailKey SourceAssetBrowserEntry::GetSourceControlThumbnailKey() const
@@ -14,7 +14,7 @@
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/AssetBrowserProductThumbnail.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
#include <QPixmap>
namespace AzToolsFramework
@@ -37,6 +37,21 @@ namespace AzToolsFramework
const AZ::Data::AssetType& ProductThumbnailKey::GetAssetType() const { return m_assetType; }
size_t ProductThumbnailKey::GetHash() const
{
return m_assetType.GetHash();
}
bool ProductThumbnailKey::Equals(const ThumbnailKey* other) const
{
if (!ThumbnailKey::Equals(other))
{
return false;
}
// products displayed in Asset Browser have icons based on asset type, so multiple different products with same asset type will have same thumbnail
return m_assetId == azrtti_cast<const ProductThumbnailKey*>(other)->GetAssetId();
}
//////////////////////////////////////////////////////////////////////////
// ProductThumbnail
//////////////////////////////////////////////////////////////////////////
@@ -93,7 +108,7 @@ namespace AzToolsFramework
// ProductThumbnailCache
//////////////////////////////////////////////////////////////////////////
ProductThumbnailCache::ProductThumbnailCache()
: ThumbnailCache<ProductThumbnail, ProductKeyHash, ProductKeyEqual>() {}
: ThumbnailCache<ProductThumbnail>() {}
ProductThumbnailCache::~ProductThumbnailCache() = default;
@@ -39,6 +39,14 @@ namespace AzToolsFramework
return m_isGem;
}
bool FolderThumbnailKey::Equals(const ThumbnailKey* other) const
{
if (!ThumbnailKey::Equals(other))
{
return false;
}
return m_isGem == azrtti_cast<const FolderThumbnailKey*>(other)->IsGem();
}
//////////////////////////////////////////////////////////////////////////
// FolderThumbnail
//////////////////////////////////////////////////////////////////////////
@@ -68,7 +76,7 @@ namespace AzToolsFramework
// FolderThumbnailCache
//////////////////////////////////////////////////////////////////////////
FolderThumbnailCache::FolderThumbnailCache()
: ThumbnailCache<FolderThumbnail, FolderKeyHash, FolderKeyEqual>() {}
: ThumbnailCache<FolderThumbnail>() {}
FolderThumbnailCache::~FolderThumbnailCache() = default;
@@ -33,6 +33,7 @@ namespace AzToolsFramework
FolderThumbnailKey(const char* folderPath, bool isGem);
const AZStd::string& GetFolderPath() const;
bool IsGem() const;
bool Equals(const ThumbnailKey* other) const override;
protected:
//! Absolute folder path
@@ -50,36 +51,10 @@ namespace AzToolsFramework
void LoadThread() override;
};
namespace
{
class FolderKeyHash
{
public:
size_t operator() (const SharedThumbnailKey& /*val*/) const
{
return 0;
}
};
class FolderKeyEqual
{
public:
bool operator()(const SharedThumbnailKey& val1, const SharedThumbnailKey& val2) const
{
auto folderThumbnailKey1 = azrtti_cast<const FolderThumbnailKey*>(val1.data());
auto folderThumbnailKey2 = azrtti_cast<const FolderThumbnailKey*>(val2.data());
if (!folderThumbnailKey1 || !folderThumbnailKey2)
{
return false;
}
// There are only two thumbnails in this cache, one for gem icon and one for folder icon
return folderThumbnailKey1->IsGem() == folderThumbnailKey2->IsGem();
}
};
}
//! FolderAssetBrowserEntry thumbnails
class FolderThumbnailCache
: public ThumbnailCache<FolderThumbnail, FolderKeyHash, FolderKeyEqual>
: public ThumbnailCache<FolderThumbnail>
{
public:
FolderThumbnailCache();
@@ -0,0 +1,128 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <AzCore/Asset/AssetTypeInfoBus.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
#include <QPixmap>
namespace AzToolsFramework
{
namespace AssetBrowser
{
//////////////////////////////////////////////////////////////////////////
// ProductThumbnailKey
//////////////////////////////////////////////////////////////////////////
ProductThumbnailKey::ProductThumbnailKey(const AZ::Data::AssetId& assetId)
: ThumbnailKey()
, m_assetId(assetId)
{
AZ::Data::AssetInfo info;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(info, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, m_assetId);
m_assetType = info.m_assetType;
}
const AZ::Data::AssetId& ProductThumbnailKey::GetAssetId() const { return m_assetId; }
const AZ::Data::AssetType& ProductThumbnailKey::GetAssetType() const { return m_assetType; }
size_t ProductThumbnailKey::GetHash() const
{
return m_assetType.GetHash();
}
bool ProductThumbnailKey::Equals(const ThumbnailKey* other) const
{
if (!ThumbnailKey::Equals(other))
{
return false;
}
// products displayed in Asset Browser have icons based on asset type, so multiple different products with same asset type will have same thumbnail
return m_assetId == azrtti_cast<const ProductThumbnailKey*>(other)->GetAssetId();
}
//////////////////////////////////////////////////////////////////////////
// ProductThumbnail
//////////////////////////////////////////////////////////////////////////
static const char* DEFAULT_PRODUCT_ICON_PATH = "Editor/Icons/AssetBrowser/DefaultProduct_16.svg";
ProductThumbnail::ProductThumbnail(Thumbnailer::SharedThumbnailKey key, int thumbnailSize)
: Thumbnail(key, thumbnailSize)
{}
void ProductThumbnail::LoadThread()
{
auto productKey = azrtti_cast<const ProductThumbnailKey*>(m_key.data());
AZ_Assert(productKey, "Incorrect key type, excpected ProductThumbnailKey");
QString iconPath;
AZ::AssetTypeInfoBus::EventResult(iconPath, productKey->GetAssetType(), &AZ::AssetTypeInfo::GetBrowserIcon);
if (!iconPath.isEmpty())
{
// is it an embedded resource or absolute path?
bool isUsablePath = (iconPath.startsWith(":") || (!AzFramework::StringFunc::Path::IsRelative(iconPath.toUtf8().constData())));
if (!isUsablePath)
{
// getting here means it needs resolution. Can we find the real path of the file? This also searches in gems for sources.
bool foundIt = false;
AZStd::string watchFolder;
AZ::Data::AssetInfo assetInfo;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(foundIt, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, iconPath.toUtf8().constData(), assetInfo, watchFolder);
if (foundIt)
{
// the absolute path is join(watchfolder, relativepath); // since its relative to the watch folder.
AZStd::string finalPath;
AzFramework::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), finalPath);
iconPath = QString::fromUtf8(finalPath.c_str());
}
}
}
else
{
// no pixmap specified - use default.
iconPath = QString::fromUtf8(DEFAULT_PRODUCT_ICON_PATH);
}
m_icon = QIcon(iconPath);
if (m_icon.isNull())
{
m_state = State::Failed;
}
}
//////////////////////////////////////////////////////////////////////////
// ProductThumbnailCache
//////////////////////////////////////////////////////////////////////////
ProductThumbnailCache::ProductThumbnailCache()
: ThumbnailCache<ProductThumbnail>() {}
ProductThumbnailCache::~ProductThumbnailCache() = default;
const char* ProductThumbnailCache::GetProviderName() const
{
return ProviderName;
}
bool ProductThumbnailCache::IsSupportedThumbnail(Thumbnailer::SharedThumbnailKey key) const
{
return azrtti_istypeof<const ProductThumbnailKey*>(key.data());
}
} // namespace AssetBrowser
} // namespace AzToolsFramework
#include "AssetBrowser/Thumbnails/moc_ProductThumbnail.cpp"
@@ -31,6 +31,8 @@ namespace AzToolsFramework
explicit ProductThumbnailKey(const AZ::Data::AssetId& assetId);
const AZ::Data::AssetId& GetAssetId() const;
const AZ::Data::AssetType& GetAssetType() const;
size_t GetHash() const override;
bool Equals(const ThumbnailKey* other) const override;
protected:
AZ::Data::AssetId m_assetId;
@@ -48,42 +50,9 @@ namespace AzToolsFramework
void LoadThread() override;
};
namespace
{
class ProductKeyHash
{
public:
size_t operator() (const Thumbnailer::SharedThumbnailKey& val) const
{
auto productThumbnailKey = azrtti_cast<const ProductThumbnailKey*>(val.data());
if (!productThumbnailKey)
{
return 0;
}
return productThumbnailKey->GetAssetType().GetHash();
}
};
class ProductKeyEqual
{
public:
bool operator()(const Thumbnailer::SharedThumbnailKey& val1, const Thumbnailer::SharedThumbnailKey& val2) const
{
auto productThumbnailKey1 = azrtti_cast<const ProductThumbnailKey*>(val1.data());
auto productThumbnailKey2 = azrtti_cast<const ProductThumbnailKey*>(val2.data());
if (!productThumbnailKey1 || !productThumbnailKey2)
{
return false;
}
// products displayed in Asset Browser have icons based on asset type, so multiple different products with same asset type will have same thumbnail
return productThumbnailKey1->GetAssetType() == productThumbnailKey2->GetAssetType();
}
};
}
//! ProductAssetBrowserEntry thumbnails
class ProductThumbnailCache
: public Thumbnailer::ThumbnailCache<ProductThumbnail, ProductKeyHash, ProductKeyEqual>
: public Thumbnailer::ThumbnailCache<ProductThumbnail>
{
public:
ProductThumbnailCache();
@@ -11,6 +11,7 @@
*/
#include <AzCore/EBus/Results.h>
#include <AzCore/std/string/string.h>
#include <AzCore/std/containers/vector.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
@@ -26,21 +27,29 @@ namespace AzToolsFramework
//////////////////////////////////////////////////////////////////////////
// SourceThumbnailKey
//////////////////////////////////////////////////////////////////////////
SourceThumbnailKey::SourceThumbnailKey(const char* fileName)
SourceThumbnailKey::SourceThumbnailKey(const AZ::Uuid& sourceUuid)
: ThumbnailKey()
, m_fileName(fileName)
, m_sourceUuid(sourceUuid)
{
AzFramework::StringFunc::Path::Split(fileName, nullptr, nullptr, nullptr, &m_extension);
}
const AZStd::string& SourceThumbnailKey::GetFileName() const
const AZ::Uuid& SourceThumbnailKey::GetSourceUuid() const
{
return m_fileName;
return m_sourceUuid;
}
const AZStd::string& SourceThumbnailKey::GetExtension() const
size_t SourceThumbnailKey::GetHash() const
{
return m_extension;
return m_sourceUuid.GetHash();
}
bool SourceThumbnailKey::Equals(const ThumbnailKey* other) const
{
if (!ThumbnailKey::Equals(other))
{
return false;
}
return m_sourceUuid == azrtti_cast<const SourceThumbnailKey*>(other)->GetSourceUuid();
}
//////////////////////////////////////////////////////////////////////////
@@ -59,48 +68,54 @@ namespace AzToolsFramework
auto sourceKey = azrtti_cast<const SourceThumbnailKey*>(m_key.data());
AZ_Assert(sourceKey, "Incorrect key type, excpected SourceThumbnailKey");
// note that there might not actually be a UUID for this yet. So we don't look it up.
AZ::EBusAggregateResults<SourceFileDetails> results;
AssetBrowserInteractionNotificationBus::BroadcastResult(results, &AssetBrowserInteractionNotificationBus::Events::GetSourceFileDetails, sourceKey->GetFileName().c_str());
// there could be multiple listeners to this, return the first one with actual image path
auto it = AZStd::find_if(results.values.begin(), results.values.end(), [](const SourceFileDetails& details) { return !details.m_sourceThumbnailPath.empty(); });
bool foundIt = false;
AZStd::string watchFolder;
AZ::Data::AssetInfo assetInfo;
AssetSystemRequestBus::BroadcastResult(foundIt, &AssetSystemRequestBus::Events::GetSourceInfoBySourceUUID, sourceKey->GetSourceUuid(), assetInfo, watchFolder);
QString iconPathToUse;
if (it != results.values.end())
if (foundIt)
{
const char* resultPath = it->m_sourceThumbnailPath.c_str();
// its an ordered bus, though, so first one wins.
// we have to massage this though. there are three valid possibilities
// 1. its a relative path to source, in which case we have to find the full path
// 2. its an absolute path, in which case we use it as-is
// 3. its an embedded resource, in which case we use it as is.
// note that there might not actually be a UUID for this yet. So we don't look it up.
AZ::EBusAggregateResults<SourceFileDetails> results;
AssetBrowserInteractionNotificationBus::BroadcastResult(results, &AssetBrowserInteractionNotificationBus::Events::GetSourceFileDetails, assetInfo.m_relativePath.c_str());
// there could be multiple listeners to this, return the first one with actual image path
auto it = AZStd::find_if(results.values.begin(), results.values.end(), [](const SourceFileDetails& details) { return !details.m_sourceThumbnailPath.empty(); });
// is it an embedded resource or absolute path?
if ((resultPath[0] == ':')||(!AzFramework::StringFunc::Path::IsRelative(resultPath)))
if (it != results.values.end())
{
iconPathToUse = QString::fromUtf8(resultPath);
}
else
{
// getting here means its a relative path. Can we find the real path of the file? This also searches in gems for sources.
bool foundIt = false;
AZStd::string watchFolder;
AZ::Data::AssetInfo assetInfo;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(foundIt, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, resultPath, assetInfo, watchFolder);
const char* resultPath = it->m_sourceThumbnailPath.c_str();
// its an ordered bus, though, so first one wins.
// we have to massage this though. there are three valid possibilities
// 1. its a relative path to source, in which case we have to find the full path
// 2. its an absolute path, in which case we use it as-is
// 3. its an embedded resource, in which case we use it as is.
AZ_WarningOnce("Asset Browser", foundIt, "Unable to find source icon file in any source folders or gems: %s\n", resultPath);
if (foundIt)
// is it an embedded resource or absolute path?
if ((resultPath[0] == ':') || (!AzFramework::StringFunc::Path::IsRelative(resultPath)))
{
// the absolute path is join(watchfolder, relativepath); // since its relative to the watch folder.
AZStd::string finalPath;
AzFramework::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), finalPath);
iconPathToUse = QString::fromUtf8(finalPath.c_str());
iconPathToUse = QString::fromUtf8(resultPath);
}
else
{
// getting here means its a relative path. Can we find the real path of the file? This also searches in gems for sources.
foundIt = false;
AssetSystemRequestBus::BroadcastResult(foundIt, &AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, resultPath, assetInfo, watchFolder);
AZ_WarningOnce("Asset Browser", foundIt, "Unable to find source icon file in any source folders or gems: %s\n", resultPath);
if (foundIt)
{
// the absolute path is join(watchfolder, relativepath); // since its relative to the watch folder.
AZStd::string finalPath;
AzFramework::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), finalPath);
iconPathToUse = QString::fromUtf8(finalPath.c_str());
}
}
}
}
else
if (iconPathToUse.isEmpty())
{
const char* engineRoot = nullptr;
AzFramework::ApplicationRequests::Bus::BroadcastResult(engineRoot, &AzFramework::ApplicationRequests::GetEngineRoot);
@@ -116,7 +131,7 @@ namespace AzToolsFramework
// SourceThumbnailCache
//////////////////////////////////////////////////////////////////////////
SourceThumbnailCache::SourceThumbnailCache()
: ThumbnailCache<SourceThumbnail, SourceKeyHash, SourceKeyEqual>() {}
: ThumbnailCache<SourceThumbnail>() {}
SourceThumbnailCache::~SourceThumbnailCache() = default;
@@ -12,7 +12,6 @@
#pragma once
#if !defined(Q_MOC_RUN)
#include <AzCore/std/string/string.h>
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
#include <QMutex>
#endif
@@ -31,15 +30,13 @@ namespace AzToolsFramework
public:
AZ_RTTI(SourceThumbnailKey, "{4AF3F33A-4B16-491D-93A5-0CC96DC59814}", ThumbnailKey);
explicit SourceThumbnailKey(const char* fileName);
const AZStd::string& GetFileName() const;
const AZStd::string& GetExtension() const;
explicit SourceThumbnailKey(const AZ::Uuid& sourceUuid);
const AZ::Uuid& GetSourceUuid() const;
size_t GetHash() const override;
bool Equals(const ThumbnailKey* other) const override;
protected:
//! absolute path
AZStd::string m_fileName;
//! file extension
AZStd::string m_extension;
AZ::Uuid m_sourceUuid;
};
class SourceThumbnail
@@ -56,41 +53,9 @@ namespace AzToolsFramework
static QMutex m_mutex;
};
namespace
{
class SourceKeyHash
{
public:
size_t operator() (const SharedThumbnailKey& val) const
{
auto sourceThumbnailKey = azrtti_cast<const SourceThumbnailKey*>(val.data());
if (!sourceThumbnailKey)
{
return 0;
}
return AZStd::hash<AZStd::string>()(sourceThumbnailKey->GetFileName());
}
};
class SourceKeyEqual
{
public:
bool operator()(const SharedThumbnailKey& val1, const SharedThumbnailKey& val2) const
{
auto sourceThumbnailKey1 = azrtti_cast<const SourceThumbnailKey*>(val1.data());
auto sourceThumbnailKey2 = azrtti_cast<const SourceThumbnailKey*>(val2.data());
if (!sourceThumbnailKey1 || !sourceThumbnailKey2)
{
return false;
}
return sourceThumbnailKey1->GetFileName() == sourceThumbnailKey2->GetFileName();
}
};
}
//! SourceAssetBrowserEntry thumbnails
class SourceThumbnailCache
: public ThumbnailCache<SourceThumbnail, SourceKeyHash, SourceKeyEqual>
: public ThumbnailCache<SourceThumbnail>
{
public:
SourceThumbnailCache();