فهرست منبع

{lyn13480} Make Asset Cache Server feature configurable at run time (#10340)

* config updates for ACS

Signed-off-by: Allen Jackson <[email protected]>

* Fixing some merge compile errors

Signed-off-by: Allen Jackson <[email protected]>

* cleaning up merge compile errors in tests

Signed-off-by: Allen Jackson <[email protected]>

* small fix for a unit test

Signed-off-by: Allen Jackson <[email protected]>

* new API for setting up the ACS mode

Signed-off-by: Allen Jackson <[email protected]>

* * AssetServerHandlerUnitTest handles the new test logic to enable the Asset Cache Server. so removed GetServerAddress_ReadFromConfig_Valid
* updated AssetCacheServer logic to serialize settings as JSON

Signed-off-by: Allen Jackson <[email protected]>

* Signed-off-by: Allen Jackson <[email protected]>

* Signed-off-by: Allen Jackson <[email protected]>

* removing lines

Signed-off-by: Allen Jackson <[email protected]>

* minor updates

Signed-off-by: Allen Jackson <[email protected]>

* updated comments and reflect() for platform config

Signed-off-by: Allen Jackson <[email protected]>
Allen Jackson 3 سال پیش
والد
کامیت
c47ceda5b2
23فایلهای تغییر یافته به همراه604 افزوده شده و 382 حذف شده
  1. 3 0
      Code/Tools/AssetProcessor/AssetBuilderSDK/AssetBuilderSDK/AssetBuilderSDK.h
  2. 16 12
      Code/Tools/AssetProcessor/native/AssetManager/assetProcessorManager.cpp
  3. 101 93
      Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp
  4. 3 14
      Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.h
  5. 5 2
      Code/Tools/AssetProcessor/native/resourcecompiler/rcjob.cpp
  6. 5 5
      Code/Tools/AssetProcessor/native/tests/AssetCatalog/AssetCatalogUnitTests.cpp
  7. 6 6
      Code/Tools/AssetProcessor/native/tests/assetmanager/AssetProcessorManagerTest.cpp
  8. 1 1
      Code/Tools/AssetProcessor/native/tests/platformconfiguration/platformconfigurationtests.cpp
  9. 0 22
      Code/Tools/AssetProcessor/native/tests/utilities/assetUtilsTest.cpp
  10. 27 13
      Code/Tools/AssetProcessor/native/unittests/AssetCacheServerUnitTests.cpp
  11. 19 19
      Code/Tools/AssetProcessor/native/unittests/AssetProcessorManagerUnitTests.cpp
  12. 9 5
      Code/Tools/AssetProcessor/native/unittests/MockApplicationManager.cpp
  13. 3 3
      Code/Tools/AssetProcessor/native/unittests/PlatformConfigurationUnitTests.cpp
  14. 1 0
      Code/Tools/AssetProcessor/native/utilities/ApplicationManager.cpp
  15. 1 3
      Code/Tools/AssetProcessor/native/utilities/ApplicationManagerBase.cpp
  16. 163 8
      Code/Tools/AssetProcessor/native/utilities/AssetServerHandler.cpp
  17. 14 1
      Code/Tools/AssetProcessor/native/utilities/AssetServerHandler.h
  18. 29 1
      Code/Tools/AssetProcessor/native/utilities/AssetUtilEBusHelper.h
  19. 2 0
      Code/Tools/AssetProcessor/native/utilities/GUIApplicationManager.cpp
  20. 166 35
      Code/Tools/AssetProcessor/native/utilities/PlatformConfiguration.cpp
  21. 28 7
      Code/Tools/AssetProcessor/native/utilities/PlatformConfiguration.h
  22. 2 117
      Code/Tools/AssetProcessor/native/utilities/assetUtils.cpp
  23. 0 15
      Code/Tools/AssetProcessor/native/utilities/assetUtils.h

+ 3 - 0
Code/Tools/AssetProcessor/AssetBuilderSDK/AssetBuilderSDK/AssetBuilderSDK.h

@@ -201,6 +201,9 @@ namespace AssetBuilderSDK
     class FilePatternMatcher
     {
     public:
+        AZ_CLASS_ALLOCATOR(FilePatternMatcher, AZ::SystemAllocator, 0);
+        AZ_TYPE_INFO(FilePatternMatcher, "{3649C0D9-D9D5-4878-B14B-C7E1E1137894}");
+
         FilePatternMatcher() = default;
         explicit FilePatternMatcher(const AssetBuilderSDK::AssetBuilderPattern& pattern);
         FilePatternMatcher(const AZStd::string& pattern, AssetBuilderSDK::AssetBuilderPattern::PatternType type);

+ 16 - 12
Code/Tools/AssetProcessor/native/AssetManager/assetProcessorManager.cpp

@@ -74,10 +74,12 @@ namespace AssetProcessor
         PopulateJobStateCache();
 
         AssetProcessor::ProcessingJobInfoBus::Handler::BusConnect();
+        AZ::Interface<AssetProcessor::RecognizerConfiguration>::Register(m_platformConfig);
     }
 
     AssetProcessorManager::~AssetProcessorManager()
     {
+        AZ::Interface<AssetProcessor::RecognizerConfiguration>::Unregister(m_platformConfig);
         AssetProcessor::ProcessingJobInfoBus::Handler::BusDisconnect();
     }
 
@@ -2291,7 +2293,10 @@ namespace AssetProcessor
 
     void AssetProcessorManager::UpdateForCacheServer(JobDetails& jobDetails)
     {
-        if (AssetUtilities::ServerAddress().isEmpty())
+        AssetServerMode assetServerMode = AssetServerMode::Inactive;
+        AssetServerBus::BroadcastResult(assetServerMode, &AssetServerBus::Events::GetRemoteCachingMode);
+
+        if (assetServerMode == AssetServerMode::Inactive)
         {
             // Asset Cache Server mode feature is turned off
             return;
@@ -2303,21 +2308,20 @@ namespace AssetProcessor
         }
 
         auto& cacheRecognizerContainer = m_platformConfig->GetAssetCacheRecognizerContainer();
-        for(auto&& cacheRecognizer : cacheRecognizerContainer)
+        for(const auto& cacheRecognizerPair : cacheRecognizerContainer)
         {
-            auto matchingPatternIt = AZStd::find_if(
-                jobDetails.m_assetBuilderDesc.m_patterns.begin(),
-                jobDetails.m_assetBuilderDesc.m_patterns.end(),
-                [cacheRecognizer](const AssetBuilderSDK::AssetBuilderPattern& pattern)
-                {
-                    return cacheRecognizer.m_patternMatcher.GetBuilderPattern().m_type == pattern.m_type &&
-                           cacheRecognizer.m_patternMatcher.GetBuilderPattern().m_pattern == pattern.m_pattern;
-                }
-            );
+            auto& cacheRecognizer = cacheRecognizerPair.second;
 
-            if (matchingPatternIt != jobDetails.m_assetBuilderDesc.m_patterns.end())
+            bool matchFound =
+                cacheRecognizer.m_patternMatcher.MatchesPath(jobDetails.m_jobEntry.m_databaseSourceName.toUtf8().data());
+
+            bool builderNameMatches =
+                cacheRecognizer.m_name.compare(jobDetails.m_assetBuilderDesc.m_name.c_str()) == 0;
+
+            if (matchFound || builderNameMatches)
             {
                 jobDetails.m_checkServer = cacheRecognizer.m_checkServer;
+                return;
             }
         }
     }

+ 101 - 93
Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.cpp

@@ -45,26 +45,26 @@ namespace AssetProcessor
         s_TempSolution_CopyJobsFinished = false;
     }
 
-    //! Special ini configuration keyword to mark a asset pattern for skipping
+    //! Special configuration keyword to mark a asset pattern for skipping
     const QString ASSET_PROCESSOR_CONFIG_KEYWORD_SKIP = "skip";
 
-    //! Special ini configuration keyword to mark a asset pattern for copying
+    //! Special configuration keyword to mark a asset pattern for copying
     const QString ASSET_PROCESSOR_CONFIG_KEYWORD_COPY = "copy";
 
     namespace Internal
     {
         void PopulateCommonDescriptorParams(AssetBuilderSDK::JobDescriptor& descriptor, const QString& platformIdentifier, const AssetInternalSpec& platformSpec, const InternalAssetRecognizer* const recognizer)
         {
-            descriptor.m_jobKey = recognizer->m_name.toUtf8().constData();
+            descriptor.m_jobKey = recognizer->m_name;
             descriptor.SetPlatformIdentifier(platformIdentifier.toUtf8().constData());
             descriptor.m_priority = recognizer->m_priority;
             descriptor.m_checkExclusiveLock = recognizer->m_testLockSource;
 
-            QString extraInformationForFingerprinting;
-            extraInformationForFingerprinting.append(platformSpec == AssetInternalSpec::Copy ? ASSET_PROCESSOR_CONFIG_KEYWORD_COPY : ASSET_PROCESSOR_CONFIG_KEYWORD_SKIP);
+            AZStd::string extraInformationForFingerprinting;
+            extraInformationForFingerprinting.append(platformSpec == AssetInternalSpec::Copy ? "copy" : "skip");
             extraInformationForFingerprinting.append(recognizer->m_version);
 
-            // if we have specified the product asset type, changing it should cuase
+            // if we have specified the product asset type, changing it should cause
             if (!recognizer->m_productAssetType.IsNull())
             {
                 char typeAsString[64] = { 0 };
@@ -74,7 +74,7 @@ namespace AssetProcessor
 
             descriptor.m_priority = recognizer->m_priority;
 
-            descriptor.m_additionalFingerprintInfo = AZStd::string(extraInformationForFingerprinting.toUtf8().constData());
+            descriptor.m_additionalFingerprintInfo = extraInformationForFingerprinting;
 
             bool isCopyJob = (platformSpec == AssetInternalSpec::Copy);
 
@@ -95,6 +95,69 @@ namespace AssetProcessor
                 descriptor.m_priority = 1;
             }
         }
+
+        void RegisterInternalAssetRecognizerToMap(
+            const AssetRecognizer& assetRecognizer,
+            const AZStd::string& builderId,
+            AZStd::unordered_map<AZStd::string, AssetInternalSpec>& sourceAssetInternalSpecs,
+            AZStd::unordered_map<AZStd::string, InternalAssetRecognizerList>& internalRecognizerListByType)
+        {
+            // this is called to say that the internal builder with builderID is to handle assets recognized by the given recognizer.
+            InternalAssetRecognizer* newAssetRecognizer = new InternalAssetRecognizer(assetRecognizer, builderId, sourceAssetInternalSpecs);
+            // the list is keyed off the builderID.
+            internalRecognizerListByType[builderId].push_back(newAssetRecognizer);
+        }
+
+        // Split all of the asset recognizers from a container into buckets based on their specific builder action type
+        void BuildInternalAssetRecognizersByType(const RecognizerContainer& assetRecognizers, AZStd::unordered_map<AZStd::string, InternalAssetRecognizerList>& internalRecognizerListByType)
+        {
+            // Go through each asset recognizer's platform specs to determine which type bucket to create and put the converted internal
+            // assert recognizer into
+            for (const auto& assetRecognizer : assetRecognizers)
+            {
+                // these hashes are keyed on the same key as the incoming asset recognizers list, which is
+                // [ name in ini file ] --> [regognizer details]
+                // so like "rc png" --> [details].  Specifically, the QString key is the name of the entry in the INI file and NOT a platform name.
+                AZStd::unordered_map<AZStd::string, AssetInternalSpec> copyAssetInternalSpecs;
+                AZStd::unordered_map<AZStd::string, AssetInternalSpec> skipAssetInternalSpecs;
+
+                // Go through the global asset recognizers and split them by operation keywords if they exist or by the main rc param
+                for (auto iterSrcPlatformSpec = assetRecognizer.second.m_platformSpecs.begin();
+                    iterSrcPlatformSpec != assetRecognizer.second.m_platformSpecs.end();
+                    iterSrcPlatformSpec++)
+                {
+                    auto platformSpec = (*iterSrcPlatformSpec).second;
+                    auto& platformId = (*iterSrcPlatformSpec).first;
+
+                    if (platformSpec == AssetInternalSpec::Copy)
+                    {
+                        copyAssetInternalSpecs[platformId] = platformSpec;
+                    }
+                    else if (platformSpec == AssetInternalSpec::Skip)
+                    {
+                        skipAssetInternalSpecs[platformId] = platformSpec;
+                    }
+                }
+
+                // Create separate internal asset recognizers based on whether or not they were detected
+                if (copyAssetInternalSpecs.size() > 0)
+                {
+                    RegisterInternalAssetRecognizerToMap(
+                        assetRecognizer.second,
+                        BUILDER_ID_COPY.GetId().toUtf8().data(),
+                        copyAssetInternalSpecs,
+                        internalRecognizerListByType);
+                }
+                if (skipAssetInternalSpecs.size() > 0)
+                {
+                    RegisterInternalAssetRecognizerToMap(
+                        assetRecognizer.second,
+                        BUILDER_ID_SKIP.GetId().toUtf8().data(),
+                        skipAssetInternalSpecs,
+                        internalRecognizerListByType);
+                }
+            }
+        }
     }
 
     BuilderIdAndName::BuilderIdAndName(QString builderName, QString builderId, Type type, QString rcParam /*=QString("")*/)
