Files
o3de/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp
T
Guthrie Adams 3977edb21e Atom Tools: Removing unnecessary modules, components, and dead code from SMC
Looking toward creating a bare bones template for a standalone application, simplifying and removing any boilerplate wherever possible. SMC followed patterns established by material editor, subdividing everything into multiple modules, which required manually adding static modules, implementing system components with little to no functionality, and a bunch of unnecessary files for such a simple application. This change deletes unnecessary boilerplate code, moving everything into a single module, making the application class responsible for reflecting classes and buses.

Signed-off-by: Guthrie Adams <guthadam@amazon.com>
2022-01-20 16:05:08 -06:00

242 lines
11 KiB
C++

/*
* 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 <AssetDatabase/AssetDatabaseConnection.h>
#include <Atom/RPI.Edit/Common/AssetUtils.h>
#include <Atom/RPI.Edit/Common/JsonUtils.h>
#include <Atom/RPI.Public/Material/Material.h>
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
#include <AtomToolsFramework/Document/AtomToolsDocumentSystemRequestBus.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzToolsFramework/UI/UICore/QWidgetSavedState.h>
#include <Document/ShaderManagementConsoleDocument.h>
#include <Document/ShaderManagementConsoleDocumentRequestBus.h>
#include <ShaderManagementConsoleApplication.h>
#include <ShaderManagementConsoleRequestBus.h>
#include <ShaderManagementConsole_Traits_Platform.h>
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
AZ_POP_DISABLE_WARNING
void InitShaderManagementConsoleResources()
{
// Must register qt resources from other modules
Q_INIT_RESOURCE(ShaderManagementConsole);
Q_INIT_RESOURCE(InspectorWidget);
Q_INIT_RESOURCE(AtomToolsAssetBrowser);
}
namespace ShaderManagementConsole
{
ShaderManagementConsoleApplication::ShaderManagementConsoleApplication(int* argc, char*** argv)
: Base(argc, argv)
{
InitShaderManagementConsoleResources();
QApplication::setApplicationName("O3DE Shader Management Console");
// The settings registry has been created at this point, so add the CMake target
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization(
*AZ::SettingsRegistry::Get(), GetBuildTargetName());
ShaderManagementConsoleRequestBus::Handler::BusConnect();
AzToolsFramework::EditorWindowRequestBus::Handler::BusConnect();
AtomToolsFramework::AtomToolsMainWindowFactoryRequestBus::Handler::BusConnect();
}
ShaderManagementConsoleApplication::~ShaderManagementConsoleApplication()
{
ShaderManagementConsoleRequestBus::Handler::BusDisconnect();
AzToolsFramework::EditorWindowRequestBus::Handler::BusDisconnect();
AtomToolsFramework::AtomToolsMainWindowFactoryRequestBus::Handler::BusDisconnect();
m_window.reset();
}
void ShaderManagementConsoleApplication::Reflect(AZ::ReflectContext* context)
{
Base::Reflect(context);
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->EBus<ShaderManagementConsoleRequestBus>("ShaderManagementConsoleRequestBus")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
->Attribute(AZ::Script::Attributes::Category, "Editor")
->Attribute(AZ::Script::Attributes::Module, "shadermanagementconsole")
->Event("GetSourceAssetInfo", &ShaderManagementConsoleRequestBus::Events::GetSourceAssetInfo)
->Event("FindMaterialAssetsUsingShader", &ShaderManagementConsoleRequestBus::Events::FindMaterialAssetsUsingShader )
->Event("GetMaterialInstanceShaderItems", &ShaderManagementConsoleRequestBus::Events::GetMaterialInstanceShaderItems)
;
behaviorContext->EBus<ShaderManagementConsoleDocumentRequestBus>("ShaderManagementConsoleDocumentRequestBus")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Category, "Editor")
->Attribute(AZ::Script::Attributes::Module, "shadermanagementconsole")
->Event("GetShaderOptionCount", &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderOptionCount)
->Event("GetShaderOptionDescriptor", &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderOptionDescriptor)
->Event("GetShaderVariantCount", &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderVariantCount)
->Event("GetShaderVariantInfo", &ShaderManagementConsoleDocumentRequestBus::Events::GetShaderVariantInfo)
;
}
}
const char* ShaderManagementConsoleApplication::GetCurrentConfigurationName() const
{
#if defined(_RELEASE)
return "ReleaseShaderManagementConsole";
#elif defined(_DEBUG)
return "DebugShaderManagementConsole";
#else
return "ProfileShaderManagementConsole";
#endif
}
void ShaderManagementConsoleApplication::StartCommon(AZ::Entity* systemEntity)
{
Base::StartCommon(systemEntity);
AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Broadcast(
&AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Handler::RegisterDocumentType,
[]() { return aznew ShaderManagementConsoleDocument(); });
}
AZStd::string ShaderManagementConsoleApplication::GetBuildTargetName() const
{
#if !defined(LY_CMAKE_TARGET)
#error "LY_CMAKE_TARGET must be defined in order to add this source file to a CMake executable target"
#endif
//! Returns the build system target name of "ShaderManagementConsole"
return AZStd::string_view{ LY_CMAKE_TARGET };
}
AZStd::vector<AZStd::string> ShaderManagementConsoleApplication::GetCriticalAssetFilters() const
{
return AZStd::vector<AZStd::string>({ "passes/", "config/" });
}
QWidget* ShaderManagementConsoleApplication::GetAppMainWindow()
{
return m_window.get();
}
void ShaderManagementConsoleApplication::CreateMainWindow()
{
m_assetBrowserInteractions.reset(aznew ShaderManagementConsoleBrowserInteractions);
m_window.reset(aznew ShaderManagementConsoleWindow);
m_window->show();
}
void ShaderManagementConsoleApplication::DestroyMainWindow()
{
m_window.reset();
}
AZ::Data::AssetInfo ShaderManagementConsoleApplication::GetSourceAssetInfo(const AZStd::string& sourceAssetFileName)
{
bool result = false;
AZ::Data::AssetInfo assetInfo;
AZStd::string watchFolder;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
result, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourcePath, sourceAssetFileName.c_str(), assetInfo,
watchFolder);
AZ_Error(nullptr, result, "Failed to get the asset info for the file: %s.", sourceAssetFileName.c_str());
return assetInfo;
}
AZStd::vector<AZ::Data::AssetId> ShaderManagementConsoleApplication::FindMaterialAssetsUsingShader(const AZStd::string& shaderFilePath)
{
// Collect the material types referencing the shader
AZStd::vector<AZStd::string> materialTypeSources;
AzToolsFramework::AssetDatabase::AssetDatabaseConnection assetDatabaseConnection;
assetDatabaseConnection.OpenDatabase();
assetDatabaseConnection.QuerySourceDependencyByDependsOnSource(
shaderFilePath.c_str(), nullptr, AzToolsFramework::AssetDatabase::SourceFileDependencyEntry::DEP_Any,
[&](AzToolsFramework::AssetDatabase::SourceFileDependencyEntry& sourceFileDependencyEntry)
{
AZStd::string assetExtension;
if (AzFramework::StringFunc::Path::GetExtension(sourceFileDependencyEntry.m_source.c_str(), assetExtension, false))
{
if (assetExtension == "materialtype")
{
materialTypeSources.push_back(sourceFileDependencyEntry.m_source);
}
}
return true;
});
AzToolsFramework::AssetDatabase::ProductDatabaseEntryContainer productDependencies;
for (const auto& materialTypeSource : materialTypeSources)
{
bool result = false;
AZ::Data::AssetInfo materialTypeSourceAssetInfo;
AZStd::string watchFolder;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
result, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourcePath, materialTypeSource.c_str(),
materialTypeSourceAssetInfo, watchFolder);
assetDatabaseConnection.QueryDirectReverseProductDependenciesBySourceGuidSubId(
materialTypeSourceAssetInfo.m_assetId.m_guid, materialTypeSourceAssetInfo.m_assetId.m_subId,
[&](AzToolsFramework::AssetDatabase::ProductDatabaseEntry& entry)
{
AZStd::string assetExtension;
if (AzFramework::StringFunc::Path::GetExtension(entry.m_productName.c_str(), assetExtension, false))
{
if (assetExtension == "azmaterial")
{
productDependencies.push_back(entry);
}
}
return true;
});
}
AZStd::vector<AZ::Data::AssetId> results;
results.reserve(productDependencies.size());
for (auto product : productDependencies)
{
assetDatabaseConnection.QueryCombinedByProductID(
product.m_productID,
[&](AzToolsFramework::AssetDatabase::CombinedDatabaseEntry& combined)
{
results.push_back({ combined.m_sourceGuid, combined.m_subID });
return false;
},
nullptr);
}
return results;
}
AZStd::vector<AZ::RPI::ShaderCollection::Item> ShaderManagementConsoleApplication::GetMaterialInstanceShaderItems(
const AZ::Data::AssetId& assetId)
{
auto materialAsset = AZ::RPI::AssetUtils::LoadAssetById<AZ::RPI::MaterialAsset>(assetId, AZ::RPI::AssetUtils::TraceLevel::Error);
auto materialInstance = AZ::RPI::Material::Create(materialAsset);
AZ_Error(
nullptr, materialAsset, "Failed to get a material instance from product asset id: %s",
assetId.ToString<AZStd::string>().c_str());
if (materialInstance != nullptr)
{
return AZStd::vector<AZ::RPI::ShaderCollection::Item>(
materialInstance->GetShaderCollection().begin(), materialInstance->GetShaderCollection().end());
}
return AZStd::vector<AZ::RPI::ShaderCollection::Item>();
}
} // namespace ShaderManagementConsole