/* * 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 #include #include #include #include #include #include #include namespace TestAssetBuilder { bool failedNetworkConnectionTest = true; AZ::Data::AssetStreamInfo TestDependentAssetCatalog::GetStreamInfoForLoad(const AZ::Data::AssetId& assetId, const AZ::Data::AssetType& type) { if (AZ::AzTypeInfo::Uuid() != type) { AZ_Error("TestDependentAssetCatalog", false, "Invalid asset type %s", assetId.ToString().c_str()); return {}; } AZ::Data::AssetInfo assetInfo; AZStd::string rootFilePath; bool result = false; AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, assetId); if (assetInfo.m_assetId.IsValid()) { AZ::Data::AssetStreamInfo streamInfo; streamInfo.m_dataOffset = 0; streamInfo.m_dataLen = assetInfo.m_sizeBytes; streamInfo.m_isCustomStreamType = true; streamInfo.m_streamName = assetInfo.m_relativePath; return streamInfo; } return {}; } TestAssetBuilderComponent::TestAssetBuilderComponent() { } TestAssetBuilderComponent::~TestAssetBuilderComponent() { } void TestAssetBuilderComponent::Init() { } void TestAssetBuilderComponent::Activate() { AssetBuilderSDK::AssetBuilderDesc builderDescriptor; builderDescriptor.m_name = "Test Asset Builder"; builderDescriptor.m_version = 2; builderDescriptor.m_patterns.emplace_back(AssetBuilderSDK::AssetBuilderPattern("*.source", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); builderDescriptor.m_patterns.emplace_back(AssetBuilderSDK::AssetBuilderPattern("*.dependent", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); builderDescriptor.m_patterns.emplace_back(AssetBuilderSDK::AssetBuilderPattern("*.slicetest", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); builderDescriptor.m_patterns.emplace_back(AssetBuilderSDK::AssetBuilderPattern("*.foldertest", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); builderDescriptor.m_busId = azrtti_typeid(); builderDescriptor.m_createJobFunction = AZStd::bind(&TestAssetBuilderComponent::CreateJobs, this, AZStd::placeholders::_1, AZStd::placeholders::_2); builderDescriptor.m_processJobFunction = AZStd::bind(&TestAssetBuilderComponent::ProcessJob, this, AZStd::placeholders::_1, AZStd::placeholders::_2); bool success = false; AZStd::vector assetSafeFolders; AzToolsFramework::AssetSystemRequestBus::BroadcastResult(success, &AzToolsFramework::AssetSystemRequestBus::Events::GetAssetSafeFolders, assetSafeFolders); failedNetworkConnectionTest = !success || assetSafeFolders.empty(); BusConnect(builderDescriptor.m_busId); m_dependentCatalog.reset(aznew TestDependentAssetCatalog()); AZ::Data::AssetManager::Instance().RegisterCatalog(m_dependentCatalog.get(), AZ::AzTypeInfo::Uuid()); AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBusTraits::RegisterBuilderInformation, builderDescriptor); } void TestAssetBuilderComponent::Deactivate() { BusDisconnect(); AZ::Data::AssetManager::Instance().UnregisterCatalog(m_dependentCatalog.get()); m_dependentCatalog.reset(); } void TestAssetBuilderComponent::Reflect(AZ::ReflectContext* context) { if (AZ::SerializeContext* serialize = azrtti_cast(context)) { serialize->Class() ->Version(0) ->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector({ AssetBuilderSDK::ComponentTags::AssetBuilder })) ; } } void TestAssetBuilderComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { provided.push_back(AZ_CRC("TestAssetBuilderPluginService", 0xa380f578)); } void TestAssetBuilderComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("TestAssetBuilderPluginService", 0xa380f578)); } void TestAssetBuilderComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) { AZ_UNUSED(required); } void TestAssetBuilderComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) { AZ_UNUSED(dependent); } void TestAssetBuilderComponent::CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response) { if (m_isShuttingDown) { response.m_result = AssetBuilderSDK::CreateJobsResultCode::ShuttingDown; return; } if(failedNetworkConnectionTest) { AZ_Assert(false, "GetAssetSafeFolders API failed to respond or responded with an empty list. The network connection to AssetProcessor must be established before builder activation."); return; } AZStd::string ext; AzFramework::StringFunc::Path::GetExtension(request.m_sourceFile.c_str(), ext, false); if (AzFramework::StringFunc::Equal(ext.c_str(), "dependent")) { // Since we're a source file, we also add a job to do the actual compilation (for each enabled platform) for (const AssetBuilderSDK::PlatformInfo& platformInfo : request.m_enabledPlatforms) { AssetBuilderSDK::JobDescriptor descriptor; descriptor.m_jobKey = "Compile Example"; descriptor.SetPlatformIdentifier(platformInfo.m_identifier.c_str()); response.m_createJobOutputs.push_back(descriptor); } response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success; return; } else if (AzFramework::StringFunc::Equal(ext.c_str(), "source")) { for (const AssetBuilderSDK::PlatformInfo& platformInfo : request.m_enabledPlatforms) { AssetBuilderSDK::JobDescriptor descriptor; descriptor.m_jobKey = "Compile Example"; descriptor.SetPlatformIdentifier(platformInfo.m_identifier.c_str()); // add a dependency on the other job: AssetBuilderSDK::SourceFileDependency sourceFile; sourceFile.m_sourceFileDependencyPath = request.m_sourceFile.c_str(); AzFramework::StringFunc::Path::ReplaceExtension(sourceFile.m_sourceFileDependencyPath, "dependent"); descriptor.m_jobDependencyList.push_back({ "Compile Example", platformInfo.m_identifier.c_str(), AssetBuilderSDK::JobDependencyType::Order, sourceFile }); response.m_createJobOutputs.push_back(descriptor); } response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success; return; } else if (AzFramework::StringFunc::Equal(ext.c_str(), "foldertest")) { for (const AssetBuilderSDK::PlatformInfo& platformInfo : request.m_enabledPlatforms) { AssetBuilderSDK::JobDescriptor descriptor; descriptor.m_jobKey = "Compile Example"; descriptor.SetPlatformIdentifier(platformInfo.m_identifier.c_str()); AZStd::string folderName; AzFramework::StringFunc::Path::GetFileName(request.m_sourceFile.c_str(), folderName); AZStd::string baseFolder; AzFramework::StringFunc::Path::GetFolderPath(request.m_sourceFile.c_str(), baseFolder); AZStd::string outFolder; AzFramework::StringFunc::Path::Join(baseFolder.c_str(), folderName.c_str(), outFolder); AZStd::string folderDep{ outFolder + "/*.dependent" }; // add a dependency on the other job: AssetBuilderSDK::SourceFileDependency sourceFile; sourceFile.m_sourceFileDependencyPath = folderDep.c_str(); sourceFile.m_sourceDependencyType = AssetBuilderSDK::SourceFileDependency::SourceFileDependencyType::Wildcards; descriptor.m_jobDependencyList.push_back({ "Compile Example", platformInfo.m_identifier.c_str(), AssetBuilderSDK::JobDependencyType::Order, sourceFile }); response.m_createJobOutputs.push_back(descriptor); } response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success; return; } else if (AzFramework::StringFunc::Equal(ext.c_str(), "slicetest")) { for (const AssetBuilderSDK::PlatformInfo& platformInfo : request.m_enabledPlatforms) { AssetBuilderSDK::JobDescriptor descriptor; descriptor.m_jobKey = "Compile Example"; descriptor.SetPlatformIdentifier(platformInfo.m_identifier.c_str()); // add a dependency on the other job: AssetBuilderSDK::SourceFileDependency sourceFile; sourceFile.m_sourceFileDependencyPath = request.m_sourceFile.c_str(); AzFramework::StringFunc::Path::ReplaceExtension(sourceFile.m_sourceFileDependencyPath, "slice"); descriptor.m_jobDependencyList.push_back({ "Editor Slice Copy", platformInfo.m_identifier.c_str(), AssetBuilderSDK::JobDependencyType::Order, sourceFile }); response.m_createJobOutputs.push_back(descriptor); } response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success; return; } AZ_Assert(false, "Unhandled extension type in TestAssetBuilderWorker."); response.m_result = AssetBuilderSDK::CreateJobsResultCode::Failed; } void TestAssetBuilderComponent::ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response) { AssetBuilderSDK::JobCancelListener jobCancelListener(request.m_jobId); AZ_TracePrintf(AssetBuilderSDK::InfoWindow, "Starting Job.\n"); AZ::IO::FileIOBase* fileIO = AZ::IO::LocalFileIO::GetInstance(); AZStd::string outputData; AZ::IO::HandleType sourcefileHandle; if (!fileIO->Open(request.m_fullPath.c_str(), AZ::IO::OpenMode::ModeRead, sourcefileHandle)) { AZ_Error("AssetBuilder", false, " Unable to open file ( %s ).", request.m_fullPath.c_str()); return; } AZ::u64 sourceSizeBytes = 0; if (fileIO->Size(sourcefileHandle, sourceSizeBytes)) { outputData.resize(sourceSizeBytes); if (!fileIO->Read(sourcefileHandle, outputData.data(), sourceSizeBytes)) { AZ_Error("AssetBuilder", false, " Unable to read file ( %s ).", request.m_fullPath.c_str()); fileIO->Close(sourcefileHandle); return; } } fileIO->Close(sourcefileHandle); AZStd::string fileName = request.m_sourceFile.c_str(); AZStd::string ext; AzFramework::StringFunc::Path::GetExtension(request.m_sourceFile.c_str(), ext, false); AZ::Data::AssetType outputAssetType = AZ::Data::AssetType::CreateNull(); const AZ::u32 DependentSubID = 2222; AZ::u32 outputSubId = 0; if (AzFramework::StringFunc::Equal(ext.c_str(), "source")) { AZStd::string sourcePath{ request.m_fullPath }; AZStd::string dependentFile{ fileName }; AzFramework::StringFunc::Path::ReplaceExtension(dependentFile, "dependentprocessed"); // By default fileIO uses @asset@ alias therefore if we give fileIO a filename // it will try to check in the cache instead of the source folder. AZ::IO::HandleType dependentfileHandle; if (!fileIO->Open(dependentFile.c_str(), AZ::IO::OpenMode::ModeRead, dependentfileHandle)) { AZ_Error("AssetBuilder", false, " Unable to open file in cache ( %s ) while processing source ( %s ) ", dependentFile.c_str(), request.m_sourceFile.c_str()); return; } AZ::u64 dependentsizeBytes = 0; if (fileIO->Size(dependentfileHandle, dependentsizeBytes)) { outputData.resize(outputData.size() + dependentsizeBytes); if (!fileIO->Read(dependentfileHandle, outputData.data() + sourceSizeBytes, dependentsizeBytes)) { AZ_Error("AssetBuilder", false, " Unable to read file data from cache ( %s ).", dependentFile.c_str()); fileIO->Close(dependentfileHandle); return; } } fileIO->Close(dependentfileHandle); // Validating AssetCatalogRequest API's here which operates on assetpath and assetid AZ::Data::AssetId depAssetId; AZ::Data::AssetCatalogRequestBus::BroadcastResult(depAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, dependentFile.c_str(), AZ::Data::s_invalidAssetType, false); if (!depAssetId.IsValid()) { AZ_Error("AssetBuilder", false, "GetAssetIdByPath - Asset id should be valid for this asset ( %s ).", dependentFile.c_str()); return; } AZ::Data::AssetInfo depAssetInfo; AZ::Data::AssetCatalogRequestBus::BroadcastResult(depAssetInfo, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, depAssetId); if (!depAssetInfo.m_assetId.IsValid()) { AZ_Error("AssetBuilder", false, "GetAssetInfoById - Asset info should be valid for this asset ( %s ).", depAssetId.ToString().c_str()); return; } if (depAssetInfo.m_assetType != AZ::AzTypeInfo::Uuid()) { AZ_Error("AssetBuilder", false, "GetAssetInfoById - Asset type not valid for asset ( %s ).", depAssetId.ToString().c_str()); return; } AZ::Data::AssetStreamInfo resultInfo = AZ::Data::AssetManager::Instance().GetLoadStreamInfoForAsset(depAssetId, AZ::AzTypeInfo::Uuid()); if (!resultInfo.IsValid()) { AZ_Error("AssetBuilder", false, "GetLoadStreamInfoForAsset - AssetStreamInfo should be valid for this asset ( %s ).", depAssetId.ToString().c_str()); return; } if (!AzFramework::StringFunc::Path::IsRelative(resultInfo.m_streamName.c_str())) { AZ_Error("AssetBuilder", false, "GetLoadStreamInfoForAsset - Source AssetStreamInfo streamName %s isn't a relative path.", resultInfo.m_streamName.c_str()); return; } bool gotSourceInfo{ false }; AZStd::string watchFolder; AZ::Data::AssetInfo sourcePathAssetInfo; AzToolsFramework::AssetSystemRequestBus::BroadcastResult(gotSourceInfo, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourcePath, sourcePath.c_str(), sourcePathAssetInfo, watchFolder); if (!gotSourceInfo) { AZ_Error("AssetBuilder", false, "GetSourceInfoBySourcePath - Failed to get source info for source ( %s ).", sourcePath.c_str()); return; } if (!sourcePathAssetInfo.m_assetId.IsValid()) { AZ_Error("AssetBuilder", false, "GetSourceInfoBySourcePath - Asset info should be valid for asset at source path ( %s ).", sourcePath.c_str()); return; } if (watchFolder.empty()) { AZ_Error("AssetBuilder", false, "GetSourceInfoBySourcePath - Got empty watch folder for asset at source path ( %s ).", sourcePath.c_str()); return; } if (AzFramework::StringFunc::Path::IsRelative(watchFolder.c_str())) { AZ_Error("AssetBuilder", false, "GetSourceInfoBySourcePath - Got relative path %s for source asset ( %s ).", watchFolder.c_str(), sourcePath.c_str()); return; } bool gotAssetInfo{ false }; AZ::Data::AssetInfo assetSystemDepInfo; AZStd::string depRootFolder; AzToolsFramework::AssetSystemRequestBus::BroadcastResult(gotAssetInfo, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetAssetInfoById, depAssetId, AZ::AzTypeInfo::Uuid(), assetSystemDepInfo, depRootFolder); if (!gotAssetInfo) { AZ_Error("AssetBuilder", false, "GetAssetInfoById - Failed to get info for asset ( %s ).", depAssetId.ToString().c_str()); return; } if (assetSystemDepInfo.m_assetType != AZ::AzTypeInfo::Uuid()) { AZ_Error("AssetBuilder", false, "GetAssetInfoById - Asset type not valid for asset ( %s ).", depAssetId.ToString().c_str()); return; } // Validating AssetCatalogRequest API's here which operates on assetpath and assetid AZ::Data::AssetId assetId; AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, dependentFile.c_str(), AZ::Data::s_invalidAssetType, false); if (!assetId.IsValid()) { AZ_Error("AssetBuilder", false, "GetAssetIdByPath - Asset id should be valid for this asset ( %s ).", dependentFile.c_str()); return; } AZ::Data::AssetInfo assetInfo; AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, assetId); if (!assetInfo.m_assetId.IsValid()) { AZ_Error("AssetBuilder", false, "GetAssetInfoById - Asset info should be valid for this asset ( %s ).", assetId.ToString().c_str()); return; } if (!AzFramework::StringFunc::Path::IsRelative(assetInfo.m_relativePath.c_str())) { AZ_Error("AssetBuilder", false, "GetAssetInfoById - assetInfo m_relativePath %s isn't a relative path.", assetInfo.m_relativePath.c_str()); return; } if (assetId.m_subId != DependentSubID) { AZ_Error("AssetBuilder", false, "GetAssetInfoById - Asset Info m_subId for %s should be %d.", assetId.ToString().c_str(), DependentSubID); return; } if (assetInfo.m_assetId.m_subId != assetId.m_subId) { AZ_Error("AssetBuilder", false, "GetAssetInfoById - Asset Info m_subId for %s should be %d.", assetInfo.m_relativePath.c_str(), assetId.m_subId); return; } AZStd::string assetpath; AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetpath, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetPathById, assetId); if (assetpath.empty()) { AZ_Error("AssetBuilder", false, "Asset path should not be empty for this assetid ( %s ) ( %s )", assetId.ToString().c_str(), dependentFile.c_str()); return; } if (!AzFramework::StringFunc::Path::IsRelative(assetpath.c_str())) { AZ_Error("AssetBuilder", false, "GetAssetPathById - assetInfo m_relativePath %s isn't a relative path.", assetInfo.m_relativePath.c_str()); return; } // Validate that we get the products for this asset bool result = false; AZStd::vector productsInfo; AzToolsFramework::AssetSystemRequestBus::BroadcastResult(result, &AzToolsFramework::AssetSystemRequestBus::Events::GetAssetsProducedBySourceUUID, assetId.m_guid, productsInfo); if (productsInfo.size() == 0) { AZ_Error("AssetBuilder", false, "GetAssetsProducedBySourceUUID - list of products can't be empty. Assetid ( %s ) ( %s )", assetId.ToString().c_str(), fileName.c_str()); return; } AzFramework::StringFunc::Path::ReplaceExtension(fileName, "sourceprocessed"); } else if (AzFramework::StringFunc::Equal(ext.c_str(), "dependent")) { AzFramework::StringFunc::Path::ReplaceExtension(fileName, "dependentprocessed"); outputAssetType = AZ::AzTypeInfo::Uuid(); outputSubId = DependentSubID; } else if (AzFramework::StringFunc::Equal(ext.c_str(), "foldertest")) { AzFramework::StringFunc::Path::ReplaceExtension(fileName, "foldertestprocessed"); } else if (AzFramework::StringFunc::Equal(ext.c_str(), "slicetest")) { AzFramework::StringFunc::Path::ReplaceExtension(fileName, "slice"); AZStd::string sourcePath{ request.m_fullPath }; // Sourcepath - full path to source slice AzFramework::StringFunc::Path::ReplaceExtension(sourcePath, "slice"); AzFramework::StringFunc::Path::Normalize(sourcePath); // Verify copied slice in cache AZ::IO::HandleType dependentfileHandle; if (!fileIO->Open(fileName.c_str(), AZ::IO::OpenMode::ModeRead, dependentfileHandle)) { AZ_Error("AssetBuilder", false, " Unable to open file in cache ( %s ) while processing source ( %s ) ", fileName.c_str(), request.m_sourceFile.c_str()); return; } AZ::u64 dependentsizeBytes = 0; if (fileIO->Size(dependentfileHandle, dependentsizeBytes)) { outputData.resize(outputData.size() + dependentsizeBytes); if (!fileIO->Read(dependentfileHandle, outputData.data() + sourceSizeBytes, dependentsizeBytes)) { AZ_Error("AssetBuilder", false, " Unable to read file data from cache ( %s ).", fileName.c_str()); fileIO->Close(dependentfileHandle); return; } } fileIO->Close(dependentfileHandle); AZ::Data::AssetId depAssetId; AZ::Data::AssetCatalogRequestBus::BroadcastResult(depAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, fileName.c_str(), AZ::Data::s_invalidAssetType, false); if (!depAssetId.IsValid()) { AZ_Error("AssetBuilder", false, "GetAssetIdByPath - Asset id should be valid for this asset ( %s ).", fileName.c_str()); return; } AZ::Data::AssetInfo depAssetInfo; AZ::Data::AssetCatalogRequestBus::BroadcastResult(depAssetInfo, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, depAssetId); if (!depAssetInfo.m_assetId.IsValid()) { AZ_Error("AssetBuilder", false, "GetAssetInfoById - Asset info should be valid for this asset ( %s ).", depAssetId.ToString().c_str()); return; } if (depAssetInfo.m_assetId.m_subId != depAssetId.m_subId) { AZ_Error("AssetBuilder", false, "GetAssetInfoById - Asset Info m_subId for %s shoudl be %d.", depAssetId.ToString().c_str(), depAssetId.m_subId); return; } AZ::Data::AssetStreamInfo resultInfo = AZ::Data::AssetManager::Instance().GetLoadStreamInfoForAsset(depAssetId, depAssetInfo.m_assetType); if (!resultInfo.IsValid()) { AZ_Error("AssetBuilder", false, "GetLoadStreamInfoForAsset - AssetStreamInfo should be valid for this asset ( %s ).", depAssetId.ToString().c_str()); return; } if(AzFramework::StringFunc::Path::IsRelative(resultInfo.m_streamName.c_str())) { AZ_Error("AssetBuilder", false, "GetLoadStreamInfoForAsset - Source AssetStreamInfo streamName %s is relative but should be absolute.", resultInfo.m_streamName.c_str()); return; } if (resultInfo.m_streamName != sourcePath) { AZ_Error("AssetBuilder", false, "GetLoadStreamInfoForAsset - AssetStreamInfo streamName %s isn't expected path %s.", resultInfo.m_streamName.c_str(), sourcePath.c_str()); return; } AZStd::string relativePath; bool pathResult{ false }; AzToolsFramework::AssetSystemRequestBus::BroadcastResult(pathResult, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetRelativeProductPathFromFullSourceOrProductPath, sourcePath, relativePath); if (!pathResult) { AZ_Error("AssetBuilder", false, "GetRelativeProductPathFromFullSourceOrProductPath - Couldn't get relative product path for ( %s ).", sourcePath.c_str()); return; } if (relativePath != fileName) { AZ_Error("AssetBuilder", false, "GetRelativeProductPathFromFullSourceOrProductPath - relativePath and fileName didn't match for ( %s ).", sourcePath.c_str()); return; } AZ::Data::AssetId pathAssetId; AZ::Data::AssetCatalogRequestBus::BroadcastResult(pathAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, fileName.c_str(), AZ::Data::s_invalidAssetType, false); if (!pathAssetId.IsValid()) { AZ_Error("AssetBuilder", false, "GetAssetIdByPath - Asset id should be valid for this asset ( %s ).", fileName.c_str()); return; } bool gotAssetSystemInfoByIdFromProduct{ false }; AZStd::string sourcePathFromProduct; AZ::Data::AssetInfo sliceSourceInfo; AzToolsFramework::AssetSystemRequestBus::BroadcastResult(gotAssetSystemInfoByIdFromProduct, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetAssetInfoById, pathAssetId, AZ::AzTypeInfo::Uuid(), sliceSourceInfo, sourcePathFromProduct); if (!gotAssetSystemInfoByIdFromProduct) { AZ_Error("AssetBuilder", false, "AssetSystemRequest::GetAssetInfoById - Failed to get asset info for ( %s ).", pathAssetId.ToString().c_str()); return; } if (pathAssetId.m_subId != sliceSourceInfo.m_assetId.m_subId) { AZ_Error("AssetBuilder", false, "AssetSystemRequest::GetAssetInfoById - Response SubID should match for ( %s ) Received SubID %d.", pathAssetId.ToString().c_str(), sliceSourceInfo.m_assetId.m_subId); return; } if (sliceSourceInfo.m_assetType != AZ::AzTypeInfo::Uuid()) { AZ_Error("AssetBuilder", false, "AssetSystemRequest::GetAssetInfoById - Lost asset type info for asset ( %s ).", pathAssetId.ToString().c_str()); return; } // Now validate failure case AZ::Data::AssetId badAssetId; badAssetId.m_guid = AZ::Uuid::Create(); badAssetId.m_subId = sliceSourceInfo.m_assetId.m_subId; gotAssetSystemInfoByIdFromProduct = false; AzToolsFramework::AssetSystemRequestBus::BroadcastResult(gotAssetSystemInfoByIdFromProduct, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetAssetInfoById, badAssetId, AZ::AzTypeInfo::Uuid(), sliceSourceInfo, sourcePathFromProduct); if (gotAssetSystemInfoByIdFromProduct) { AZ_Error("AssetBuilder", false, "AssetSystemRequest::GetAssetInfoById - Got a valid result for invalid asset ( %s ).", badAssetId.ToString().c_str()); return; } if (sliceSourceInfo.m_assetId.IsValid()) { AZ_Error("AssetBuilder", false, "AssetSystemRequest::GetAssetInfoById - Response AssetID should not be valid for ( %s )", badAssetId.ToString().c_str()); return; } if (badAssetId.m_subId == sliceSourceInfo.m_assetId.m_subId) { AZ_Error("AssetBuilder", false, "AssetSystemRequest::GetAssetInfoById - Response SubID should not match for ( %s ) Received SubID %d.", badAssetId.ToString().c_str()); return; } if (sliceSourceInfo.m_assetType != AZ::Data::s_invalidAssetType) { AZ_Error("AssetBuilder", false, "AssetSystemRequest::GetAssetInfoById - Response AssetType should not be valid for ( %s )", badAssetId.ToString().c_str()); return; } bool gotSourceInfo{ false }; AZStd::string watchFolder; AZ::Data::AssetInfo sourcePathAssetInfo; AzToolsFramework::AssetSystemRequestBus::BroadcastResult(gotSourceInfo, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourcePath, sourcePath.c_str(), sourcePathAssetInfo, watchFolder); if (!gotSourceInfo) { AZ_Error("AssetBuilder", false, "GetSourceInfoBySourcePath - Failed to get source info for source ( %s ).", sourcePath.c_str()); return; } if (!sourcePathAssetInfo.m_assetId.IsValid()) { AZ_Error("AssetBuilder", false, "GetSourceInfoBySourcePath - Asset info should be valid for asset at source path ( %s ).", sourcePath.c_str()); return; } if (watchFolder.empty()) { AZ_Error("AssetBuilder", false, "GetSourceInfoBySourcePath - Got empty watch folder for asset at source path ( %s ).", sourcePath.c_str()); return; } if (AzFramework::StringFunc::Path::IsRelative(watchFolder.c_str())) { AZ_Error("AssetBuilder", false, "GetSourceInfoBySourcePath - Got relative path %s for source asset ( %s ).", watchFolder.c_str(), sourcePath.c_str()); return; } AZ::Data::AssetId sourceAssetId{ sourcePathAssetInfo.m_assetId }; AZStd::string rootPath; bool gotResultAssetInfo{ false }; AZ::Data::AssetInfo systemAssetInfo; AzToolsFramework::AssetSystemRequestBus::BroadcastResult(gotResultAssetInfo, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetAssetInfoById, sourceAssetId, sourcePathAssetInfo.m_assetType, systemAssetInfo, rootPath); if (!gotResultAssetInfo) { AZ_Error("AssetBuilder", false, "GetAssetInfoById - Failed to get asset info for ( %s ).", sourceAssetId.ToString().c_str()); return; } if (!systemAssetInfo.m_assetId.IsValid()) { AZ_Error("AssetBuilder", false, "GetAssetInfoById - Asset info should be valid for this asset ( %s ).", sourceAssetId.ToString().c_str()); return; } if (rootPath.empty()) { AZ_Error("AssetBuilder", false, "GetAssetInfoById - Failed to get root path for ( %s ).", sourceAssetId.ToString().c_str()); return; } if (watchFolder != rootPath) { AZ_Error("AssetBuilder", false, "GetAssetInfoById - Watch folder and root path don't match( %s vs %s ).", watchFolder.c_str(), rootPath.c_str()); return; } watchFolder.clear(); AZ::Data::AssetInfo sourcePathAssetInfoByUUID; AzToolsFramework::AssetSystemRequestBus::BroadcastResult(gotSourceInfo, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourceUUID, sourceAssetId.m_guid, sourcePathAssetInfoByUUID, watchFolder); if (!gotSourceInfo) { AZ_Error("AssetBuilder", false, "GetSourceInfoBySourceUUID - Asset info should be valid for asset with uuid ( %s ).", sourceAssetId.m_guid.ToString().c_str()); return; } if (!sourcePathAssetInfo.m_assetId.IsValid()) { AZ_Error("AssetBuilder", false, "GetSourceInfoBySourceUUID - Asset info should be valid for asset with uuid ( %s ).", sourceAssetId.m_guid.ToString().c_str()); return; } if (watchFolder.empty()) { AZ_Error("AssetBuilder", false, "GetSourceInfoBySourceUUID - Got empty watch folder for asset with uuid ( %s ).", sourceAssetId.m_guid.ToString().c_str()); return; } if (watchFolder != rootPath) { AZ_Error("AssetBuilder", false, "GetSourceInfoBySourceUUID - Watch folder and root path don't match( %s vs %s ).", watchFolder.c_str(), rootPath.c_str()); return; } AZ::Data::AssetStreamInfo sourceStreamInfo = AZ::Data::AssetManager::Instance().GetLoadStreamInfoForAsset(sourceAssetId, sourcePathAssetInfo.m_assetType); if (!resultInfo.IsValid()) { AZ_Error("AssetBuilder", false, "GetLoadStreamInfoForAsset - Source AssetStreamInfo should be valid for this asset ( %s ).", sourceAssetId.ToString().c_str()); return; } if (sourceStreamInfo.m_streamName != sourcePath) { AZ_Error("AssetBuilder", false, "GetLoadStreamInfoForAsset - Stream name doesn't match source path (%s vs %s ).", sourceStreamInfo.m_streamName.c_str(), sourcePath.c_str()); return; }; AzFramework::StringFunc::Path::ReplaceExtension(fileName, "slicetestout"); } // write the file to the cache at (temppath)/filenameOnly AZStd::string destPath; AZStd::string fileNameOnly; AzFramework::StringFunc::Path::GetFullFileName(fileName.c_str(), fileNameOnly); // this removes the path from fileName. AzFramework::StringFunc::Path::ConstructFull(request.m_tempDirPath.c_str(), fileNameOnly.c_str(), destPath, true); // Check if we are cancelled or shutting down before doing intensive processing on this source file if (jobCancelListener.IsCancelled()) { AZ_TracePrintf(AssetBuilderSDK::WarningWindow, "Cancel was requested for job %s.\n", request.m_fullPath.c_str()); response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Cancelled; return; } if (m_isShuttingDown) { AZ_TracePrintf(AssetBuilderSDK::WarningWindow, "Cancelled job %s because shutdown was requested.\n", request.m_fullPath.c_str()); response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Cancelled; return; } AZ::IO::HandleType assetfileHandle; if (!fileIO->Open(destPath.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary, assetfileHandle)) { AZ_Error("AssetBuilder", false, " Unable to open file for writing ( %s ).", destPath.c_str()); return; } if (!fileIO->Write(assetfileHandle, outputData.data(), outputData.size())) { AZ_Error("AssetBuilder", false, " Unable to write to file data ( %s ).", destPath.c_str()); fileIO->Close(assetfileHandle); return; } fileIO->Close(assetfileHandle); AssetBuilderSDK::JobProduct jobProduct(fileNameOnly, outputAssetType, outputSubId); jobProduct.m_dependenciesHandled = true; // This builder has no product dependencies // once you've filled up the details of the product in jobProduct, add it to the result list: response.m_outputProducts.push_back(jobProduct); response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success; } void TestAssetBuilderComponent::ShutDown() { m_isShuttingDown = true; } } // namespace TestAssetBuilder