@@ -156,15 +219,15 @@ namespace AssetProcessor
         { BUILDER_ID_SKIP.GetId(), BUILDER_ID_SKIP }
     };
 
-    InternalAssetRecognizer::InternalAssetRecognizer(const AssetRecognizer& src, const QString& builderId, const QHash<QString, AssetInternalSpec>& assetPlatformSpecByPlatform)
+    InternalAssetRecognizer::InternalAssetRecognizer(const AssetRecognizer& src, const AZStd::string& builderId, const AZStd::unordered_map<AZStd::string, AssetInternalSpec>& AssetInternalSpecByPlatform)
         : AssetRecognizer(src.m_name, src.m_testLockSource, src.m_priority, src.m_isCritical, src.m_supportsCreateJobs, src.m_patternMatcher, src.m_version, src.m_productAssetType, src.m_outputProductDependencies, src.m_checkServer)
         , m_builderId(builderId)
     {
-        // assetPlatformSpecByPlatform is a hash table like
+        // AssetInternalSpecByPlatform is a hash table like
         // "pc" --> (settings to compile on pc)
         // "ios" --> settings to compile on ios)
         // and so is m_platformSpecsByPlatform
-        m_platformSpecsByPlatform = assetPlatformSpecByPlatform;
+        m_platformSpecsByPlatform = AssetInternalSpecByPlatform;
         m_paramID = CalculateCRC();
     }
 
@@ -172,8 +235,8 @@ namespace AssetProcessor
     {
         AZ::Crc32 crc;
 
-        crc.Add(m_name.toUtf8().data());
-        crc.Add(m_builderId.toUtf8().data());
+        crc.Add(m_name);
+        crc.Add(m_builderId);
         crc.Add(const_cast<void*>(static_cast<const void*>(&m_testLockSource)), sizeof(m_testLockSource));
         crc.Add(const_cast<void*>(static_cast<const void*>(&m_priority)), sizeof(m_priority));
         crc.Add(m_patternMatcher.GetBuilderPattern().m_pattern.c_str());
@@ -249,8 +312,8 @@ namespace AssetProcessor
         // Split the asset recognizers that were scanned in into 'buckets' for each of the 3 builder ids based on
         // either the custom fixed rc params or the standard rc param ('copy','skip', or others)
 
-        QHash<QString, InternalAssetRecognizerList> internalRecognizerListByType;
-        InternalRecognizerBasedBuilder::BuildInternalAssetRecognizersByType(assetRecognizers, internalRecognizerListByType);
+        AZStd::unordered_map<AZStd::string, InternalAssetRecognizerList> internalRecognizerListByType;
+        Internal::BuildInternalAssetRecognizersByType(assetRecognizers, internalRecognizerListByType);
 
         // note that the QString key to this map is actually the builder ID (as in the QString "Internal Copy Builder" for example)
         // and the key of the map is actually a AZStd::list for InternalAssetRecognizer* which belong to that builder
@@ -288,23 +351,21 @@ namespace AssetProcessor
         //        }
         //      },
 
-        for (auto internalRecognizerList = internalRecognizerListByType.begin();
-             internalRecognizerList != internalRecognizerListByType.end();
-             internalRecognizerList++)
+        for (const auto& internalRecognizerList : internalRecognizerListByType)
         {
-            QString builderId = internalRecognizerList.key();
+            QString builderId = internalRecognizerList.first.c_str();
             const BuilderIdAndName& builderInfo = m_builderById[builderId];
             QString builderName = builderInfo.GetName();
             AZStd::vector<AssetBuilderSDK::AssetBuilderPattern> builderPatterns;
 
             bool supportsCreateJobs = false;
-            // intentionaly using a set here, as we want it to be the same order each time for hashing.
+            // intentionally using a set here, as we want it to be the same order each time for hashing.
             AZStd::set<AZStd::string> fingerprintRelevantParameters;
 
-            for (auto internalAssetRecognizer : *internalRecognizerList)
+            for (auto* internalAssetRecognizer : internalRecognizerList.second)
             {
                 // so referring to the structure explanation above, internalAssetRecognizer is
-                // one of those objects that has the regex in it, (along with list of commands to apply per platform)
+                // one of those objects that has the RegEx in it, (along with list of commands to apply per platform)
                 if (internalAssetRecognizer->m_platformSpecsByPlatform.size() == 0)
                 {
                     delete internalAssetRecognizer;
@@ -321,28 +382,27 @@ namespace AssetProcessor
                     continue;
                 }
 
-                for (auto iteratorValue = internalAssetRecognizer->m_platformSpecsByPlatform.begin();
-                    iteratorValue != internalAssetRecognizer->m_platformSpecsByPlatform.end();
-                    ++iteratorValue)
+                for (const auto& iteratorValue : internalAssetRecognizer->m_platformSpecsByPlatform)
                 {
-                    const char* internalJobName = (iteratorValue.value() == AssetInternalSpec::Copy) ?
-                        ASSET_PROCESSOR_CONFIG_KEYWORD_COPY.toUtf8().constData() :
-                        ASSET_PROCESSOR_CONFIG_KEYWORD_SKIP.toUtf8().constData();
-                    fingerprintRelevantParameters.insert(AZStd::string::format("%s-%s", iteratorValue.key().toUtf8().constData(), internalJobName));
+                    fingerprintRelevantParameters.insert(
+                        AZStd::string::format(
+                            "%s-%s",
+                            iteratorValue.first.c_str(),
+                            iteratorValue.second == AssetInternalSpec::Copy ? "copy" : "skip"));
                 }
 
                 // note that the version number must be included here, despite the builder dirty-check function taking version into account
                 // because the RC Builder is just a single builder (with version#0) that defers to these "internal" builders when called upon.
-                if (!internalAssetRecognizer->m_version.isEmpty())
+                if (!internalAssetRecognizer->m_version.empty())
                 {
-                    fingerprintRelevantParameters.insert(internalAssetRecognizer->m_version.toUtf8().constData());
+                    fingerprintRelevantParameters.insert(internalAssetRecognizer->m_version);
                 }
                 fingerprintRelevantParameters.insert(internalAssetRecognizer->m_productAssetType.ToString<AZStd::string>());
 
                 // Register the recognizer
                 builderPatterns.push_back(internalAssetRecognizer->m_patternMatcher.GetBuilderPattern());
                 m_assetRecognizerDictionary[internalAssetRecognizer->m_paramID] = internalAssetRecognizer;
-                AZ_TracePrintf(AssetProcessor::DebugChannel, "Registering %s as a %s\n", internalAssetRecognizer->m_name.toUtf8().data(),
+                AZ_TracePrintf(AssetProcessor::DebugChannel, "Registering %s as a %s\n", internalAssetRecognizer->m_name.c_str(),
                     builderName.toUtf8().data());
 
                 supportsCreateJobs = supportsCreateJobs || (internalAssetRecognizer->m_supportsCreateJobs);
@@ -460,24 +520,20 @@ namespace AssetProcessor
             bool skippedByPlatform = false;
 
             // Iterate through the platform specific specs and apply the ones that match the platform flag
-            for (auto iterPlatformSpec = recognizer->m_platformSpecsByPlatform.cbegin();
-                iterPlatformSpec != recognizer->m_platformSpecsByPlatform.cend();
-                iterPlatformSpec++)
+            for (const auto& platformSpec : recognizer->m_platformSpecsByPlatform)
             {
-                if (request.HasPlatform(iterPlatformSpec.key().toUtf8().constData()))
+                if (request.HasPlatform(platformSpec.first.c_str()))
                 {
-                    auto internalJobType = iterPlatformSpec.value();
-
                     // Check if this is the 'skip' parameter
-                    if (internalJobType == AssetInternalSpec::Skip)
+                    if (platformSpec.second == AssetInternalSpec::Skip)
                     {
                         skippedByPlatform = true;
                     }
                     // The recognizer's builder id must match the job requests' builder id
-                    else if (recognizer->m_builderId.compare(requestedBuilderID) == 0)
+                    else if (requestedBuilderID.compare(recognizer->m_builderId.c_str()) == 0)
                     {
                         AssetBuilderSDK::JobDescriptor descriptor;
-                        Internal::PopulateCommonDescriptorParams(descriptor, iterPlatformSpec.key(), iterPlatformSpec.value(), recognizer);
+                        Internal::PopulateCommonDescriptorParams(descriptor, platformSpec.first.c_str(), platformSpec.second, recognizer);
                         // Job Parameter Value can be any arbitrary string since we are relying on the key to lookup
                         // the parameter in the process job
                         descriptor.m_jobParameters[recognizer->m_paramID] = descriptor.m_jobKey;
@@ -486,12 +542,12 @@ namespace AssetProcessor
                         response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success;
                     }
                 }
-            }
 
-            // Adjust response if we did not get any jobs, but one or more platforms were marked as skipped
-            if ((response.m_result == AssetBuilderSDK::CreateJobsResultCode::Failed) && (skippedByPlatform))
-            {
-                response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success;
+                // Adjust response if we did not get any jobs, but one or more platforms were marked as skipped
+                if ((response.m_result == AssetBuilderSDK::CreateJobsResultCode::Failed) && (skippedByPlatform))
+                {
+                    response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success;
+                }
             }
         }
     }
@@ -640,53 +696,5 @@ namespace AssetProcessor
 
         return false;
     }
-
-
-    void InternalRecognizerBasedBuilder::RegisterInternalAssetRecognizerToMap(const AssetRecognizer& assetRecognizer, const QString& builderId, QHash<QString, AssetInternalSpec>& sourceAssetPlatformSpecs, QHash<QString, InternalAssetRecognizerList>& internalRecognizerListByType)
-    {
-        // this is called to say that the internal builder with builderID is to handle assets recognized by the givne recognizer.
-        InternalAssetRecognizer* newAssetRecognizer = new InternalAssetRecognizer(assetRecognizer, builderId, sourceAssetPlatformSpecs);
-        // the list is keyed off the builderID.
-        internalRecognizerListByType[builderId].push_back(newAssetRecognizer);
-    }
-
-    void InternalRecognizerBasedBuilder::BuildInternalAssetRecognizersByType(const RecognizerContainer& assetRecognizers, QHash<QString, InternalAssetRecognizerList>& internalRecognizerListByType)
-    {
-        // Go through each asset recognizer's platform specs to determine which type bucket to create and put the converted internal
-        // assert recognizer into
-        for (const AssetRecognizer& assetRecognizer : assetRecognizers)
-        {
-            // these hashes are keyed on the same key as the incoming asset recognizers list, which is
-            // [ name in ini file ] --> [regognizer details]
-            // so like "rc png" --> [details].  Specifically, the QString key is the name of the entry in the INI file and NOT a platform name.
-            QHash<QString, AssetInternalSpec> copyAssetPlatformSpecs;
-            QHash<QString, AssetInternalSpec> skipAssetPlatformSpecs;
-
-            // Go through the global asset recognizers and split them by operation keywords if they exist or by the main rc param
-            for (auto iterSrcPlatformSpec = assetRecognizer.m_platformSpecs.begin();
-                 iterSrcPlatformSpec != assetRecognizer.m_platformSpecs.end();
-                 iterSrcPlatformSpec++)
-            {
-                if (*iterSrcPlatformSpec == AssetInternalSpec::Copy)
-                {
-                    copyAssetPlatformSpecs[iterSrcPlatformSpec.key()] = iterSrcPlatformSpec.value();
-                }
-                else if (*iterSrcPlatformSpec == AssetInternalSpec::Skip)
-                {
-                    skipAssetPlatformSpecs[iterSrcPlatformSpec.key()] = iterSrcPlatformSpec.value();
-                }
-            }
-
-            // Create separate internal asset recognizers based on whether or not they were detected
-            if (copyAssetPlatformSpecs.size() > 0)
-            {
-                RegisterInternalAssetRecognizerToMap(assetRecognizer, BUILDER_ID_COPY.GetId(), copyAssetPlatformSpecs, internalRecognizerListByType);
-            }
-            if (skipAssetPlatformSpecs.size() > 0)
-            {
-                RegisterInternalAssetRecognizerToMap(assetRecognizer, BUILDER_ID_SKIP.GetId(), skipAssetPlatformSpecs, internalRecognizerListByType);
-            }
-        }
-    }
 }
 

+ 3 - 14
Code/Tools/AssetProcessor/native/resourcecompiler/RCBuilder.h

@@ -51,20 +51,20 @@ namespace AssetProcessor
     struct InternalAssetRecognizer
         : public AssetRecognizer
     {
-        InternalAssetRecognizer(const AssetRecognizer& src, const QString& builderId, const QHash<QString, AssetInternalSpec>& assetPlatformSpecByPlatform);
+        InternalAssetRecognizer(const AssetRecognizer& src, const AZStd::string& builderId, const AZStd::unordered_map<AZStd::string, AssetInternalSpec>& assetPlatformSpecByPlatform);
         InternalAssetRecognizer(const InternalAssetRecognizer& src) = default;
 
         AZ::u32 CalculateCRC() const;
 
         //! Map of platform specs based on the identifier of the platform
-        QHash<QString, AssetInternalSpec> m_platformSpecsByPlatform;
+        AZStd::unordered_map<AZStd::string, AssetInternalSpec> m_platformSpecsByPlatform;
 
         //! unique id that is generated for each unique internal asset recognizer
         //! which can be used as the key for the job parameter map (see AssetBuilderSDK::JobParameterMap)
         AZ::u32 m_paramID;
 
         //! Keep track which internal builder type this recognizer is for
-        const QString m_builderId;
+        const AZStd::string m_builderId;
     };
     typedef QHash<AZ::u32, InternalAssetRecognizer*> InternalRecognizerContainer;
     typedef QList<const InternalAssetRecognizer*> InternalRecognizerPointerContainer;
@@ -96,17 +96,6 @@ namespace AssetProcessor
 
         static bool MatchTempFileToSkip(const QString& outputFilename);
 
-        static void RegisterInternalAssetRecognizerToMap(
-            const AssetRecognizer& assetRecognizer,
-            const QString& builderId,
-            QHash<QString, AssetInternalSpec>& sourceAssetPlatformSpecs,
-            QHash<QString, InternalAssetRecognizerList>& internalRecognizerListByType);
-
-        //! Split all of the asset recognizers from a container into buckets based on their specific builder action type
-        static void BuildInternalAssetRecognizersByType(
-            const RecognizerContainer& assetRecognizers,
-            QHash<QString, InternalAssetRecognizerList>& internalRecognizerListByType);
-
     protected:
         //! Constructor to initialize the internal builders and a general internal builder uuid that is used for bus
         //! registration.  This constructor is helpful for deriving other classes from this builder for purposes like

+ 5 - 2
Code/Tools/AssetProcessor/native/resourcecompiler/rcjob.cpp

@@ -538,10 +538,13 @@ namespace AssetProcessor
                     bool runProcessJob = true;
                     if (m_jobDetails.m_checkServer)
                     {
+                        AssetServerMode assetServerMode = AssetServerMode::Inactive;
+                        AssetServerBus::BroadcastResult(assetServerMode, &AssetServerBus::Events::GetRemoteCachingMode);
+
                         QFileInfo fileInfo(builderParams.m_processJobRequest.m_sourceFile.c_str());
                         builderParams.m_serverKey = QString("%1_%2_%3_%4").arg(fileInfo.completeBaseName(), builderParams.m_processJobRequest.m_jobDescription.m_jobKey.c_str(), builderParams.m_processJobRequest.m_platformInfo.m_identifier.c_str()).arg(builderParams.m_rcJob->GetOriginalFingerprint());
                         bool operationResult = false;
-                        if (AssetUtilities::InServerMode())
+                        if (assetServerMode == AssetServerMode::Server)
                         {
                             // sending process job command to the builder
                             builderParams.m_assetBuilderDesc.m_processJobFunction(builderParams.m_processJobRequest, result);
@@ -566,7 +569,7 @@ namespace AssetProcessor
                                 }
                             }
                         }
-                        else
+                        else if (assetServerMode == AssetServerMode::Client)
                         {
                             // running as client, check with the server whether it has already
                             // processed this asset, if not or if the operation fails then process locally

+ 5 - 5
Code/Tools/AssetProcessor/native/tests/AssetCatalog/AssetCatalogUnitTests.cpp

@@ -251,14 +251,14 @@ namespace AssetProcessor
 
             rec.m_name = "random files";
             rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.random", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-            rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
+            rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
             config.AddRecognizer(rec);
 
             const char* builderTxt1Name = "txt files";
             rec.m_name = builderTxt1Name;
             rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.txt", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-            rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
-            rec.m_platformSpecs.insert("android", AssetInternalSpec::Copy);
+            rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
+            rec.m_platformSpecs.insert({"android", AssetInternalSpec::Copy});
 
             config.AddRecognizer(rec);
 
@@ -266,8 +266,8 @@ namespace AssetProcessor
             AssetRecognizer ignore_rec;
             ignore_rec.m_name = "ignore files";
             ignore_rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.ignore", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-            ignore_rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
-            ignore_rec.m_platformSpecs.insert("android", AssetInternalSpec::Skip);
+            ignore_rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
+            ignore_rec.m_platformSpecs.insert({"android", AssetInternalSpec::Skip});
             config.AddRecognizer(ignore_rec);
 
             ExcludeAssetRecognizer excludeRecogniser;

+ 6 - 6
Code/Tools/AssetProcessor/native/tests/assetmanager/AssetProcessorManagerTest.cpp

@@ -154,7 +154,7 @@ void AssetProcessorManagerTest::SetUp()
     AssetRecognizer rec;
     rec.m_name = "txt files";
     rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.txt", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-    rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
+    rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
     rec.m_supportsCreateJobs = false;
     rec.m_supportsCreateJobs = false;
     ASSERT_TRUE(m_mockApplicationManager->RegisterAssetRecognizerAsBuilder(rec));
@@ -1249,7 +1249,7 @@ void PathDependencyTest::SetUp()
     AssetRecognizer rec;
     rec.m_name = "txt files2";
     rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.txt", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-    rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
+    rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
     rec.m_supportsCreateJobs = false;
     m_mockApplicationManager->RegisterAssetRecognizerAsBuilder(rec);
 
@@ -1493,7 +1493,7 @@ TEST_F(PathDependencyTest, NoLongerProcessedFile_IsRemoved)
     AssetRecognizer rec;
     rec.m_name = "txt files2";
     rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.txt", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-    rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
+    rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
     rec.m_supportsCreateJobs = false;
     m_mockApplicationManager->RegisterAssetRecognizerAsBuilder(rec);
 
@@ -2532,8 +2532,8 @@ void MultiplatformPathDependencyTest::SetUp()
 
     rec.m_name = "multiplatform txt files";
     rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.txt", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-    rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
-    rec.m_platformSpecs.insert("provo", AssetInternalSpec::Copy);
+    rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
+    rec.m_platformSpecs.insert({"provo", AssetInternalSpec::Copy});
     rec.m_supportsCreateJobs = false;
     m_mockApplicationManager->RegisterAssetRecognizerAsBuilder(rec);
 
@@ -2541,7 +2541,7 @@ void MultiplatformPathDependencyTest::SetUp()
 
     rec2.m_name = "single platform ini files";
     rec2.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.ini", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-    rec2.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
+    rec2.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
     rec2.m_supportsCreateJobs = false;
     m_mockApplicationManager->RegisterAssetRecognizerAsBuilder(rec2);
 }

+ 1 - 1
Code/Tools/AssetProcessor/native/tests/platformconfiguration/platformconfigurationtests.cpp

@@ -507,7 +507,7 @@ TEST_F(PlatformConfigurationUnitTests, ReadCheckServer_FromConfig_Valid)
 
     // verify that check server flag is set to true for i_caf
     ASSERT_TRUE(recogs.contains("i_caf"));
-    ASSERT_TRUE(recogs["i_caf"].m_checkServer);
+    ASSERT_TRUE(recogs.at("i_caf").m_checkServer);
 }
 
 TEST_F(PlatformConfigurationUnitTests, PlatformConfigFile_IsPresent_Found)

+ 0 - 22
Code/Tools/AssetProcessor/native/tests/utilities/assetUtilsTest.cpp

@@ -520,28 +520,6 @@ TEST_F(AssetUtilitiesTest, GetFileFingerprint_NonExistentFiles)
     EXPECT_STREQ(AssetUtilities::GetFileFingerprint(nonExistentFile1, "Name").c_str(), AssetUtilities::GetFileFingerprint(nonExistentFile1, "Name").c_str());
 }
 
-TEST_F(AssetUtilitiesTest, GetServerAddress_ReadFromConfig_Valid)
-{
-    QTemporaryDir tempDir;
-    QDir tempPath(tempDir.path());
-    QString assetServerAddress("T:/AssetServerCacheDummyFolder");
-    QString assetProcesorPlatformConfigPath = tempPath.absoluteFilePath("AssetProcessorPlatformConfig.ini");
-    UnitTestUtils::CreateDummyFile(assetProcesorPlatformConfigPath, QString("[Server]\ncacheServerAddress=%1\n").arg(assetServerAddress));
-
-    AssetUtilities::ResetAssetRoot();
-    QDir newRoot;
-    AssetUtilities::ComputeEngineRoot(newRoot, &tempPath);
-
-    auto settingsRegistry = AZ::SettingsRegistry::Get();
-    AZ::SettingsRegistryMergeUtils::ConfigParserSettings configParserSettings;
-    configParserSettings.m_registryRootPointerPath = AssetProcessor::AssetProcessorSettingsKey;
-    AssetProcessor::PlatformConfiguration::MergeConfigFileToSettingsRegistry(*settingsRegistry,
-        assetProcesorPlatformConfigPath.toUtf8().data());
-    QString assetServerAddressReturned = AssetUtilities::ServerAddress();
-    EXPECT_STREQ(assetServerAddressReturned.toUtf8().data(), assetServerAddress.toUtf8().data());
-}
-
-
 TEST_F(AssetUtilitiesTest, CreateDirWithTimeout_Valid)
 {
     QTemporaryDir tempDir;

+ 27 - 13
Code/Tools/AssetProcessor/native/unittests/AssetCacheServerUnitTests.cpp

@@ -52,15 +52,18 @@ namespace UnitTest
             AZ::SettingsRegistry::Register(&m_mockSettingsRegistry);
             m_tempFolder = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
             m_fakeSourceFile = QString(m_tempFolder + m_fakeFullname + ".zip");
-            AssetUtilities::ResetServerAddress();
-            AssetUtilities::ResetServerMode();
+
+            using namespace AssetProcessor;
+            AssetServerBus::Broadcast(&AssetServerBus::Events::SetServerAddress, "");
+            AssetServerBus::Broadcast(&AssetServerBus::Events::SetRemoteCachingMode, AssetServerMode::Inactive);
         }
 
         ~AssetServerHandlerUnitTest()
         {
             RemoveMockAssetArchive();
-            AssetUtilities::ResetServerAddress();
-            AssetUtilities::ResetServerMode();
+            using namespace AssetProcessor;
+            AssetServerBus::Broadcast(&AssetServerBus::Events::SetServerAddress, "");
+            AssetServerBus::Broadcast(&AssetServerBus::Events::SetRemoteCachingMode, AssetServerMode::Inactive);
             AZ::SettingsRegistry::Unregister(&m_mockSettingsRegistry);
         }
 
@@ -116,7 +119,8 @@ namespace UnitTest
 
     TEST_F(AssetServerHandlerUnitTest, AssetCacheServer_UnConfiguredToRunAsServer_SetsFalse)
     {
-        EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<AZStd::string&>(), ::testing::_)).Times(1);
+        EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<AZStd::string&>(), ::testing::_)).Times(2);
+        EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<bool&>(), ::testing::_)).Times(1);
 
         AssetProcessor::AssetServerHandler assetServerHandler;
         EXPECT_FALSE(assetServerHandler.IsServerAddressValid());
@@ -127,12 +131,12 @@ namespace UnitTest
         m_enableServer = true;
         MockSettingsRegistry();
 
-        EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<AZStd::string&>(), ::testing::_)).Times(1);
+        EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<AZStd::string&>(), ::testing::_)).Times(2);
         EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<bool&>(), ::testing::_)).Times(1);
 
         AssetProcessor::AssetServerHandler assetServerHandler;
         EXPECT_TRUE(assetServerHandler.IsServerAddressValid());
-        EXPECT_TRUE(AssetUtilities::InServerMode());
+        EXPECT_TRUE(assetServerHandler.GetRemoteCachingMode() == AssetProcessor::AssetServerMode::Server);
     }
 
     TEST_F(AssetServerHandlerUnitTest, AssetCacheServer_ConfiguredToRunAsClient_Works)
@@ -140,12 +144,12 @@ namespace UnitTest
         m_enableServer = false;
         MockSettingsRegistry();
 
-        EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<AZStd::string&>(), ::testing::_)).Times(1);
+        EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<AZStd::string&>(), ::testing::_)).Times(2);
         EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<bool&>(), ::testing::_)).Times(1);
 
         AssetProcessor::AssetServerHandler assetServerHandler;
         EXPECT_TRUE(assetServerHandler.IsServerAddressValid());
-        EXPECT_FALSE(AssetUtilities::InServerMode());
+        EXPECT_TRUE(assetServerHandler.GetRemoteCachingMode() == AssetProcessor::AssetServerMode::Client);
     }
 
     TEST_F(AssetServerHandlerUnitTest, AssetCacheServer_ServerStoresZipFile_Works)
@@ -162,7 +166,7 @@ namespace UnitTest
         };
         ON_CALL(m_mockArchiveCommandsBusHandler, CreateArchive(::testing::_, ::testing::_)).WillByDefault(createArchive);
 
-        EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<AZStd::string&>(), ::testing::_)).Times(1);
+        EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<AZStd::string&>(), ::testing::_)).Times(2);
         EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<bool&>(), ::testing::_)).Times(1);
         EXPECT_CALL(m_mockArchiveCommandsBusHandler, CreateArchive(::testing::_, ::testing::_)).Times(1);
 
@@ -177,8 +181,13 @@ namespace UnitTest
         builderParams.m_processJobRequest.m_sourceFile = (m_tempFolder + m_fakeFullname).toUtf8().toStdString().c_str();
 
         AssetProcessor::AssetServerHandler assetServerHandler;
+
+        using namespace AssetProcessor;
+        AssetServerMode mode = {};
+        AssetServerBus::BroadcastResult(mode , &AssetServerBus::Events::GetRemoteCachingMode);
+
         EXPECT_TRUE(assetServerHandler.IsServerAddressValid());
-        EXPECT_TRUE(AssetUtilities::InServerMode());
+        EXPECT_EQ(mode, AssetServerMode::Server);
         EXPECT_TRUE(assetServerHandler.StoreJobResult(builderParams, sourceFileList));
     }
 
@@ -197,7 +206,7 @@ namespace UnitTest
         };
         ON_CALL(m_mockArchiveCommandsBusHandler, ExtractArchive(::testing::_, ::testing::_)).WillByDefault(extractArchive);
 
-        EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<AZStd::string&>(), ::testing::_)).Times(1);
+        EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<AZStd::string&>(), ::testing::_)).Times(2);
         EXPECT_CALL(m_mockSettingsRegistry, Get(::testing::An<bool&>(), ::testing::_)).Times(1);
         EXPECT_CALL(m_mockArchiveCommandsBusHandler, ExtractArchive(::testing::_, ::testing::_)).Times(1);
 
@@ -211,8 +220,13 @@ namespace UnitTest
         builderParams.m_processJobRequest.m_sourceFile = (m_tempFolder + m_fakeFullname).toUtf8().toStdString().c_str();
 
         AssetProcessor::AssetServerHandler assetServerHandler;
+
+        using namespace AssetProcessor;
+        AssetServerMode mode = {};
+        AssetServerBus::BroadcastResult(mode, &AssetServerBus::Events::GetRemoteCachingMode);
+
         EXPECT_TRUE(assetServerHandler.IsServerAddressValid());
-        EXPECT_FALSE(AssetUtilities::InServerMode());
+        EXPECT_EQ(mode, AssetServerMode::Client);
         EXPECT_TRUE(assetServerHandler.RetrieveJobResult(builderParams));
     }
 }

+ 19 - 19
Code/Tools/AssetProcessor/native/unittests/AssetProcessorManagerUnitTests.cpp

@@ -93,10 +93,10 @@ namespace AssetProcessor
             config.GetMatchingRecognizers(filePath, output);
             for (const AssetRecognizer* assetRecogniser : output)
             {
-                extraInfoForPC.append(assetRecogniser->m_platformSpecs["pc"] == AssetInternalSpec::Copy ? "copy" : "skip");
-                extraInfoForANDROID.append(assetRecogniser->m_platformSpecs["android"] == AssetInternalSpec::Copy ? "copy" : "skip");
-                extraInfoForPC.append(assetRecogniser->m_version);
-                extraInfoForANDROID.append(assetRecogniser->m_version);
+                extraInfoForPC.append(assetRecogniser->m_platformSpecs.at("pc") == AssetInternalSpec::Copy ? "copy" : "skip");
+                extraInfoForANDROID.append(assetRecogniser->m_platformSpecs.at("android") == AssetInternalSpec::Copy ? "copy" : "skip");
+                extraInfoForPC.append(assetRecogniser->m_version.c_str());
+                extraInfoForANDROID.append(assetRecogniser->m_version.c_str());
             }
 
             //Calculating fingerprints for the file for pc and android platforms
@@ -267,15 +267,15 @@ namespace AssetProcessor
 
         rec.m_name = "random files";
         rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.random", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-        rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
+        rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
         config.AddRecognizer(rec);
         UNIT_TEST_EXPECT_TRUE(mockAppManager.RegisterAssetRecognizerAsBuilder(rec));
 
         const char* builderTxt1Name = "txt files";
         rec.m_name = builderTxt1Name;
         rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.txt", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-        rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
-        rec.m_platformSpecs.insert("android", AssetInternalSpec::Copy);
+        rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
+        rec.m_platformSpecs.insert({"android", AssetInternalSpec::Copy});
 
         config.AddRecognizer(rec);
 
@@ -296,7 +296,7 @@ namespace AssetProcessor
         rec.m_name = "tiff files";
         rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.tiff", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
         rec.m_platformSpecs.clear();
-        rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
+        rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
         rec.m_testLockSource = true;
         config.AddRecognizer(rec);
         mockAppManager.RegisterAssetRecognizerAsBuilder(rec);
@@ -306,15 +306,15 @@ namespace AssetProcessor
 
         rec.m_name = "xxx files";
         rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.xxx", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-        rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
-        rec.m_platformSpecs.insert("android", AssetInternalSpec::Copy);
+        rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
+        rec.m_platformSpecs.insert({"android", AssetInternalSpec::Copy});
         config.AddRecognizer(rec);
         mockAppManager.RegisterAssetRecognizerAsBuilder(rec);
 
         // two recognizers for the same pattern.
         rec.m_name = "xxx files 2 (builder2)";
-        rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
-        rec.m_platformSpecs.insert("android", AssetInternalSpec::Copy);
+        rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
+        rec.m_platformSpecs.insert({"android", AssetInternalSpec::Copy});
         config.AddRecognizer(rec);
         mockAppManager.RegisterAssetRecognizerAsBuilder(rec);
 
@@ -322,8 +322,8 @@ namespace AssetProcessor
         AssetRecognizer ignore_rec;
         ignore_rec.m_name = "ignore files";
         ignore_rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.ignore", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-        ignore_rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
-        ignore_rec.m_platformSpecs.insert("android", AssetInternalSpec::Skip);
+        ignore_rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
+        ignore_rec.m_platformSpecs.insert({"android", AssetInternalSpec::Skip});
         config.AddRecognizer(ignore_rec);
         mockAppManager.RegisterAssetRecognizerAsBuilder(ignore_rec);
 
@@ -1687,7 +1687,7 @@ namespace AssetProcessor
         UNIT_TEST_EXPECT_TRUE(mockAppManager.UnRegisterAssetRecognizerAsBuilder("xxx files 2 (builder2)"));
 
         //Changing specs for pc
-        rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
+        rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
 
         config.AddRecognizer(rec);
         mockAppManager.RegisterAssetRecognizerAsBuilder(rec);
@@ -2191,13 +2191,13 @@ namespace AssetProcessor
         AssetRecognizer abt_rec1;
         abt_rec1.m_name = "UnitTestTextBuilder1";
         abt_rec1.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.txt", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-        abt_rec1.m_platformSpecs.insert("android", AssetInternalSpec::Copy);
+        abt_rec1.m_platformSpecs.insert({"android", AssetInternalSpec::Copy});
         mockAppManager.RegisterAssetRecognizerAsBuilder(abt_rec1);
 
         AssetRecognizer abt_rec2;
         abt_rec2.m_name = "UnitTestTextBuilder2";
         abt_rec2.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.txt", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-        abt_rec2.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
+        abt_rec2.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
         mockAppManager.RegisterAssetRecognizerAsBuilder(abt_rec2);
 
         processResults.clear();
@@ -2242,8 +2242,8 @@ namespace AssetProcessor
         UNIT_TEST_EXPECT_TRUE(processResults[1].m_jobEntry.m_platformInfo.m_identifier == "pc");
         UNIT_TEST_EXPECT_TRUE(QString::compare(processResults[0].m_jobEntry.GetAbsoluteSourcePath(), absolutePath, Qt::CaseInsensitive) == 0);
         UNIT_TEST_EXPECT_TRUE(QString::compare(processResults[1].m_jobEntry.GetAbsoluteSourcePath(), absolutePath, Qt::CaseInsensitive) == 0);
-        UNIT_TEST_EXPECT_TRUE(QString::compare(QString(processResults[0].m_jobEntry.m_jobKey), QString(abt_rec1.m_name)) == 0);
-        UNIT_TEST_EXPECT_TRUE(QString::compare(QString(processResults[1].m_jobEntry.m_jobKey), QString(abt_rec2.m_name)) == 0);
+        UNIT_TEST_EXPECT_TRUE(QString::compare(QString(processResults[0].m_jobEntry.m_jobKey), QString(abt_rec1.m_name.c_str())) == 0);
+        UNIT_TEST_EXPECT_TRUE(QString::compare(QString(processResults[1].m_jobEntry.m_jobKey), QString(abt_rec2.m_name.c_str())) == 0);
         Q_EMIT UnitTestPassed();
 
         // Stop file watching, disconnect everything and process all events so nothing gets called after the method finishes

+ 9 - 5
Code/Tools/AssetProcessor/native/unittests/MockApplicationManager.cpp

@@ -38,6 +38,11 @@ namespace AssetProcessor
             return m_excludeContainer;
         }
 
+        bool AddAssetCacheRecognizerContainer(const RecognizerContainer&) override
+        {
+            return false;
+        }
+
         RecognizerContainer m_container;
         ExcludeRecognizerContainer m_excludeContainer;
     };
@@ -55,7 +60,7 @@ namespace AssetProcessor
     bool InternalMockBuilder::InitializeMockBuilder(const AssetRecognizer& assetRecognizer)
     {
         MockRecognizerConfiguration conf;
-        conf.m_container[QString(assetRecognizer.m_name.data())] = assetRecognizer;
+        conf.m_container[assetRecognizer.m_name] = assetRecognizer;
         return InternalRecognizerBasedBuilder::Initialize(conf);
     }
 
@@ -110,7 +115,7 @@ namespace AssetProcessor
     bool MockApplicationManager::RegisterAssetRecognizerAsBuilder(const AssetProcessor::AssetRecognizer& rec)
     {
         QString newBuilderId = BUILDER_ID_COPY.GetId();
-        QString newBuilderName = rec.m_name;
+        QString newBuilderName = rec.m_name.c_str();
         QHash<QString, BuilderIdAndName> inputBuilderNameByIdMap =
         {
             { newBuilderId, BUILDER_ID_COPY }
@@ -136,15 +141,14 @@ namespace AssetProcessor
         patterns.push_back(rec.m_patternMatcher.GetBuilderPattern());
 
 
-        AZStd::string buildAZName(rec.m_name.toUtf8().data());
+        AZStd::string buildAZName(rec.m_name);
         if (m_internalBuilders.find(buildAZName) != m_internalBuilders.end())
         {
             m_internalBuilders.erase(buildAZName);
         }
         m_internalBuilders[buildAZName] = builder;
 
-        AssetBuilderSDK::AssetBuilderDesc   builderDesc = builder->CreateBuilderDesc(rec.m_name, newBuilderId, patterns);
-
+        AssetBuilderSDK::AssetBuilderDesc   builderDesc = builder->CreateBuilderDesc(rec.m_name.c_str(), newBuilderId, patterns);
 
         AZ::Uuid internalUuid = AZ::Uuid::CreateRandom();
         m_internalBuilderUUIDByName[buildAZName] = internalUuid;

+ 3 - 3
Code/Tools/AssetProcessor/native/unittests/PlatformConfigurationUnitTests.cpp

@@ -86,9 +86,9 @@ void PlatformConfigurationTests::StartTest()
 
         rec.m_name = "txt files";
         rec.m_patternMatcher = AssetBuilderSDK::FilePatternMatcher("*.txt", AssetBuilderSDK::AssetBuilderPattern::Wildcard);
-        rec.m_platformSpecs.insert("pc", AssetInternalSpec::Copy);
-        rec.m_platformSpecs.insert("android", AssetInternalSpec::Copy);
-        rec.m_platformSpecs.insert("fandago", AssetInternalSpec::Copy);
+        rec.m_platformSpecs.insert({"pc", AssetInternalSpec::Copy});
+        rec.m_platformSpecs.insert({"android", AssetInternalSpec::Copy});
+        rec.m_platformSpecs.insert({"fandago", AssetInternalSpec::Copy});
         config.AddRecognizer(rec);
 
         // test dual-recognisers - two recognisers for the same pattern.

+ 1 - 0
Code/Tools/AssetProcessor/native/utilities/ApplicationManager.cpp

@@ -18,6 +18,7 @@
 
 #include <native/resourcecompiler/RCBuilder.h>
 #include <native/utilities/StatsCapture.h>
+#include <native/utilities/PlatformConfiguration.h>
 
 #include <QLocale>
 #include <QTranslator>

+ 1 - 3
Code/Tools/AssetProcessor/native/utilities/ApplicationManagerBase.cpp

@@ -1322,9 +1322,7 @@ void ApplicationManagerBase::ShutDownFileProcessor()
 void ApplicationManagerBase::InitAssetServerHandler()
 {
     m_assetServerHandler = new AssetProcessor::AssetServerHandler();
-    // This will cache whether AP is running in server mode or not.
-    // It is also important to invoke it here because incase the asset server address is invalid, the error message should get captured in the AP log.
-    AssetUtilities::InServerMode();
+    m_assetServerHandler->HandleRemoteConfiguration();
 }
 
 void ApplicationManagerBase::DestroyAssetServerHandler()

+ 163 - 8
Code/Tools/AssetProcessor/native/utilities/AssetServerHandler.cpp

@@ -8,7 +8,9 @@
 
 #include <native/utilities/AssetServerHandler.h>
 #include <native/resourcecompiler/rcjob.h>
+#include <AzCore/Serialization/Json/JsonUtils.h>
 #include <AzToolsFramework/Archive/ArchiveAPI.h>
+#include <AzCore/JSON/pointer.h>
 #include <QDir>
 
 namespace AssetProcessor
@@ -26,10 +28,64 @@ namespace AssetProcessor
         string.append(buffer.c_str());
     }
 
-    QString ComputeArchiveFilePath(const AssetProcessor::BuilderParams& builderParams)
+    AssetServerMode CheckServerMode()
+    {
+        AssetServerMode enableCacheServerMode = AssetServerMode::Inactive;
+
+        auto settingsRegistry = AZ::SettingsRegistry::Get();
+        if (settingsRegistry)
+        {
+            bool enableAssetCacheServerMode = false;
+            AZ::SettingsRegistryInterface::FixedValueString key(AssetProcessor::AssetProcessorSettingsKey);
+            if (settingsRegistry->Get(enableAssetCacheServerMode, key + "/Server/enableCacheServer"))
+            {
+                enableCacheServerMode = enableAssetCacheServerMode ? AssetServerMode::Server : AssetServerMode::Client;
+                AZ_Warning(AssetProcessor::DebugChannel, false, "The 'enableCacheServer' key is deprecated. Please swith to 'assetCacheServerMode'");
+            }
+
+            AZStd::string assetCacheServerModeValue;
+            if (settingsRegistry->Get(assetCacheServerModeValue, key + "/Server/assetCacheServerMode"))
+            {
+                AZStd::to_lower(assetCacheServerModeValue.begin(), assetCacheServerModeValue.end());
+
+                if(assetCacheServerModeValue == "server")
+                {
+                    return AssetServerMode::Server;
+                }
+                else if (assetCacheServerModeValue == "client")
+                {
+                    return AssetServerMode::Client;
+                }
+                else if (assetCacheServerModeValue != "inactive")
+                {
+                    AZ_Warning(AssetProcessor::DebugChannel, false, "Unknown mode for 'assetCacheServerMode' (%s)", assetCacheServerModeValue.c_str());
+                }
+            }
+        }
+
+        return enableCacheServerMode;
+    }
+
+    AZStd::string CheckServerAddress()
+    {
+        auto settingsRegistry = AZ::SettingsRegistry::Get();
+        if (settingsRegistry)
+        {
+            AZStd::string address;
+            if (settingsRegistry->Get(address,
+                AZ::SettingsRegistryInterface::FixedValueString(AssetProcessor::AssetProcessorSettingsKey) + "/Server/cacheServerAddress"))
+            {
+                AZ_TracePrintf(AssetProcessor::DebugChannel, "Server Address: %s\n", address.c_str());
+                return AZStd::move(address);
+            }
+        }
+        return {};
+    }
+
+    QString AssetServerHandler::ComputeArchiveFilePath(const AssetProcessor::BuilderParams& builderParams)
     {
         QFileInfo fileInfo(builderParams.m_processJobRequest.m_sourceFile.c_str());
-        QString assetServerAddress = QDir::toNativeSeparators(AssetUtilities::ServerAddress());
+        QString assetServerAddress = QDir::toNativeSeparators(QString{m_serverAddress.c_str()});
         if (!assetServerAddress.isEmpty())
         {
             QString archiveFileName = builderParams.GetServerKey() + ".zip";
@@ -60,21 +116,120 @@ namespace AssetProcessor
 
     AssetServerHandler::AssetServerHandler()
     {
+        SetServerAddress(CheckServerAddress());
+        SetRemoteCachingMode(CheckServerMode());
         AssetServerBus::Handler::BusConnect();
     }
 
     AssetServerHandler::~AssetServerHandler()
     {
+        SetRemoteCachingMode(AssetServerMode::Inactive);
         AssetServerBus::Handler::BusDisconnect();
     }
 
     bool AssetServerHandler::IsServerAddressValid()
     {
-        QString address = AssetUtilities::ServerAddress();
+        QString address{m_serverAddress.c_str()};
         bool isValid = !address.isEmpty() && QDir(address).exists();
         return isValid;
     }
 
+    void AssetServerHandler::HandleRemoteConfiguration()
+    {
+        if (m_assetCachingMode == AssetServerMode::Inactive || !IsServerAddressValid())
+        {
+            return;
+        }
+        AZ::IO::Path settingsFilePath{ m_serverAddress };
+        settingsFilePath /= "settings.json";
+
+        auto* recognizerConfiguration = AZ::Interface<AssetProcessor::RecognizerConfiguration>::Get();
+        if (!recognizerConfiguration)
+        {
+            return;
+        }
+
+        if (m_assetCachingMode == AssetServerMode::Server)
+        {
+            AZStd::string jsonBuffer;
+            const auto& assetCacheRecognizerContainer = recognizerConfiguration->GetAssetCacheRecognizerContainer();
+            AssetProcessor::PlatformConfiguration::ConvertToJson(assetCacheRecognizerContainer, jsonBuffer);
+            if (jsonBuffer.empty())
+            {
+                // no configuration to save
+                return;
+            }
+
+            // save the configuration
+            rapidjson::Document recognizerDoc;
+            recognizerDoc.Parse(jsonBuffer.c_str());
+            AZ::JsonSerializationUtils::WriteJsonFile(recognizerDoc, settingsFilePath.LexicallyNormal().c_str());
+        }
+        else if (m_assetCachingMode == AssetServerMode::Client)
+        {
+            // load the configuration
+            if (!AZ::IO::SystemFile::Exists(settingsFilePath.c_str()))
+            {
+                // no log since it is okay to not have a settings file
+                return;
+            }
+
+            auto result = AZ::JsonSerializationUtils::ReadJsonFile(settingsFilePath.LexicallyNormal().c_str());
+            if (!result.IsSuccess())
+            {
+                AZ_Warning(AssetProcessor::DebugChannel, false, "ACS settings file failed with (%s)", result.GetError().c_str());
+                return;
+            }
+
+            rapidjson::StringBuffer stringBuffer;
+            rapidjson::Writer<rapidjson::StringBuffer> writer(stringBuffer);
+            if (result.GetValue().Accept(writer) == false)
+            {
+                AZ_Warning(AssetProcessor::DebugChannel, false, "ACS failed to load settings file (%s)", settingsFilePath.c_str());
+                return;
+            }
+
+            RecognizerContainer recognizerContainer;
+            if (!AssetProcessor::PlatformConfiguration::ConvertFromJson(stringBuffer.GetString(), recognizerContainer))
+            {
+                AZ_Warning(AssetProcessor::DebugChannel, false, "ACS failed to convert settings file (%s)", settingsFilePath.c_str());
+                return;
+            }
+
+            recognizerConfiguration->AddAssetCacheRecognizerContainer(recognizerContainer);
+        }
+    }
+
+    AssetServerMode AssetServerHandler::GetRemoteCachingMode() const
+    {
+        return m_assetCachingMode;
+    }
+
+    void AssetServerHandler::SetRemoteCachingMode(AssetServerMode mode)
+    {
+        m_assetCachingMode = mode;
+        AssetServerNotificationBus::Broadcast(&AssetServerNotificationBus::Events::OnRemoteCachingModeChanged, mode);
+    }
+
+    const AZStd::string& AssetServerHandler::GetServerAddress() const
+    {
+        return m_serverAddress;
+    }
+
+    void AssetServerHandler::SetServerAddress(const AZStd::string& address)
+    {
+        AZStd::string previousServerAddress = m_serverAddress;
+        m_serverAddress = address;
+        if (!IsServerAddressValid())
+        {
+            m_serverAddress = previousServerAddress;
+            AZ_Error(AssetProcessor::DebugChannel, false,
+                "Server address (%.*s) is invalid! Reverting back to (%.*s)",
+                AZ_STRING_ARG(address),
+                AZ_STRING_ARG(previousServerAddress));
+        }
+    }
+
     bool AssetServerHandler::RetrieveJobResult(const AssetProcessor::BuilderParams& builderParams)
     {
         AssetBuilderSDK::JobCancelListener jobCancelListener(builderParams.m_rcJob->GetJobEntry().m_jobRunKey);
@@ -84,20 +239,20 @@ namespace AssetProcessor
         QString archiveAbsFilePath = ComputeArchiveFilePath(builderParams);
         if (archiveAbsFilePath.isEmpty())
         {
-            AZ_Error(AssetProcessor::DebugChannel, false, "Extracting archive operation failed. Archive Absolute Path is empty. \n");
+            AZ_Error(AssetProcessor::DebugChannel, false, "Extracting archive operation failed. Archive Absolute Path is empty.");
             return false;
         }
 
         if (!QFile::exists(archiveAbsFilePath))
         {
             // file does not exist on the server 
-            AZ_TracePrintf(AssetProcessor::DebugChannel, "Extracting archive operation cancelled. Archive does not exist on server. \n");
+            AZ_TracePrintf(AssetProcessor::DebugChannel, "Extracting archive operation canceled. Archive does not exist on server. \n");
             return false;
         }
 
         if (listener.WasQuitRequested() || jobCancelListener.IsCancelled())
         {
-            AZ_TracePrintf(AssetProcessor::DebugChannel, "Extracting archive operation cancelled. \n");
+            AZ_TracePrintf(AssetProcessor::DebugChannel, "Extracting archive operation canceled. \n");
             return false;
         }
         AZ_TracePrintf(AssetProcessor::DebugChannel, "Extracting archive for job (%s, %s, %s) with fingerprint (%u).\n",
@@ -128,13 +283,13 @@ namespace AssetProcessor
         if (QFile::exists(archiveAbsFilePath))
         {
             // file already exists on the server 
-            AZ_TracePrintf(AssetProcessor::DebugChannel, "Creating archive operation cancelled. An archive of this asset already exists on server. \n");
+            AZ_TracePrintf(AssetProcessor::DebugChannel, "Creating archive operation canceled. An archive of this asset already exists on server. \n");
             return true;
         }
         
         if (listener.WasQuitRequested() || jobCancelListener.IsCancelled())
         {
-            AZ_TracePrintf(AssetProcessor::DebugChannel, "Creating archive operation cancelled. \n");
+            AZ_TracePrintf(AssetProcessor::DebugChannel, "Creating archive operation canceled. \n");
             return false;
         }
 

+ 14 - 1
Code/Tools/AssetProcessor/native/utilities/AssetServerHandler.h

@@ -28,11 +28,24 @@ namespace AssetProcessor
         bool StoreJobResult(const AssetProcessor::BuilderParams& builderParams, AZStd::vector<AZStd::string>& sourceFileList)  override;
         //! RetrieveJobResult will retrieve the zip file from the network share associated with the server key and unzip it to the temporary directory provided by AP.
         bool RetrieveJobResult(const AssetProcessor::BuilderParams& builderParams) override;
+        //! HandleRemoteConfiguration will attempt to set or get the remote configuration for the cache server
+        void HandleRemoteConfiguration();
+        //! Retrieve the current mode for shared caching
+        AssetServerMode GetRemoteCachingMode() const override;
+        //! Store the shared caching mode
+        void SetRemoteCachingMode(AssetServerMode mode) override;
+        //! Retrieve the remote folder location for the shared cache 
+        const AZStd::string& GetServerAddress() const override;
+        //! Store the remote folder location for the shared cache 
+        void SetServerAddress(const AZStd::string& address) override;
     protected:
         //! Source files intended to be copied into the cache don't go through out temp folder so they need
         //! to be added to the Archive in an additional step
         bool AddSourceFilesToArchive(const AssetProcessor::BuilderParams& builderParams, const QString& archivePath, AZStd::vector<AZStd::string>& sourceFileList);
+        QString ComputeArchiveFilePath(const AssetProcessor::BuilderParams& builderParams);
         
-        //////////////////////////////////////////////////////////////////////////
+    private:
+        AssetServerMode m_assetCachingMode = AssetServerMode::Inactive;
+        AZStd::string m_serverAddress;
     };
 } //namespace AssetProcessor

+ 29 - 1
Code/Tools/AssetProcessor/native/utilities/AssetUtilEBusHelper.h

@@ -220,6 +220,13 @@ namespace AssetProcessor
         virtual bool CheckSufficientDiskSpace(qint64 /*requiredSpace*/, bool /*shutdownIfInsufficient*/) { return true; }
     };
 
+    //! Defines the modes the Asset Cache Server mode setting for the Asset Processor (AP).
+    enum class AssetServerMode
+    {
+        Inactive, //! This mode means the AP is offline; only processing the assets locally
+        Server, //! This mode means the AP is writing out the asset products to a remote location
+        Client //! This mode means the AP is attempting to retrieve asset products from a remote location
+    };
     // This EBUS is used to perform Asset Server related tasks.
     class AssetServerBusTraits
         : public AZ::EBusTraits
@@ -242,10 +249,31 @@ namespace AssetProcessor
         //! and put them in the temporary directory provided by the builderParam.
         //! This will return true if it was able to retrieve all the relevant job data from the server, otherwise return false.
         virtual bool RetrieveJobResult(const AssetProcessor::BuilderParams& builderParams) = 0;
+        //! Retrieve the current mode for shared caching
+        virtual AssetServerMode GetRemoteCachingMode() const = 0;
+        //! Store the shared caching mode
+        virtual void SetRemoteCachingMode(AssetServerMode mode) = 0;
+        //! Retrieve the remote folder location for the shared cache 
+        virtual const AZStd::string& GetServerAddress() const = 0;
+        //! Store the remote folder location for the shared cache 
+        virtual void SetServerAddress(const AZStd::string& address) = 0;
     };
-
     using AssetServerBus = AZ::EBus<AssetServerBusTraits>;
 
+    // This EBUS has notify listeners when Asset Server state(s) changes.
+    class AssetServerNotifications
+        : public AZ::EBusTraits
+    {
+    public:
+        static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; // multi listener
+        static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; //single bus
+        typedef AZStd::recursive_mutex MutexType;
+
+        //! This emits when the mode of the Asset Server Cache mode has changed.
+        virtual void OnRemoteCachingModeChanged([[maybe_unused]] AssetServerMode mode) {}
+    };
+    using AssetServerNotificationBus = AZ::EBus<AssetServerNotifications>;
+
     // This EBUS is used to retrieve asset server information
     class AssetServerInfoBusTraits
         : public AZ::EBusTraits

+ 2 - 0
Code/Tools/AssetProcessor/native/utilities/GUIApplicationManager.cpp

@@ -12,6 +12,7 @@
 #include "native/resourcecompiler/rccontroller.h"
 #include "native/FileServer/fileServer.h"
 #include "native/AssetManager/assetScanner.h"
+#include <native/utilities/PlatformConfiguration.h>
 
 #include <QApplication>
 #include <QDialogButtonBox>
@@ -750,6 +751,7 @@ void GUIApplicationManager::Reflect()
     EBUS_EVENT_RESULT(context, AZ::ComponentApplicationBus, GetSerializeContext);
     AZ_Assert(context, "No serialize context");
     AzToolsFramework::LogPanel::BaseLogPanel::Reflect(context);
+    AssetProcessor::PlatformConfiguration::Reflect(context);
 }
 
 const char* GUIApplicationManager::GetLogBaseName()

+ 166 - 35
Code/Tools/AssetProcessor/native/utilities/PlatformConfiguration.cpp

@@ -10,13 +10,17 @@
 
 #include <QDirIterator>
 
+#include <AzCore/Component/ComponentApplicationBus.h>
 #include <AzCore/Settings/SettingsRegistryMergeUtils.h>
 #include <AzCore/Settings/SettingsRegistryVisitorUtils.h>
+#include <AzCore/Serialization/Json/JsonUtils.h>
 #include <AzCore/Utils/Utils.h>
 #include <AzFramework/API/ApplicationAPI.h>
 #include <AzFramework/Gem/GemInfo.h>
 #include <AzToolsFramework/Asset/AssetUtils.h>
 
+#include <AzCore/Serialization/SerializeContext.h>
+
 namespace
 {
     // the starting order in the file for gems.
@@ -385,7 +389,7 @@ namespace AssetProcessor
                 m_simpleJobNameStack.push(rcName);
 
                 auto& assetRecognizer = m_assetRecognizers.emplace_back();
-                assetRecognizer.m_recognizer.m_name = QString::fromUtf8(rcName.c_str(), aznumeric_cast<int>(rcName.size()));
+                assetRecognizer.m_recognizer.m_name = rcName;
             }
         }
         break;
@@ -416,14 +420,13 @@ namespace AssetProcessor
         }
 
         AZStd::string_view sjNameView = m_simpleJobNameStack.top();
-        auto sjName = QString::fromUtf8(sjNameView.data(), aznumeric_cast<int>(sjNameView.size()));
 
         // Find AssetRecognizer identified by the top entry in the name stack
         auto assetRecognizerEntryIt = AZStd::find_if(m_assetRecognizers.rbegin(), m_assetRecognizers.rend(),
-            [&sjName](const SimpleJobAssetRecognizer& assetRecognizer)
-            {
-                return assetRecognizer.m_recognizer.m_name == sjName;
-            });
+            [&sjNameView](const auto& assetRecognizer)
+        {
+            return assetRecognizer.m_recognizer.m_name == sjNameView;
+        });
         if (assetRecognizerEntryIt == m_assetRecognizers.rend())
         {
             return;
@@ -464,13 +467,12 @@ namespace AssetProcessor
         }
 
         AZStd::string_view sjNameView = m_simpleJobNameStack.top();
-        auto sjName = QString::fromUtf8(sjNameView.data(), aznumeric_cast<int>(sjNameView.size()));
 
         // Find AssetRecognizer identified by the top entry in the name stack
         auto assetRecognizerEntryIt = AZStd::find_if(m_assetRecognizers.rbegin(), m_assetRecognizers.rend(),
-            [&sjName](const SimpleJobAssetRecognizer& assetRecognizer)
+            [&sjNameView](const auto& assetRecognizer)
             {
-                return assetRecognizer.m_recognizer.m_name == sjName;
+            return assetRecognizer.m_recognizer.m_name == sjNameView;
             });
         if (assetRecognizerEntryIt == m_assetRecognizers.rend())
         {
@@ -492,13 +494,13 @@ namespace AssetProcessor
         }
 
         AZStd::string_view sjNameView = m_simpleJobNameStack.top();
-        auto sjName = QString::fromUtf8(sjNameView.data(), aznumeric_cast<int>(sjNameView.size()));
+        
 
         // Find AssetRecognizer identified by the top entry in the name stack
         auto assetRecognizerEntryIt = AZStd::find_if(m_assetRecognizers.rbegin(), m_assetRecognizers.rend(),
-            [&sjName](const SimpleJobAssetRecognizer& assetRecognizer)
+            [&sjNameView](const SimpleJobAssetRecognizer& assetRecognizer)
             {
-                return assetRecognizer.m_recognizer.m_name == sjName;
+                return assetRecognizer.m_recognizer.m_name == sjNameView;
             });
         if (assetRecognizerEntryIt == m_assetRecognizers.rend())
         {
@@ -554,7 +556,7 @@ namespace AssetProcessor
         }
         else if (valueName == "version")
         {
-            assetRecognizer.m_recognizer.m_version = QString::fromUtf8(value.data(), aznumeric_cast<int>(value.size()));
+            assetRecognizer.m_recognizer.m_version = value;
         }
         else if (valueName == "productAssetType")
         {
@@ -581,13 +583,13 @@ namespace AssetProcessor
         }
 
         AZStd::string_view sjNameView = m_simpleJobNameStack.top();
-        auto sjName = QString::fromUtf8(sjNameView.data(), aznumeric_cast<int>(sjNameView.size()));
+
 
         // Find AssetRecognizer identified by the top entry in the name stack
         auto assetRecognizerEntryIt = AZStd::find_if(m_assetRecognizers.rbegin(), m_assetRecognizers.rend(),
-            [&sjName](const SimpleJobAssetRecognizer& assetRecognizer)
+            [&sjNameView](const SimpleJobAssetRecognizer& assetRecognizer)
         {
-            return assetRecognizer.m_recognizer.m_name == sjName;
+            return assetRecognizer.m_recognizer.m_name == sjNameView;
         });
         if (assetRecognizerEntryIt == m_assetRecognizers.rend())
         {
@@ -668,9 +670,7 @@ namespace AssetProcessor
             // now generate a platform spec as long as we're not skipping
             if (!AZ::StringFunc::Equal(currentParams, "skip"))
             {
-                auto platformIdentifier = QString::fromUtf8(platform.m_identifier.data(),
-                    aznumeric_cast<int>(platform.m_identifier.size()));
-                assetRecognizer.m_recognizer.m_platformSpecs[platformIdentifier] = AssetInternalSpec::Copy;
+                assetRecognizer.m_recognizer.m_platformSpecs[platform.m_identifier] = AssetInternalSpec::Copy;
             }
         }
     }
@@ -683,13 +683,12 @@ namespace AssetProcessor
             return nullptr;
         }
 
-        AZStd::string_view nameView = m_nameStack.top();
-        auto rcName = QString::fromUtf8(nameView.data(), aznumeric_cast<int>(nameView.size()));
+        auto& nameView = m_nameStack.top();
 
         auto assetRecognizerEntryIt = AZStd::find_if(m_assetRecognizers.rbegin(), m_assetRecognizers.rend(),
-            [&rcName](const AssetRecognizer& assetRecognizer)
+            [&nameView](const AssetRecognizer& assetRecognizer)
             {
-                return assetRecognizer.m_name == rcName;
+                return assetRecognizer.m_name == nameView;
             });
         if (assetRecognizerEntryIt == m_assetRecognizers.rend())
         {
@@ -717,7 +716,7 @@ namespace AssetProcessor
                 m_nameStack.push(name);
 
                 AssetRecognizer& assetRecognizer = m_assetRecognizers.emplace_back();
-                assetRecognizer.m_name = QString::fromUtf8(name.c_str(), aznumeric_cast<int>(name.size()));
+                assetRecognizer.m_name = name;
             }
         }
         break;
@@ -835,7 +834,7 @@ namespace AssetProcessor
         }
         else if (valueName == "version")
         {
-            assetRecognizer->m_version = QString::fromUtf8(value.data(), aznumeric_cast<int>(value.size()));
+            assetRecognizer->m_version = value;
         }
         else if (valueName == "productAssetType")
         {
@@ -1231,6 +1230,133 @@ namespace AssetProcessor
         return AZStd::nullopt;
     }
 
+    // used to save our the AssetCacheServer settings to a remote location
+    struct AssetCacheServerMatcher
+    {
+        AZ_CLASS_ALLOCATOR(AssetCacheServerMatcher, AZ::SystemAllocator, 0);
+        AZ_TYPE_INFO(AssetCacheServerMatcher, "{329A59C9-755E-4FA9-AADB-05C50AC62FD5}");
+
+        AZStd::string m_name;
+        AZStd::string m_glob;
+        AZStd::string m_pattern;
+        AZ::Uuid m_productAssetType = AZ::Uuid::CreateNull();
+        bool m_checkServer = false;
+    };
+
+    bool PlatformConfiguration::ConvertToJson(const RecognizerContainer& recognizerContainer, AZStd::string& jsonText)
+    {
+        AZ::JsonSerializerSettings settings;
+        AZ::ComponentApplicationBus::BroadcastResult(settings.m_serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
+        settings.m_registrationContext = nullptr;
+
+        AZStd::unordered_map<AZStd::string, AssetCacheServerMatcher> assetCacheServerMatcherMap;
+        
+        for (const auto& recognizer : recognizerContainer)
+        {
+            AssetCacheServerMatcher matcher;
+            matcher.m_name = recognizer.first;
+            matcher.m_checkServer = recognizer.second.m_checkServer;
+            matcher.m_productAssetType = recognizer.second.m_productAssetType;
+
+            if (recognizer.second.m_patternMatcher.GetBuilderPattern().m_type == AssetBuilderSDK::AssetBuilderPattern::Wildcard)
+            {
+                matcher.m_glob = recognizer.second.m_patternMatcher.GetBuilderPattern().m_pattern;
+            }
+            else if (recognizer.second.m_patternMatcher.GetBuilderPattern().m_type == AssetBuilderSDK::AssetBuilderPattern::Regex)
+            {
+                matcher.m_pattern = recognizer.second.m_patternMatcher.GetBuilderPattern().m_pattern;
+            }
+            assetCacheServerMatcherMap.insert({"ACS " + recognizer.first, matcher});
+        }
+
+        rapidjson::Document jsonDocument;
+        auto jsonResult = AZ::JsonSerialization::Store(jsonDocument, jsonDocument.GetAllocator(), assetCacheServerMatcherMap, settings);
+        if (jsonResult.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted)
+        {
+            return false;
+        }
+
+        auto saveToFileOutcome = AZ::JsonSerializationUtils::WriteJsonString(jsonDocument, jsonText);
+        return saveToFileOutcome.IsSuccess();
+    }
+
+    bool PlatformConfiguration::ConvertFromJson(const AZStd::string& jsonText, RecognizerContainer& recognizerContainer)
+    {
+        rapidjson::Document assetCacheServerMatcherDoc;
+        assetCacheServerMatcherDoc.Parse(jsonText.c_str());
+        if (assetCacheServerMatcherDoc.HasParseError())
+        {
+            return false;
+        }
+
+        AZ::JsonSerializerSettings settings;
+        AZ::ComponentApplicationBus::BroadcastResult(settings.m_serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
+        settings.m_registrationContext = nullptr;
+
+        AZStd::unordered_map<AZStd::string, AssetCacheServerMatcher> assetCacheServerMatcherMap;
+        auto resultCode = AZ::JsonSerialization::Load(assetCacheServerMatcherMap, assetCacheServerMatcherDoc, {});        
+        if (!resultCode.HasDoneWork())
+        {
+            return false;
+        }
+
+        recognizerContainer.clear();
+        for (const auto& matcher : assetCacheServerMatcherMap)
+        {
+            AssetRecognizer assetRecognizer;
+            assetRecognizer.m_checkServer = matcher.second.m_checkServer;
+            assetRecognizer.m_name = matcher.second.m_name;
+            assetRecognizer.m_productAssetType = matcher.second.m_productAssetType;
+
+            if (!matcher.second.m_glob.empty())
+            {
+                assetRecognizer.m_patternMatcher = { matcher.second.m_glob , AssetBuilderSDK::AssetBuilderPattern::Wildcard };
+            }
+            else if (!matcher.second.m_pattern.empty())
+            {
+                assetRecognizer.m_patternMatcher = { matcher.second.m_pattern , AssetBuilderSDK::AssetBuilderPattern::Regex };
+            }
+            recognizerContainer.insert({ "ACS " + assetRecognizer.m_name, assetRecognizer });
+        }
+
+        return !recognizerContainer.empty();
+    }
+
+    void PlatformConfiguration::Reflect(AZ::ReflectContext* context)
+    {
+        if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serializeContext->Class<AssetBuilderSDK::FilePatternMatcher>()->Version(0);
+
+            serializeContext->Class<AssetInternalSpec>()->Version(0);                
+
+            // needs to serialize in/out 'glob' and 'pattern'
+            serializeContext->Class<AssetRecognizer>()->Version(0)
+                ->Field("checkServer", &AssetRecognizer::m_checkServer)
+                ->Field("isCritical", &AssetRecognizer::m_isCritical)
+                ->Field("name", &AssetRecognizer::m_name)
+                ->Field("outputProductDependencies", &AssetRecognizer::m_outputProductDependencies)
+                ->Field("patternMatcher", &AssetRecognizer::m_patternMatcher)
+                ->Field("platformSpecs", &AssetRecognizer::m_platformSpecs)
+                ->Field("priority", &AssetRecognizer::m_priority)
+                ->Field("productAssetType", &AssetRecognizer::m_productAssetType)
+                ->Field("supportsCreateJobs", &AssetRecognizer::m_supportsCreateJobs)
+                ->Field("testLockSource", &AssetRecognizer::m_testLockSource)
+                ->Field("version", &AssetRecognizer::m_version);
+
+            serializeContext->Class<AssetCacheServerMatcher>()->Version(0)
+                ->Field("name", &AssetCacheServerMatcher::m_name)
+                ->Field("glob", &AssetCacheServerMatcher::m_glob)
+                ->Field("pattern", &AssetCacheServerMatcher::m_pattern)
+                ->Field("productAssetType", &AssetCacheServerMatcher::m_productAssetType)
+                ->Field("checkServer", &AssetCacheServerMatcher::m_checkServer);
+
+            serializeContext->RegisterGenericType<AZStd::unordered_map<AZStd::string, AssetRecognizer>>();
+            serializeContext->RegisterGenericType<AZStd::unordered_map<AZStd::string, AssetInternalSpec>>();
+            serializeContext->RegisterGenericType<AZStd::unordered_map<AZStd::string, AssetCacheServerMatcher>>();
+        }
+    }
+
     bool PlatformConfiguration::ReadRecognizersFromSettingsRegistry(const QString& assetRoot, bool skipScanFolders, QStringList scanFolderPatterns)
     {
         auto settingsRegistry = AZ::SettingsRegistry::Get();
@@ -1380,15 +1506,11 @@ namespace AssetProcessor
 
         SimpleJobVisitor simpleJobVisitor(*settingsRegistry, m_enabledPlatforms);
         settingsRegistry->Visit(simpleJobVisitor, AssetProcessorSettingsKey);
-        for (auto&& simpleJobRecognizer : simpleJobVisitor.m_assetRecognizers)
+        for (auto&& sjRecognizer : simpleJobVisitor.m_assetRecognizers)
         {
-            if (simpleJobRecognizer.m_ignore)
+            if (!sjRecognizer.m_recognizer.m_platformSpecs.empty() && !sjRecognizer.m_ignore)
             {
-                m_assetRecognizers.remove(simpleJobRecognizer.m_recognizer.m_name);
-            }
-            else if (!simpleJobRecognizer.m_recognizer.m_platformSpecs.empty())
-            {
-                m_assetRecognizers[simpleJobRecognizer.m_recognizer.m_name] = simpleJobRecognizer.m_recognizer;
+                m_assetRecognizers[sjRecognizer.m_recognizer.m_name] = AZStd::move(sjRecognizer.m_recognizer);
             }
         }
 
@@ -1527,8 +1649,9 @@ namespace AssetProcessor
             //if the file is excluded than return false;
             return false;
         }
-        for (const AssetRecognizer& recognizer : m_assetRecognizers)
+        for (const auto& assetRecognizer : m_assetRecognizers)
         {
+            const AssetRecognizer& recognizer = assetRecognizer.second;
             if (recognizer.m_patternMatcher.MatchesPath(fileName.toUtf8().constData()))
             {
                 // found a match
@@ -1593,12 +1716,12 @@ namespace AssetProcessor
 
     void PlatformConfiguration::AddRecognizer(const AssetRecognizer& source)
     {
-        m_assetRecognizers.insert(source.m_name, source);
+        m_assetRecognizers.insert({source.m_name, source});
     }
 
     void PlatformConfiguration::RemoveRecognizer(QString name)
     {
-        auto found = m_assetRecognizers.find(name);
+        auto found = m_assetRecognizers.find(name.toUtf8().data());
         m_assetRecognizers.erase(found);
     }
 
@@ -2006,6 +2129,14 @@ namespace AssetProcessor
         return m_excludeAssetRecognizers;
     }
 
+    bool PlatformConfiguration::AddAssetCacheRecognizerContainer(const RecognizerContainer& recognizerContainer)
+    {
+        m_assetCacheServerRecognizers.insert(recognizerContainer.begin(), recognizerContainer.end());
+        return true;
+    }
+
+    // AssetProcessor
+
     void AssetProcessor::PlatformConfiguration::AddExcludeRecognizer(const ExcludeAssetRecognizer& recogniser)
     {
         m_excludeAssetRecognizers.insert(recogniser.m_name, recogniser);

+ 28 - 7
Code/Tools/AssetProcessor/native/utilities/PlatformConfiguration.h

@@ -68,11 +68,22 @@ namespace AssetProcessor
     //! essentially a plain data holder, but with helper funcs
     struct AssetRecognizer
     {
+        AZ_CLASS_ALLOCATOR(AssetRecognizer, AZ::SystemAllocator, 0);
+        AZ_TYPE_INFO(AssetRecognizer, "{29B7A73A-4D7F-4C19-AEAC-6D6750FB1156}");
+
         AssetRecognizer() = default;
 
-        AssetRecognizer(const QString& name, bool testLockSource, int priority,
-            bool critical, bool supportsCreateJobs, AssetBuilderSDK::FilePatternMatcher patternMatcher,
-            const QString& version, const AZ::Data::AssetType& productAssetType, bool outputProductDependencies, bool checkServer = false)
+        AssetRecognizer(
+            const AZStd::string& name,
+            bool testLockSource,
+            int priority,
+            bool critical,
+            bool supportsCreateJobs,
+            AssetBuilderSDK::FilePatternMatcher patternMatcher, 
+            const AZStd::string& version,
+            const AZ::Data::AssetType& productAssetType,
+            bool outputProductDependencies,
+            bool checkServer = false)
             : m_name(name)
             , m_testLockSource(testLockSource)
             , m_priority(priority)
@@ -85,13 +96,13 @@ namespace AssetProcessor
             , m_checkServer(checkServer)
         {}
 
-        QString m_name;
+        AZStd::string m_name;
         AssetBuilderSDK::FilePatternMatcher  m_patternMatcher;
-        QString m_version = QString();
+        AZStd::string m_version = {};
 
         // the QString is the Platform Identifier ("pc")
         // the AssetInternalSpec specifies the type of internal job to process
-        QHash<QString, AssetInternalSpec> m_platformSpecs;
+        AZStd::unordered_map<AZStd::string, AssetInternalSpec> m_platformSpecs;
 
         // an optional parameter which is a UUID of types to assign to the output asset(s)
         // if you don't specify one, then a heuristic will be used
@@ -105,7 +116,7 @@ namespace AssetProcessor
         bool m_outputProductDependencies = false;
     };
     //! Dictionary of Asset Recognizers based on name
-    typedef QHash<QString, AssetRecognizer> RecognizerContainer;
+    typedef AZStd::unordered_map<AZStd::string, AssetRecognizer> RecognizerContainer;
     typedef QList<const AssetRecognizer*> RecognizerPointerContainer;
 
     //! The structure holds information about a particular exclude recognizer
@@ -119,9 +130,12 @@ namespace AssetProcessor
     //! Interface to get constant references to asset and exclude recognizers
     struct RecognizerConfiguration
     {
+        AZ_RTTI(RecognizerConfiguration, "{2E4DD73E-8D1E-42BC-A3E3-1A671D636DAC}");
+
         virtual const RecognizerContainer& GetAssetRecognizerContainer() const = 0;
         virtual const RecognizerContainer& GetAssetCacheRecognizerContainer() const = 0;
         virtual const ExcludeRecognizerContainer& GetExcludeAssetRecognizerContainer() const = 0;
+        virtual bool AddAssetCacheRecognizerContainer(const RecognizerContainer& recognizerContainer) = 0;
     };
 
     //! Visitor for reading the "/Amazon/AssetProcessor/Settings/ScanFolder *" entries from the Settings Registry
@@ -231,6 +245,8 @@ namespace AssetProcessor
         explicit PlatformConfiguration(QObject* pParent = nullptr);
         virtual ~PlatformConfiguration() = default;
 
+        static void Reflect(AZ::ReflectContext* context);
+
         /** Use this function to parse the set of config files and the gem file to set up the platform config.
         * This should be about the only function that is required to be called in order to end up with
         * a full configuration.
@@ -358,6 +374,11 @@ namespace AssetProcessor
 
         const ExcludeRecognizerContainer& GetExcludeAssetRecognizerContainer() const override;
 
+        bool AddAssetCacheRecognizerContainer(const RecognizerContainer& recognizerContainer) override;
+
+        static bool ConvertToJson(const RecognizerContainer& recognizerContainer, AZStd::string& jsonText);
+        static bool ConvertFromJson(const AZStd::string& jsonText, RecognizerContainer& recognizerContainer);
+
         /** returns true if the config is valid.
         * configs are considered invalid if critical information is missing.
         * for example, if no recognizers are given, or no platforms are enabled.

+ 2 - 117
Code/Tools/AssetProcessor/native/utilities/assetUtils.cpp

@@ -232,12 +232,10 @@ namespace AssetUtilities
     AZ::SettingsRegistryInterface::FixedValueString s_projectPath;
     AZ::SettingsRegistryInterface::FixedValueString s_projectName;
     AZ::SettingsRegistryInterface::FixedValueString s_assetRoot;
-    AZ::SettingsRegistryInterface::FixedValueString s_assetServerAddress;
     AZ::SettingsRegistryInterface::FixedValueString s_cachedEngineRoot;
     int s_truncateFingerprintTimestampPrecision{ 1 };
     AZStd::optional<bool> s_fileHashOverride{};
     AZStd::optional<bool> s_fileHashSetting{};
-    AZStd::optional<bool> s_serverMode{};
 
     void SetTruncateFingerprintTimestamp(int precision)
     {
@@ -550,120 +548,6 @@ namespace AssetUtilities
         return QString::fromUtf8(s_projectPath.c_str(), aznumeric_cast<int>(s_projectPath.size()));
     }
 
-    bool InServerMode()
-    {
-        if (s_serverMode.has_value())
-        {
-            return s_serverMode.value();
-        }
-        s_serverMode = AZStd::make_optional<bool>(CheckServerMode());
-        return s_serverMode.value();
-    }
-
-    void ResetServerMode()
-    {
-        if (s_serverMode.has_value())
-        {
-            s_serverMode.reset();
-        }
-    }
-
-    bool CheckServerMode()
-    {
-        bool inServerMode = false;
-        if (QCoreApplication::instance())
-        {
-            QStringList args = QCoreApplication::arguments();
-            for (const QString& arg : args)
-            {
-                if (arg.contains("/server", Qt::CaseInsensitive) || arg.contains("--server", Qt::CaseInsensitive))
-                {
-                    inServerMode = true;
-                    break;
-                }
-            }
-        }
-
-        if (!inServerMode)
-        {
-            auto settingsRegistry = AZ::SettingsRegistry::Get();
-            if (settingsRegistry)
-            {
-                bool enableAssetCacheServerMode = false;
-                AZ::SettingsRegistryInterface::FixedValueString key(AssetProcessor::AssetProcessorSettingsKey);
-                if (settingsRegistry->Get(enableAssetCacheServerMode, key + "/Server/enableCacheServer"))
-                {
-                    inServerMode = enableAssetCacheServerMode;
-                }
-            }
-        }
-
-        if (inServerMode)
-        {
-            bool isServerAddressValid = false;
-            AssetProcessor::AssetServerBus::BroadcastResult(isServerAddressValid, &AssetProcessor::AssetServerBusTraits::IsServerAddressValid);
-            if (isServerAddressValid)
-            {
-                AZ_TracePrintf(AssetProcessor::ConsoleChannel, "Asset Processor is running in server mode.\n");
-                return true;
-            }
-            else
-            {
-                AZ_Warning(AssetProcessor::ConsoleChannel, false,
-                    "Invalid server address, please check the AssetProcessorPlatformConfig.setreg file"
-                    " to ensure that the address is correct. Asset Processor won't be running in server mode.");
-            }
-        }
-        return false;
-    }
-
-    void ResetServerAddress()
-    {
-        s_assetServerAddress.clear();
-    }
-
-    QString ServerAddress()
-    {
-        if (!s_assetServerAddress.empty())
-        {
-            return QString::fromUtf8(s_assetServerAddress.data(), aznumeric_cast<int>(s_assetServerAddress.size()));
-        }
-        // QCoreApplication is not created during unit test mode and that can cause QtWarning to get emitted
-        // since we need to retrieve arguments from Qt
-        if (QCoreApplication::instance())
-        {
-            // if its been specified on the command line, then ignore AssetProcessorPlatformConfig:
-            QStringList args = QCoreApplication::arguments();
-            for (QString arg : args)
-            {
-                if (arg.contains("/serverAddress=", Qt::CaseInsensitive) || arg.contains("--serverAddress=", Qt::CaseInsensitive))
-                {
-                    QString serverAddress = arg.split("=")[1].trimmed();
-                    if (!serverAddress.isEmpty())
-                    {
-                        s_assetServerAddress = serverAddress.toUtf8().constData();
-                        return QString::fromUtf8(s_assetServerAddress.data(), aznumeric_cast<int>(s_assetServerAddress.size()));
-                    }
-                }
-            }
-        }
-
-        auto settingsRegistry = AZ::SettingsRegistry::Get();
-        if (settingsRegistry)
-        {
-            AZStd::string address;
-            if (settingsRegistry->Get(address, AZ::SettingsRegistryInterface::FixedValueString(AssetProcessor::AssetProcessorSettingsKey)
-                + "/Server/cacheServerAddress"))
-            {
-                AZ_TracePrintf(AssetProcessor::DebugChannel, "Server Address: %s\n", address.c_str());
-                s_assetServerAddress = address;
-                return QString::fromUtf8(address.data(), aznumeric_cast<int>(address.size()));
-            }
-        }
-
-        return QString();
-    }
-
     bool ShouldUseFileHashing()
     {
         // Check if the settings file is overridden, if so, use the override instead
@@ -1057,7 +941,8 @@ namespace AssetUtilities
 
     QString ComputeJobDescription(const AssetProcessor::AssetRecognizer* recognizer)
     {
-        return recognizer->m_name.toLower();
+        QString jobDescription{ recognizer->m_name.c_str() };
+        return jobDescription.toLower();
     }
 
     AZStd::string ComputeJobLogFolder()

+ 0 - 15
Code/Tools/AssetProcessor/native/utilities/assetUtils.h

@@ -84,21 +84,6 @@ namespace AssetUtilities
     //! Updates the branch token in the bootstrap file
     bool UpdateBranchToken();
 
-    //! Checks to see if the asset processor is running in server mode
-    bool InServerMode();
-
-    //! Clears the server flag
-    void ResetServerMode();
-
-    //! Checks the args for the server parameter, returns true if found otherwise false.
-    bool CheckServerMode();
-
-    //! Reads the server address from the config file.
-    QString ServerAddress();
-
-    //! Clears the string holding the server address for the Cache Server mode
-    void ResetServerAddress();
-
     bool ShouldUseFileHashing();
 
     //! Determine the name of the current project - for example, AutomatedTesting