You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1615 lines
70 KiB
C++
1615 lines
70 KiB
C++
|
|
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
#include "AssetBuilderSDK.h"
|
|
#include "AssetBuilderBusses.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//currently only needed for GETFAKEASSETYPE
|
|
#include <AzFramework/StringFunc/StringFunc.h>
|
|
#include <AzCore/std/string/wildcard.h>
|
|
#include <AzCore/IO/SystemFile.h>
|
|
#include <AzCore/XML/rapidxml.h>
|
|
#include <AzCore/XML/rapidxml_print.h>
|
|
#include <AzCore/Component/Entity.h> // so we can have the entity UUID type.
|
|
#include <AzFramework/IO/LocalFileIO.h>
|
|
#include <AzCore/Component/ComponentApplicationBus.h>
|
|
#include <AzCore/Slice/SliceAsset.h> // For slice asset sub ids
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
namespace AssetBuilderSDK
|
|
{
|
|
const char* const ErrorWindow = "Error"; //Use this window name to log error messages.
|
|
const char* const WarningWindow = "Warning"; //Use this window name to log warning messages.
|
|
const char* const InfoWindow = "Info"; //Use this window name to log info messages.
|
|
|
|
const char* const s_processJobRequestFileName = "ProcessJobRequest.xml";
|
|
const char* const s_processJobResponseFileName = "ProcessJobResponse.xml";
|
|
|
|
// for now, we're going to put our various masks that are widely known in here.
|
|
// we may expand this into a 64-bit "namespace" by adding additional 32 bits at the front at some point, if it becomes necessary.
|
|
const AZ::u32 SUBID_MASK_ID = 0x0000FFFF;
|
|
const AZ::u32 SUBID_MASK_LOD_LEVEL = 0x000F0000;
|
|
const AZ::u32 SUBID_LOD_LEVEL_SHIFT = 16; // shift 16 bits to the left to get 0x000F0000
|
|
const AZ::u32 SUBID_FLAG_DIFF = 0x00100000;
|
|
const AZ::u32 SUBID_FLAG_ALPHA = 0x00200000;
|
|
|
|
AZ::u32 GetSubID_ID(AZ::u32 packedSubId)
|
|
{
|
|
return packedSubId & SUBID_MASK_ID;
|
|
}
|
|
|
|
AZ::u32 GetSubID_LOD(AZ::u32 packedSubId)
|
|
{
|
|
return ((packedSubId & SUBID_MASK_LOD_LEVEL) >> SUBID_LOD_LEVEL_SHIFT);
|
|
}
|
|
|
|
AZ::u32 ConstructSubID(AZ::u32 subIndex, AZ::u32 lodLevel, AZ::u32 fromSubIndex)
|
|
{
|
|
AZ_Warning(WarningWindow, subIndex <= SUBID_MASK_ID, "ConstructSubID: subIndex %u is too big to fit", subIndex);
|
|
AZ_Warning(WarningWindow, lodLevel <= 0xF, "ConstructSubID: lodLevel %u is too big to fit", lodLevel);
|
|
AZ::u32 mask = ~(SUBID_MASK_ID | SUBID_MASK_LOD_LEVEL);
|
|
AZ::u32 original = fromSubIndex & mask; // eliminate all the bits that are part of the subid or the lod index
|
|
|
|
fromSubIndex = original;
|
|
fromSubIndex |= subIndex;
|
|
fromSubIndex |= (lodLevel << SUBID_LOD_LEVEL_SHIFT) & SUBID_MASK_LOD_LEVEL;
|
|
|
|
AZ_Warning(WarningWindow, original == (fromSubIndex & mask), "ConstructSubID: Unexpected modification of the bits that should not have been touched");
|
|
|
|
return fromSubIndex;
|
|
}
|
|
|
|
#if defined(ENABLE_LEGACY_PLATFORMFLAGS_SUPPORT)
|
|
// this function exists merely to retain code compatibility with older versions.
|
|
// it is recommended to upgrade to the new way, which is to just use the m_enabledPlatforms structs.
|
|
Platform LEGACY_ConvertNewPlatformIdentifierToOldPlatform(const char* newPlatformName)
|
|
{
|
|
if (azstricmp(newPlatformName, "pc") == 0)
|
|
{
|
|
return AssetBuilderSDK::Platform_PC;
|
|
}
|
|
if (azstricmp(newPlatformName, "android") == 0)
|
|
{
|
|
return AssetBuilderSDK::Platform_ANDROID;
|
|
}
|
|
if (azstricmp(newPlatformName, "ios") == 0)
|
|
{
|
|
return AssetBuilderSDK::Platform_IOS;
|
|
}
|
|
if (azstricmp(newPlatformName, "mac") == 0)
|
|
{
|
|
return AssetBuilderSDK::Platform_MAC;
|
|
}
|
|
if (azstricmp(newPlatformName, "provo") == 0)
|
|
{
|
|
return AssetBuilderSDK::Platform_PROVO;
|
|
}
|
|
#if defined(AZ_PLATFORM_JASPER) || defined(TOOLS_SUPPORT_JASPER)
|
|
#include AZ_RESTRICTED_FILE_EXPLICIT(AssetBuilderSDK_cpp, jasper)
|
|
#endif
|
|
#if defined(AZ_PLATFORM_PROVO) || defined(TOOLS_SUPPORT_PROVO)
|
|
#include AZ_RESTRICTED_FILE_EXPLICIT(AssetBuilderSDK_cpp, provo)
|
|
#endif
|
|
#if defined(AZ_PLATFORM_SALEM) || defined(TOOLS_SUPPORT_SALEM)
|
|
#include AZ_RESTRICTED_FILE_EXPLICIT(AssetBuilderSDK_cpp, salem)
|
|
#endif
|
|
|
|
return AssetBuilderSDK::Platform_NONE;
|
|
}
|
|
|
|
// this function exists merely to retain code compatibility with older versions.
|
|
// it is recommended to upgrade to the new way, which is to just use the m_enabledPlatforms structs.
|
|
const char* LEGACY_ConvertOldPlatformToNewPlatformIdentifier(Platform oldPlatform)
|
|
{
|
|
switch (oldPlatform)
|
|
{
|
|
case AssetBuilderSDK::Platform_PC:
|
|
return "pc";
|
|
case AssetBuilderSDK::Platform_ANDROID:
|
|
return "android";
|
|
case AssetBuilderSDK::Platform_IOS:
|
|
return "ios";
|
|
case AssetBuilderSDK::Platform_MAC:
|
|
return "mac";
|
|
case AssetBuilderSDK::Platform_PROVO:
|
|
return "provo";
|
|
case AssetBuilderSDK::Platform_SALEM:
|
|
return "salem";
|
|
case AssetBuilderSDK::Platform_JASPER:
|
|
return "jasper";
|
|
}
|
|
return "unknown platform";
|
|
}
|
|
|
|
#endif // defined(ENABLE_LEGACY_PLATFORMFLAGS_SUPPORT)
|
|
|
|
void BuilderLog(AZ::Uuid builderId, const char* message, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, message);
|
|
EBUS_EVENT(AssetBuilderSDK::AssetBuilderBus, BuilderLog, builderId, message, args);
|
|
va_end(args);
|
|
}
|
|
|
|
AssetBuilderPattern::AssetBuilderPattern(const AZStd::string& pattern, PatternType type)
|
|
: m_pattern(pattern)
|
|
, m_type(type)
|
|
{
|
|
}
|
|
|
|
AZStd::string AssetBuilderPattern::ToString() const
|
|
{
|
|
return AZStd::string::format("{%s:%s}", m_type == Wildcard ? "WildCard" : "Regex", m_pattern.c_str());
|
|
}
|
|
|
|
void AssetBuilderPattern::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<AssetBuilderPattern>()
|
|
->Version(1)
|
|
->Field("Pattern", &AssetBuilderPattern::m_pattern)
|
|
->Field("Type", &AssetBuilderPattern::m_type);
|
|
|
|
serializeContext->RegisterGenericType<AZStd::vector<AssetBuilderPattern>>();
|
|
}
|
|
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<AssetBuilderPattern>("AssetBuilderPattern")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Constructor()
|
|
->Property("pattern", BehaviorValueProperty(&AssetBuilderPattern::m_pattern))
|
|
->Property("type", BehaviorValueProperty(&AssetBuilderPattern::m_type))
|
|
->Enum<aznumeric_cast<int>(AssetBuilderPattern::PatternType::Wildcard)>("Wildcard")
|
|
->Enum<aznumeric_cast<int>(AssetBuilderPattern::PatternType::Regex)>("Regex");
|
|
}
|
|
}
|
|
|
|
FilePatternMatcher::FilePatternMatcher(const AssetBuilderSDK::AssetBuilderPattern& pattern)
|
|
: m_pattern(pattern)
|
|
{
|
|
if (pattern.m_type == AssetBuilderSDK::AssetBuilderPattern::Regex)
|
|
{
|
|
m_isRegex = true;
|
|
m_isValid = FilePatternMatcher::ValidatePatternRegex(pattern.m_pattern);
|
|
if (m_isValid)
|
|
{
|
|
this->m_regex = RegexType(pattern.m_pattern.c_str(), RegexType::flag_type::icase | RegexType::flag_type::ECMAScript);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_isValid = true;
|
|
m_isRegex = false;
|
|
}
|
|
}
|
|
|
|
FilePatternMatcher::FilePatternMatcher(const AZStd::string& pattern, AssetBuilderSDK::AssetBuilderPattern::PatternType type)
|
|
: FilePatternMatcher(AssetBuilderSDK::AssetBuilderPattern(pattern, type))
|
|
{
|
|
}
|
|
|
|
FilePatternMatcher::FilePatternMatcher(const FilePatternMatcher& copy)
|
|
: m_pattern(copy.m_pattern)
|
|
, m_regex(copy.m_regex)
|
|
, m_isRegex(copy.m_isRegex)
|
|
, m_isValid(copy.m_isValid)
|
|
, m_errorString(copy.m_errorString)
|
|
{
|
|
}
|
|
|
|
FilePatternMatcher& FilePatternMatcher::operator=(const FilePatternMatcher& copy)
|
|
{
|
|
this->m_pattern = copy.m_pattern;
|
|
this->m_regex = copy.m_regex;
|
|
this->m_isRegex = copy.m_isRegex;
|
|
this->m_isValid = copy.m_isValid;
|
|
this->m_errorString = copy.m_errorString;
|
|
return *this;
|
|
}
|
|
|
|
bool FilePatternMatcher::MatchesPath(const AZStd::string& assetPath) const
|
|
{
|
|
bool matches = false;
|
|
if (this->m_isRegex)
|
|
{
|
|
matches = AZStd::regex_match(assetPath.c_str(), this->m_regex);
|
|
}
|
|
else
|
|
{
|
|
matches = AZStd::wildcard_match(this->m_pattern.m_pattern, assetPath);
|
|
}
|
|
return matches;
|
|
}
|
|
|
|
bool FilePatternMatcher::IsValid() const
|
|
{
|
|
return this->m_isValid;
|
|
}
|
|
|
|
AZStd::string FilePatternMatcher::GetErrorString() const
|
|
{
|
|
return m_errorString;
|
|
}
|
|
|
|
const AssetBuilderSDK::AssetBuilderPattern& FilePatternMatcher::GetBuilderPattern() const
|
|
{
|
|
return this->m_pattern;
|
|
}
|
|
|
|
bool FilePatternMatcher::ValidatePatternRegex(const AZStd::string& pattern)
|
|
{
|
|
AssertAbsorber absorber;
|
|
AZStd::regex validate_regex(pattern.c_str(),
|
|
AZStd::regex::flag_type::icase |
|
|
AZStd::regex::flag_type::ECMAScript);
|
|
|
|
return absorber.m_assertMessage.empty();
|
|
}
|
|
|
|
void AssetBuilderDesc::AddFlags(AZ::u8 flags, const AZStd::string& jobKey)
|
|
{
|
|
AZ::u8& flagsByKey = m_flagsByJobKey[jobKey];
|
|
flagsByKey |= flags;
|
|
}
|
|
|
|
bool AssetBuilderDesc::HasFlag(AZ::u8 flag, const AZStd::string& jobKey) const
|
|
{
|
|
if ((m_flags & flag) != 0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
auto iter = m_flagsByJobKey.find(jobKey);
|
|
return iter != m_flagsByJobKey.end() ? (iter->second & flag) != 0 : false;
|
|
}
|
|
|
|
bool AssetBuilderDesc::IsExternalBuilder() const
|
|
{
|
|
return m_builderType == AssetBuilderType::External;
|
|
}
|
|
|
|
/**
|
|
* New constructor - uses the platform Identifier from the PlatformInfo passed into Create Jobs.
|
|
*/
|
|
JobDescriptor::JobDescriptor(const AZStd::string& additionalFingerprintInfo, AZStd::string jobKey, const char* platformIdentifier)
|
|
: m_additionalFingerprintInfo(additionalFingerprintInfo)
|
|
, m_jobKey(jobKey)
|
|
{
|
|
SetPlatformIdentifier(platformIdentifier);
|
|
}
|
|
|
|
#if defined(ENABLE_LEGACY_PLATFORMFLAGS_SUPPORT)
|
|
/**
|
|
* old api constructor. Still supported for backward compatibility, but do not use in new code.
|
|
*/
|
|
JobDescriptor::JobDescriptor(AZStd::string additionalFingerprintInfo, int platform, const AZStd::string& jobKey)
|
|
: m_additionalFingerprintInfo(additionalFingerprintInfo)
|
|
, m_platform(platform)
|
|
, m_jobKey(jobKey)
|
|
{
|
|
SetPlatformIdentifier(LEGACY_ConvertOldPlatformToNewPlatformIdentifier(static_cast<AssetBuilderSDK::Platform>(m_platform)));
|
|
}
|
|
#endif // defined(ENABLE_LEGACY_PLATFORMFLAGS_SUPPORT)
|
|
|
|
void JobDescriptor::SetPlatformIdentifier(const char* platformIdentifier)
|
|
{
|
|
if (platformIdentifier)
|
|
{
|
|
m_platformIdentifier = platformIdentifier;
|
|
}
|
|
#if defined(ENABLE_LEGACY_PLATFORMFLAGS_SUPPORT)
|
|
m_platform = LEGACY_ConvertNewPlatformIdentifierToOldPlatform(platformIdentifier);
|
|
#endif // defined(ENABLE_LEGACY_PLATFORMFLAGS_SUPPORT)
|
|
}
|
|
|
|
const AZStd::string& JobDescriptor::GetPlatformIdentifier() const
|
|
{
|
|
return m_platformIdentifier;
|
|
}
|
|
|
|
#if defined(ENABLE_LEGACY_PLATFORMFLAGS_SUPPORT)
|
|
namespace Internal
|
|
{
|
|
// for legacy compatibility, we make sure that if only the m_platform field is populated
|
|
// we go ahead and fill out the new API from the old one.
|
|
class JobDescriptorSerializeEventHandler
|
|
: public AZ::SerializeContext::IEventHandler
|
|
{
|
|
public:
|
|
virtual void OnReadBegin(void* classPtr)
|
|
{
|
|
JobDescriptor* populatingJobDescriptor = reinterpret_cast<JobDescriptor*>(classPtr);
|
|
if (populatingJobDescriptor)
|
|
{
|
|
// before we serialize this instance into a stream, lets make sure its converted.
|
|
if (populatingJobDescriptor->GetPlatformIdentifier().empty())
|
|
{
|
|
populatingJobDescriptor->SetPlatformIdentifier(LEGACY_ConvertOldPlatformToNewPlatformIdentifier(static_cast<AssetBuilderSDK::Platform>(populatingJobDescriptor->m_platform)));
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual void OnWriteEnd(void* classPtr)
|
|
{
|
|
JobDescriptor* populatingJobDescriptor = reinterpret_cast<JobDescriptor*>(classPtr);
|
|
if (populatingJobDescriptor)
|
|
{
|
|
// we've finished writing into this instance, lets patch up the platform.
|
|
if (populatingJobDescriptor->GetPlatformIdentifier().empty())
|
|
{
|
|
populatingJobDescriptor->SetPlatformIdentifier(LEGACY_ConvertOldPlatformToNewPlatformIdentifier(static_cast<AssetBuilderSDK::Platform>(populatingJobDescriptor->m_platform)));
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
static JobDescriptorSerializeEventHandler s_jobDescriptorSerializeEventHandlerInstance;
|
|
}
|
|
|
|
#endif // defined(ENABLE_LEGACY_PLATFORMFLAGS_SUPPORT)
|
|
|
|
|
|
void JobDescriptor::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<JobDescriptor>()->
|
|
Version(4)->
|
|
Field("Additional Fingerprint Info", &JobDescriptor::m_additionalFingerprintInfo)->
|
|
#if defined(ENABLE_LEGACY_PLATFORMFLAGS_SUPPORT)
|
|
EventHandler(&Internal::s_jobDescriptorSerializeEventHandlerInstance)->
|
|
Field("Platform", &JobDescriptor::m_platform)-> // note: deprecated but we still pass it via the network so it must be serialized.
|
|
#endif // defined(ENABLE_LEGACY_PLATFORMFLAGS_SUPPORT)
|
|
Field("Platform Identifier", &JobDescriptor::m_platformIdentifier)-> // new API
|
|
Field("Job Key", &JobDescriptor::m_jobKey)->
|
|
Field("Critical", &JobDescriptor::m_critical)->
|
|
Field("Priority", &JobDescriptor::m_priority)->
|
|
Field("Job Parameters", &JobDescriptor::m_jobParameters)->
|
|
Field("Check Exclusive Lock", &JobDescriptor::m_checkExclusiveLock)->
|
|
Field("Fail On Error", &JobDescriptor::m_failOnError)->
|
|
Field("Job Dependency List", &JobDescriptor::m_jobDependencyList)->
|
|
Field("Check Server", &JobDescriptor::m_checkServer);
|
|
|
|
serializeContext->RegisterGenericType<AZStd::vector<JobDescriptor>>();
|
|
}
|
|
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<JobDescriptor>("JobDescriptor")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Constructor()
|
|
->Constructor<const AZStd::string&, AZStd::string, const char*>()
|
|
->Property("jobParameters", BehaviorValueProperty(&JobDescriptor::m_jobParameters))
|
|
->Property("additionalFingerprintInfo", BehaviorValueProperty(&JobDescriptor::m_additionalFingerprintInfo))
|
|
->Property("jobKey", BehaviorValueProperty(&JobDescriptor::m_jobKey))
|
|
->Property("priority", BehaviorValueProperty(&JobDescriptor::m_priority))
|
|
->Property("checkExclusiveLock", BehaviorValueProperty(&JobDescriptor::m_checkExclusiveLock))
|
|
->Property("checkServer", BehaviorValueProperty(&JobDescriptor::m_checkServer))
|
|
->Property("jobDependencyList", BehaviorValueProperty(&JobDescriptor::m_jobDependencyList))
|
|
->Property("failOnError", BehaviorValueProperty(&JobDescriptor::m_failOnError))
|
|
->Method("set_platform_identifier", &JobDescriptor::SetPlatformIdentifier)
|
|
->Method("get_platform_identifier", &JobDescriptor::GetPlatformIdentifier);
|
|
}
|
|
}
|
|
|
|
CreateJobsRequest::CreateJobsRequest(AZ::Uuid builderid, AZStd::string sourceFile, AZStd::string watchFolder, const AZStd::vector<PlatformInfo>& enabledPlatforms, const AZ::Uuid& sourceFileUUID)
|
|
: m_builderid(builderid)
|
|
, m_sourceFile(sourceFile)
|
|
, m_watchFolder(watchFolder)
|
|
, m_enabledPlatforms(enabledPlatforms)
|
|
, m_sourceFileUUID(sourceFileUUID)
|
|
{
|
|
// synthesize m_platformFlags from the rest
|
|
}
|
|
|
|
CreateJobsRequest::CreateJobsRequest()
|
|
{
|
|
}
|
|
|
|
bool CreateJobsRequest::HasPlatform(const char* platformIdentifier) const
|
|
{
|
|
if (!platformIdentifier)
|
|
{
|
|
AZ_Assert(false, "HasPlatform called with nullptr platformIdentifier.");
|
|
return false;
|
|
}
|
|
for (const PlatformInfo& info : m_enabledPlatforms)
|
|
{
|
|
if (azstricmp(info.m_identifier.c_str(), platformIdentifier) == 0)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CreateJobsRequest::HasPlatformWithTag(const char* platformTag) const
|
|
{
|
|
if (!platformTag)
|
|
{
|
|
AZ_Assert(false, "HasPlatformWithTag called with nullptr platformTag.");
|
|
return false;
|
|
}
|
|
|
|
for (const PlatformInfo& info : m_enabledPlatforms)
|
|
{
|
|
if (info.HasTag(platformTag))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#if defined(ENABLE_LEGACY_PLATFORMFLAGS_SUPPORT)
|
|
size_t CreateJobsRequest::GetEnabledPlatformsCount() const
|
|
{
|
|
return m_enabledPlatforms.size();
|
|
}
|
|
|
|
AssetBuilderSDK::Platform CreateJobsRequest::GetEnabledPlatformAt(size_t index) const
|
|
{
|
|
AZ_WarningOnce(AssetBuilderSDK::WarningWindow, false, "This builder is calling a deprecated function: GetEnabledPlatformAt. Consider just using the new m_enabledPlatforms member instead.");
|
|
if (index >= m_enabledPlatforms.size())
|
|
{
|
|
// for old compat, we cannot assert here.
|
|
return AssetBuilderSDK::Platform_NONE;
|
|
}
|
|
const PlatformInfo& info = m_enabledPlatforms[index];
|
|
|
|
return LEGACY_ConvertNewPlatformIdentifierToOldPlatform(info.m_identifier.c_str());
|
|
}
|
|
|
|
bool CreateJobsRequest::IsPlatformEnabled(AZ::u32 platform) const
|
|
{
|
|
AZ_WarningOnce(AssetBuilderSDK::WarningWindow, false, "This builder is calling a deprecated function: IsPlatformEnabled. Consider just using the new m_enabledPlatforms member instead.");
|
|
for (const PlatformInfo& info : m_enabledPlatforms)
|
|
{
|
|
if (static_cast<AZ::u32>(LEGACY_ConvertNewPlatformIdentifierToOldPlatform(info.m_identifier.c_str())) == platform)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CreateJobsRequest::IsPlatformValid(AZ::u32 platform) const
|
|
{
|
|
AZ_WarningOnce(AssetBuilderSDK::WarningWindow, false, "This builder is calling a deprecated function: IsPlatformValid. Consider just using the new m_enabledPlatforms member instead.");
|
|
return ((platform & AllPlatforms) == platform);
|
|
}
|
|
#endif // defined(ENABLE_LEGACY_PLATFORMFLAGS_SUPPORT)
|
|
|
|
PlatformInfo::PlatformInfo(AZStd::string identifier, const AZStd::unordered_set<AZStd::string>& tags)
|
|
: m_identifier(AZStd::move(identifier))
|
|
, m_tags(tags)
|
|
{
|
|
}
|
|
|
|
bool PlatformInfo::HasTag(const char* tag) const
|
|
{
|
|
return m_tags.find(tag) != m_tags.end();
|
|
}
|
|
|
|
bool PlatformInfo::operator==(const PlatformInfo& other)
|
|
{
|
|
return (this->m_identifier == other.m_identifier);
|
|
}
|
|
|
|
void PlatformInfo::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<PlatformInfo>()->
|
|
Version(1)->
|
|
Field("Platform Identifier", &PlatformInfo::m_identifier)->
|
|
Field("Tags on Platform", &PlatformInfo::m_tags);
|
|
|
|
serializeContext->RegisterGenericType<AZStd::vector<PlatformInfo>>();
|
|
}
|
|
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<PlatformInfo>("PlatformInfo")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Property("identifier", BehaviorValueProperty(&PlatformInfo::m_identifier))
|
|
->Property("tags", BehaviorValueProperty(&PlatformInfo::m_tags));
|
|
}
|
|
}
|
|
|
|
AZStd::string PlatformInfo::PlatformVectorAsString(const AZStd::vector<PlatformInfo>& platforms)
|
|
{
|
|
AZStd::string platformString;
|
|
for (const auto& platformInfo : platforms)
|
|
{
|
|
if (!platformString.empty())
|
|
{
|
|
platformString.append(", ");
|
|
}
|
|
platformString.append(platformInfo.m_identifier.c_str());
|
|
}
|
|
|
|
return platformString;
|
|
}
|
|
|
|
void CreateJobsRequest::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
PlatformInfo::Reflect(context);
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<CreateJobsRequest>()->
|
|
Version(2)->
|
|
Field("Builder Id", &CreateJobsRequest::m_builderid)->
|
|
Field("Watch Folder", &CreateJobsRequest::m_watchFolder)->
|
|
Field("Source File", &CreateJobsRequest::m_sourceFile)->
|
|
Field("Enabled Platforms", &CreateJobsRequest::m_enabledPlatforms)->
|
|
Field("Source File UUID", &CreateJobsRequest::m_sourceFileUUID);
|
|
}
|
|
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<CreateJobsRequest>("CreateJobsRequest")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Property("builderId", BehaviorValueProperty(&CreateJobsRequest::m_builderid))
|
|
->Property("watchFolder", BehaviorValueProperty(&CreateJobsRequest::m_watchFolder))
|
|
->Property("sourceFile", BehaviorValueProperty(&CreateJobsRequest::m_sourceFile))
|
|
->Property("sourceFileUUID", BehaviorValueProperty(&CreateJobsRequest::m_sourceFileUUID))
|
|
->Property("enabledPlatforms", BehaviorValueProperty(&CreateJobsRequest::m_enabledPlatforms));
|
|
}
|
|
|
|
}
|
|
|
|
ProductDependency::ProductDependency(AZ::Data::AssetId dependencyId, const AZStd::bitset<64>& flags)
|
|
: m_dependencyId(dependencyId)
|
|
, m_flags(flags)
|
|
{
|
|
}
|
|
|
|
void ProductDependency::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<ProductDependency>()->
|
|
Version(1)->
|
|
Field("Dependency Id", &ProductDependency::m_dependencyId)->
|
|
Field("Flags", &ProductDependency::m_flags);
|
|
|
|
serializeContext->RegisterGenericType<AZStd::vector<ProductDependency>>();
|
|
}
|
|
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<ProductDependency>("ProductDependency")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Constructor()
|
|
->Property("dependencyId", BehaviorValueProperty(&ProductDependency::m_dependencyId))
|
|
->Property("flags", BehaviorValueProperty(&ProductDependency::m_flags));
|
|
}
|
|
|
|
}
|
|
|
|
ProductPathDependency::ProductPathDependency(AZStd::string_view dependencyPath, ProductPathDependencyType dependencyType)
|
|
: m_dependencyPath(dependencyPath),
|
|
m_dependencyType(dependencyType)
|
|
{
|
|
}
|
|
|
|
bool ProductPathDependency::operator==(const ProductPathDependency& rhs) const
|
|
{
|
|
return m_dependencyPath == rhs.m_dependencyPath
|
|
&& m_dependencyType == rhs.m_dependencyType;
|
|
}
|
|
|
|
void ProductPathDependency::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<ProductPathDependency>()->
|
|
Version(1)->
|
|
Field("Dependency Path", &ProductPathDependency::m_dependencyPath)->
|
|
Field("Dependency Type", &ProductPathDependency::m_dependencyType);
|
|
|
|
serializeContext->RegisterGenericType<AZStd::vector<ProductPathDependency>>();
|
|
serializeContext->RegisterGenericType<AZStd::unordered_set<ProductPathDependency>>();
|
|
}
|
|
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<ProductPathDependency>("ProductPathDependency")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Property("dependencyPath", BehaviorValueProperty(&ProductPathDependency::m_dependencyPath))
|
|
->Property("dependencyType", BehaviorValueProperty(&ProductPathDependency::m_dependencyType))
|
|
->Enum<aznumeric_cast<int>(ProductPathDependencyType::ProductFile)>("ProductFile")
|
|
->Enum<aznumeric_cast<int>(ProductPathDependencyType::SourceFile)>("SourceFile");
|
|
}
|
|
}
|
|
|
|
JobProduct::JobProduct(const AZStd::string& productName, AZ::Data::AssetType productAssetType /*= AZ::Data::AssetType::CreateNull() */, AZ::u32 productSubID /*= 0*/)
|
|
: m_productFileName(productName)
|
|
, m_productAssetType(productAssetType)
|
|
, m_productSubID(productSubID)
|
|
{
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Builders should output product asset types directly.
|
|
// This should only be used for exceptions, mostly legacy and generic data.
|
|
if (m_productAssetType.IsNull())
|
|
{
|
|
m_productAssetType = InferAssetTypeByProductFileName(m_productFileName.c_str());
|
|
}
|
|
if (m_productSubID == 0)
|
|
{
|
|
m_productSubID = InferSubIDFromProductFileName(m_productAssetType, m_productFileName.c_str());
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
}
|
|
|
|
JobProduct::JobProduct(AZStd::string&& productName, AZ::Data::AssetType productAssetType /*= AZ::Data::AssetType::CreateNull() */, AZ::u32 productSubID /*= 0*/)
|
|
: m_productFileName(AZStd::move(productName))
|
|
, m_productAssetType(productAssetType)
|
|
, m_productSubID(productSubID)
|
|
{
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Builders should output product asset types directly.
|
|
// This should only be used for exceptions, mostly legacy.
|
|
if (m_productAssetType.IsNull())
|
|
{
|
|
m_productAssetType = InferAssetTypeByProductFileName(m_productFileName.c_str());
|
|
}
|
|
if (m_productSubID == 0)
|
|
{
|
|
m_productSubID = InferSubIDFromProductFileName(m_productAssetType, m_productFileName.c_str());
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// the following block is for legacy compatibility
|
|
// all new assets should either place their desired UUIDs in the productAssetType field in the actual assetProcessorPlatformConfig.ini file
|
|
// or should create an actual Builder-SDK builder which can specify the id and typeid very specifically.
|
|
|
|
// the following three extensions can have splitted LOD files
|
|
static const char* textureExtensions = ".dds";
|
|
static const char* staticMeshExtensions = ".cgf";
|
|
static const char* skinnedMeshExtensions = ".skin";
|
|
static const char* materialExtensions = ".mtl";
|
|
|
|
// MIPS
|
|
static const int c_MaxMipsCount = 11; // 11 is for 8k textures non-compressed. When not compressed it is using one file per mip.
|
|
// splitted lods have the following extensions:
|
|
static const char* mipsAndLodsExtensions = ".1 .2 .3 .4 .5 .6 .7 .8 .9 .10 .11 .a .1a .2a .3a .4a .5a .6a .7a .8a .9a .10a .11a";
|
|
|
|
// XML files may contain generic data (avoid this in new builders - use a custom extension!)
|
|
static const char* xmlExtensions = ".xml";
|
|
static const char* geomCacheExtensions = ".cax";
|
|
static const char* skeletonExtensions = ".chr";
|
|
|
|
static AZ::Data::AssetType unknownAssetType = AZ::Data::AssetType::CreateNull();
|
|
|
|
// as real BuilderSDK builders are created for these types, they will no longer need to be matched by extension
|
|
// and can be emitted by the builder itself, which has knowledge of the type.
|
|
// first, we'll do the ones which are randomly assigned because they did not actually have an asset type or handler in the main engine yet
|
|
static AZ::Data::AssetType textureMipsAssetType("{3918728C-D3CA-4D9E-813E-A5ED20C6821E}");
|
|
static AZ::Data::AssetType skinnedMeshLodsAssetType("{58E5824F-C27B-46FD-AD48-865BA41B7A51}");
|
|
static AZ::Data::AssetType staticMeshLodsAssetType("{9AAE4926-CB6A-4C60-9948-A1A22F51DB23}");
|
|
static AZ::Data::AssetType geomCacheAssetType("{EBC96071-E960-41B6-B3E3-328F515AE5DA}");
|
|
static AZ::Data::AssetType skeletonAssetType("{60161B46-21F0-4396-A4F0-F2CCF0664CDE}");
|
|
static AZ::Data::AssetType entityIconAssetType("{3436C30E-E2C5-4C3B-A7B9-66C94A28701B}");
|
|
|
|
// now the ones that are actual asset types that already have an AssetData-derived class in the engine
|
|
// note that ideally, all NEW asset types beyond this point are instead built by an actual specific builder-SDK derived builder
|
|
// and thus can emit their own asset types, but for legacy compatibility, this is an alternate means to do this.
|
|
static AZ::Data::AssetType textureAssetType("{59D5E20B-34DB-4D8E-B867-D33CC2556355}"); // from MaterialAsset.h
|
|
static AZ::Data::AssetType materialAssetType("{F46985B5-F7FF-4FCB-8E8C-DC240D701841}"); // from MaterialAsset.h
|
|
static AZ::Data::AssetType meshAssetType("{C2869E3B-DDA0-4E01-8FE3-6770D788866B}"); // from MeshAsset.h
|
|
static AZ::Data::AssetType skinnedMeshAssetType("{C5D443E1-41FF-4263-8654-9438BC888CB7}"); // from MeshAsset.h
|
|
static AZ::Data::AssetType sliceAssetType("{C62C7A87-9C09-4148-A985-12F2C99C0A45}"); // from SliceAsset.h
|
|
static AZ::Data::AssetType dynamicSliceAssetType("{78802ABF-9595-463A-8D2B-D022F906F9B1}"); // from SliceAsset.h
|
|
|
|
// the following Asset Types are discovered in generic XMLs. in the future, these need to be custom file extensions
|
|
// and this data can move from here to the INI file, or into a custom builder.
|
|
static AZ::Data::AssetType prefabsLibraryAssetType("{2DC3C556-9461-4729-8313-2BA0CB64EF52}"); // from PrefabsLibraryAssetTypeInfo.cpp
|
|
static AZ::Data::AssetType entityPrototypeLibraryAssetType("{B034F8AB-D881-4A35-A408-184E3FDEB2FE}"); // from EntityPrototypeLibraryAssetTypeInfo.cpp
|
|
static AZ::Data::AssetType gameTokenAssetType("{1D4B56F8-366A-4040-B645-AE87E3A00DAB}"); // from GameTokenAssetTypeInfo.cpp
|
|
static AZ::Data::AssetType particleLibraryAssetType("{99542BB9-2870-4DD0-AA0A-57B5541CD196}");
|
|
static AZ::Data::AssetType particleAssetType("{6EB56B55-1B58-4EE3-A268-27680338AE56}"); // from ParticleAsset.h
|
|
static AZ::Data::AssetType lensFlareAssetType("{CF44D1F0-F178-4A3D-A9E6-D44721F50C20}"); // from LensFlareAsset.h
|
|
static AZ::Data::AssetType fontAssetType("{57767D37-0EBE-43BE-8F60-AB36D2056EF8}"); // form UiAssetTypes.h
|
|
static AZ::Data::AssetType uiCanvasAssetType("{E48DDAC8-1F1E-4183-AAAB-37424BCC254B}"); // from UiAssetTypes.h
|
|
|
|
// EMotionFX Gem types
|
|
// If we have a way to register gem specific asset type in the future, we can remove this.
|
|
static const char* emotionFXActorExtension = ".actor";
|
|
static const char* emotionFXMotionExtension = ".motion";
|
|
static const char* emotionFXMotionSetExtension = ".motionset";
|
|
static const char* emotionFXAnimGraphExtension = ".animgraph";
|
|
static AZ::Data::AssetType emotionFXActorAssetType("{F67CC648-EA51-464C-9F5D-4A9CE41A7F86}"); // from ActorAsset.h in EMotionFX Gem
|
|
static AZ::Data::AssetType emotionFXMotionAssetType("{00494B8E-7578-4BA2-8B28-272E90680787}"); // from MotionAsset.h in EMotionFX Gem
|
|
static AZ::Data::AssetType emotionFXMotionSetAssetType("{1DA936A0-F766-4B2F-B89C-9F4C8E1310F9}"); // from MotionSetAsset.h in EMotionFX Gem
|
|
static AZ::Data::AssetType emotionFXAnimGraphAssetType("{28003359-4A29-41AE-8198-0AEFE9FF5263}"); // from AnimGraphAsset.h in EMotionFX Gem
|
|
|
|
AZ::Data::AssetType JobProduct::InferAssetTypeByProductFileName(const char* productFile)
|
|
{
|
|
//get the extension
|
|
AZStd::string extension;
|
|
if (!AzFramework::StringFunc::Path::GetExtension(productFile, extension, true))
|
|
{
|
|
// files which have no extension at all are not currently supported
|
|
return unknownAssetType;
|
|
}
|
|
|
|
// intercept texture mips and mesh lods first
|
|
size_t pos = AZStd::string::npos;
|
|
pos = AzFramework::StringFunc::Find(mipsAndLodsExtensions, extension.c_str());
|
|
if (pos != AZStd::string::npos)
|
|
{
|
|
// Could be a texture mip or a model lod...
|
|
// we don't want them to have the same asset type as the main asset,
|
|
// otherwise they would be assignable in the editor for that type.
|
|
|
|
// is it a texture mip?
|
|
AZStd::vector<AZStd::string> textureExtensionsList;
|
|
AzFramework::StringFunc::Tokenize(textureExtensions, textureExtensionsList);
|
|
for (const auto& textureExtension : textureExtensionsList)
|
|
{
|
|
pos = AzFramework::StringFunc::Find(productFile, textureExtension.c_str());
|
|
if (pos != AZStd::string::npos)
|
|
{
|
|
return textureMipsAssetType;
|
|
}
|
|
}
|
|
|
|
// if its not a texture mip is it a static mesh lod?
|
|
AZStd::vector<AZStd::string> staticMeshExtensionsList;
|
|
AzFramework::StringFunc::Tokenize(staticMeshExtensions, staticMeshExtensionsList);
|
|
for (const auto& staticMeshExtension : staticMeshExtensionsList)
|
|
{
|
|
pos = AzFramework::StringFunc::Find(productFile, staticMeshExtension.c_str());
|
|
if (pos != AZStd::string::npos)
|
|
{
|
|
return staticMeshLodsAssetType;
|
|
}
|
|
}
|
|
|
|
// if its not a static mesh lod is it a skinned mesh lod?
|
|
AZStd::vector<AZStd::string> skinnedMeshExtensionsList;
|
|
AzFramework::StringFunc::Tokenize(skinnedMeshExtensions, skinnedMeshExtensionsList);
|
|
for (const auto& skinnedMeshExtension : skinnedMeshExtensionsList)
|
|
{
|
|
pos = AzFramework::StringFunc::Find(productFile, skinnedMeshExtension.c_str());
|
|
if (pos != AZStd::string::npos)
|
|
{
|
|
return skinnedMeshLodsAssetType;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (AzFramework::StringFunc::Find(textureExtensions, extension.c_str()) != AZStd::string::npos)
|
|
{
|
|
return textureAssetType;
|
|
}
|
|
|
|
if (AzFramework::StringFunc::Find(materialExtensions, extension.c_str()) != AZStd::string::npos)
|
|
{
|
|
return materialAssetType;
|
|
}
|
|
|
|
if (AzFramework::StringFunc::Find(staticMeshExtensions, extension.c_str()) != AZStd::string::npos)
|
|
{
|
|
return meshAssetType;
|
|
}
|
|
|
|
if (AzFramework::StringFunc::Find(skinnedMeshExtensions, extension.c_str()) != AZStd::string::npos)
|
|
{
|
|
return skinnedMeshAssetType;
|
|
}
|
|
|
|
if (AzFramework::StringFunc::Find(geomCacheExtensions, extension.c_str()) != AZStd::string::npos)
|
|
{
|
|
return geomCacheAssetType;
|
|
}
|
|
|
|
if (AzFramework::StringFunc::Find(skeletonExtensions, extension.c_str()) != AZStd::string::npos)
|
|
{
|
|
return skeletonAssetType;
|
|
}
|
|
|
|
// EMFX Gem Begin
|
|
// If we have a way to register gem specific asset type in the future, we can remove this.
|
|
if (AzFramework::StringFunc::Find(emotionFXActorExtension, extension.c_str()) != AZStd::string::npos)
|
|
{
|
|
return emotionFXActorAssetType;
|
|
}
|
|
|
|
if (AzFramework::StringFunc::Find(emotionFXMotionExtension, extension.c_str()) != AZStd::string::npos)
|
|
{
|
|
return emotionFXMotionAssetType;
|
|
}
|
|
|
|
if (AzFramework::StringFunc::Find(emotionFXMotionSetExtension, extension.c_str()) != AZStd::string::npos)
|
|
{
|
|
return emotionFXMotionSetAssetType;
|
|
}
|
|
|
|
if (AzFramework::StringFunc::Find(emotionFXAnimGraphExtension, extension.c_str()) != AZStd::string::npos)
|
|
{
|
|
return emotionFXAnimGraphAssetType;
|
|
}
|
|
// EMFX Gem End
|
|
|
|
// if its an XML file then we may need to open it up to find out what it is...
|
|
if (AzFramework::StringFunc::Find(xmlExtensions, extension.c_str()) != AZStd::string::npos)
|
|
{
|
|
if (!AZ::IO::SystemFile::Exists(productFile))
|
|
{
|
|
return unknownAssetType;
|
|
}
|
|
|
|
uint64_t fileSize = AZ::IO::SystemFile::Length(productFile);
|
|
if (fileSize == 0)
|
|
{
|
|
return unknownAssetType;
|
|
}
|
|
|
|
AZStd::vector<char> buffer(fileSize + 1);
|
|
buffer[fileSize] = 0;
|
|
if (!AZ::IO::SystemFile::Read(productFile, buffer.data()))
|
|
{
|
|
return unknownAssetType;
|
|
}
|
|
|
|
// if it contains this kind of element, we save that info for later once we confirm its an objectstream.
|
|
bool contains_UIAssetCanvasElement = (AzFramework::StringFunc::Find(buffer.data(), "{50B8CF6C-B19A-4D86-AFE9-96EFB820D422}") != AZStd::string::npos);
|
|
|
|
// this is why new asset types REALLY need to have an extension (or other indicator) on their source or product that are different and can easily determine their
|
|
// intended usage.
|
|
AZ::rapidxml::xml_document<char>* xmlDoc = azcreate(AZ::rapidxml::xml_document<char>, (), AZ::SystemAllocator, "BuilderSDK Temp XML Reader");
|
|
if (xmlDoc->parse<AZ::rapidxml::parse_no_data_nodes>(buffer.data()))
|
|
{
|
|
// note that PARSE_FASTEST does not null-terminate strings, instead we just PARSE_NO_DATA_NODES so that xdata and other such blobs are ignored since they don't matter
|
|
AZ::rapidxml::xml_node<char>* xmlRootNode = xmlDoc->first_node();
|
|
if (!xmlRootNode)
|
|
{
|
|
azdestroy(xmlDoc, AZ::SystemAllocator, AZ::rapidxml::xml_document<char>);
|
|
return unknownAssetType;
|
|
}
|
|
|
|
if (!azstricmp(xmlRootNode->name(), "fontshader"))
|
|
{
|
|
azdestroy(xmlDoc, AZ::SystemAllocator, AZ::rapidxml::xml_document<char>);
|
|
return fontAssetType;
|
|
}
|
|
|
|
if (!azstricmp(xmlRootNode->name(), "ParticleLibrary"))
|
|
{
|
|
azdestroy(xmlDoc, AZ::SystemAllocator, AZ::rapidxml::xml_document<char>);
|
|
return particleAssetType;
|
|
}
|
|
|
|
if (!azstricmp(xmlRootNode->name(), "LensFlareLibrary"))
|
|
{
|
|
azdestroy(xmlDoc, AZ::SystemAllocator, AZ::rapidxml::xml_document<char>);
|
|
return lensFlareAssetType;
|
|
}
|
|
|
|
if (!azstricmp(xmlRootNode->name(), "PrefabsLibrary"))
|
|
{
|
|
azdestroy(xmlDoc, AZ::SystemAllocator, AZ::rapidxml::xml_document<char>);
|
|
return prefabsLibraryAssetType;
|
|
}
|
|
|
|
if (!azstricmp(xmlRootNode->name(), "EntityPrototypeLibrary"))
|
|
{
|
|
azdestroy(xmlDoc, AZ::SystemAllocator, AZ::rapidxml::xml_document<char>);
|
|
return entityPrototypeLibraryAssetType;
|
|
}
|
|
|
|
if (!azstricmp(xmlRootNode->name(), "GameTokensLibrary"))
|
|
{
|
|
azdestroy(xmlDoc, AZ::SystemAllocator, AZ::rapidxml::xml_document<char>);
|
|
return gameTokenAssetType;
|
|
}
|
|
|
|
if (!azstricmp(xmlRootNode->name(), "ObjectStream")) // this is an object stream, which means the actual class in the object stream is the first child.
|
|
{
|
|
if (contains_UIAssetCanvasElement)
|
|
{
|
|
azdestroy(xmlDoc, AZ::SystemAllocator, AZ::rapidxml::xml_document<char>);
|
|
return uiCanvasAssetType;
|
|
}
|
|
|
|
for (AZ::rapidxml::xml_node<char>* childNode = xmlRootNode->first_node(); childNode; childNode = childNode->next_sibling())
|
|
{
|
|
// the old object-stream format used to put the name of the type as the actual <element> so we have to just check it for a 'type' flag.
|
|
AZ::rapidxml::xml_attribute<char>* attr = childNode->first_attribute("type", 0, false);
|
|
if (attr)
|
|
{
|
|
// note that this will issue a warning if its a malformed UUID.
|
|
AZ::Data::AssetType attrType(attr->value());
|
|
|
|
if (attrType != AZ::Data::AssetType::CreateNull())
|
|
{
|
|
azdestroy(xmlDoc, AZ::SystemAllocator, AZ::rapidxml::xml_document<char>);
|
|
return attrType;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
azdestroy(xmlDoc, AZ::SystemAllocator, AZ::rapidxml::xml_document<char>);
|
|
}
|
|
return unknownAssetType;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// This is for e
|
|
AZ::u32 JobProduct::InferSubIDFromProductFileName(const AZ::Data::AssetType& assetType, const char* productFile)
|
|
{
|
|
// The engine only uses dynamic slice files, but for right now slices are also copy products...
|
|
// So slice will have two products, so they must have a different sub id's.
|
|
// In the interest of future compatibility we will want dynamic slices to have a unique subId, seperate from a
|
|
// slice copy job product subId. The only reason they are currently copy products is for the builder to
|
|
// make dynamic slice products. This will change in the future and the .slice files will no longer copy themselves
|
|
// as products, so this is a temporary rule and eventually there will only be one subId
|
|
if (assetType == sliceAssetType)
|
|
{
|
|
return AZ::SliceAsset::GetAssetSubId();
|
|
}
|
|
|
|
// Dynamic slices use a unique subId to avoid ambiguity with legacy editor slice guids.
|
|
if (assetType == dynamicSliceAssetType)
|
|
{
|
|
return AZ::DynamicSliceAsset::GetAssetSubId();
|
|
}
|
|
|
|
//get the extension
|
|
AZStd::string extension;
|
|
if (!AzFramework::StringFunc::Path::GetExtension(productFile, extension, true))
|
|
{
|
|
return 0; //no extension....the safest thing is 0 and see if we get any collisions
|
|
}
|
|
|
|
//intercept mips and lods first
|
|
bool isTextureMip = assetType == textureMipsAssetType;
|
|
bool isStaticMeshLod = assetType == staticMeshLodsAssetType;
|
|
bool isSkinnedMeshLod = assetType == skinnedMeshLodsAssetType;
|
|
bool isTexture = assetType == textureAssetType;
|
|
|
|
//if its a static or skinned mesh, then its not a lod so return 0
|
|
if ((assetType == skinnedMeshAssetType) || (assetType == meshAssetType))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//calculated sub ids
|
|
AZ::u32 subID = 0;
|
|
|
|
// PNG files can be processed as both texture and EntityIcon assets. Make sure they have different subids.
|
|
if (assetType == entityIconAssetType)
|
|
{
|
|
return subID + 1;
|
|
}
|
|
|
|
// if its texture or texture mip there is a special case for diff-textures
|
|
// it is special because a single FILENAME_CM.TIF can become -many- outputs:
|
|
// filename_cm_diff.dds
|
|
// filename_cm_diff.dds.1
|
|
// filename_cm_diff.dds.1a
|
|
// ...
|
|
// filename_cm_diff.dds.9
|
|
// filename_cm_diff.dds.9a
|
|
// filename_cm.dds
|
|
// filename_cm.dds.1
|
|
// filename_cm.dds.1a
|
|
// ...
|
|
// filename_cm.dds.9
|
|
// filename_cm.dds.9a
|
|
|
|
if (isTexture || isTextureMip)
|
|
{
|
|
//but it could be a special case for _diff. textures
|
|
if (AzFramework::StringFunc::Find(productFile, "_diff.") != AZStd::string::npos)
|
|
{
|
|
subID |= SUBID_FLAG_DIFF; // 'diff' textures will have the 6th bit set. This still leaves us with 0..31 as valid mips
|
|
}
|
|
}
|
|
|
|
if (isTexture)
|
|
{
|
|
return subID; //if its texture and not a mip, so it gets 0 or 100
|
|
}
|
|
|
|
if (isTextureMip || isStaticMeshLod || isSkinnedMeshLod)
|
|
{
|
|
//if its a mip or lod add to the subid, so .1 should be 1, .2 should be 2 etc.. if its a diff mips its will be 101, 102, etc...
|
|
if ((extension[extension.size() - 1]) == 'a')
|
|
{
|
|
// if it ends with a .a, its the next set
|
|
subID = subID | SUBID_FLAG_ALPHA;
|
|
extension.resize(extension.size() - 1);
|
|
}
|
|
|
|
for (int idx = 1; idx <= c_MaxMipsCount; ++idx)
|
|
{
|
|
AZStd::string check = AZStd::string::format(".%i", idx);
|
|
if (check == extension)
|
|
{
|
|
subID = ConstructSubID(0, idx, subID);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// note that if its JUST '.a' then it will end up here with 0 added.
|
|
|
|
return subID;
|
|
}
|
|
|
|
return 0; //zero by default
|
|
}
|
|
|
|
void JobProduct::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<JobProduct>()->
|
|
Version(6)->
|
|
Field("Product File Name", &JobProduct::m_productFileName)->
|
|
Field("Product Asset Type", &JobProduct::m_productAssetType)->
|
|
Field("Product Sub Id", &JobProduct::m_productSubID)->
|
|
Field("Legacy Sub Ids", &JobProduct::m_legacySubIDs)->
|
|
Field("Dependencies", &JobProduct::m_dependencies)->
|
|
Field("Relative Path Dependencies", &JobProduct::m_pathDependencies)->
|
|
Field("Dependencies Handled", &JobProduct::m_dependenciesHandled);
|
|
|
|
serializeContext->RegisterGenericType<AZStd::vector<JobProduct>>();
|
|
}
|
|
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<JobProduct>("JobProduct")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Constructor()
|
|
->Constructor<const AZStd::string&, AZ::Data::AssetType, AZ::u32>()
|
|
->Property("productFileName", BehaviorValueProperty(&JobProduct::m_productFileName))
|
|
->Property("productAssetType", BehaviorValueProperty(&JobProduct::m_productAssetType))
|
|
->Property("productSubID", BehaviorValueProperty(&JobProduct::m_productSubID))
|
|
->Property("productDependencies", BehaviorValueProperty(&JobProduct::m_dependencies))
|
|
->Property("pathDependencies", BehaviorValueProperty(&JobProduct::m_pathDependencies))
|
|
->Property("dependenciesHandled", BehaviorValueProperty(&JobProduct::m_dependenciesHandled));
|
|
;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void ProcessJobRequest::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<ProcessJobRequest>()->
|
|
Version(2)->
|
|
Field("Source File", &ProcessJobRequest::m_sourceFile)->
|
|
Field("Watch Folder", &ProcessJobRequest::m_watchFolder)->
|
|
Field("Full Path", &ProcessJobRequest::m_fullPath)->
|
|
Field("Builder Guid", &ProcessJobRequest::m_builderGuid)->
|
|
Field("Job Description", &ProcessJobRequest::m_jobDescription)->
|
|
Field("Temp Dir Path", &ProcessJobRequest::m_tempDirPath)->
|
|
Field("Platform Info", &ProcessJobRequest::m_platformInfo)->
|
|
Field("Source File Dependency List", &ProcessJobRequest::m_sourceFileDependencyList)->
|
|
Field("Source File UUID", &ProcessJobRequest::m_sourceFileUUID);
|
|
}
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<ProcessJobRequest>("ProcessJobRequest")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Property("sourceFile", BehaviorValueProperty(&ProcessJobRequest::m_sourceFile))
|
|
->Property("watchFolder", BehaviorValueProperty(&ProcessJobRequest::m_watchFolder))
|
|
->Property("fullPath", BehaviorValueProperty(&ProcessJobRequest::m_fullPath))
|
|
->Property("builderGuid", BehaviorValueProperty(&ProcessJobRequest::m_builderGuid))
|
|
->Property("jobDescription", BehaviorValueProperty(&ProcessJobRequest::m_jobDescription))
|
|
->Property("tempDirPath", BehaviorValueProperty(&ProcessJobRequest::m_tempDirPath))
|
|
->Property("platformInfo", BehaviorValueProperty(&ProcessJobRequest::m_platformInfo))
|
|
->Property("sourceFileDependencyList", BehaviorValueProperty(&ProcessJobRequest::m_sourceFileDependencyList))
|
|
->Property("sourceFileUUID", BehaviorValueProperty(&ProcessJobRequest::m_sourceFileUUID))
|
|
->Property("jobId", BehaviorValueProperty(&ProcessJobRequest::m_jobId));
|
|
}
|
|
}
|
|
|
|
void ProcessJobResponse::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<ProcessJobResponse>()->
|
|
Version(2)->
|
|
Field("Output Products", &ProcessJobResponse::m_outputProducts)->
|
|
Field("Result Code", &ProcessJobResponse::m_resultCode)->
|
|
Field("Requires SubId Generation", &ProcessJobResponse::m_requiresSubIdGeneration)->
|
|
Field("Source To Reprocess", &ProcessJobResponse::m_sourcesToReprocess);
|
|
}
|
|
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<ProcessJobResponse>("ProcessJobResponse")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Property("outputProducts", BehaviorValueProperty(&ProcessJobResponse::m_outputProducts))
|
|
->Property("resultCode", BehaviorValueProperty(&ProcessJobResponse::m_resultCode))
|
|
->Property("requiresSubIdGeneration", BehaviorValueProperty(&ProcessJobResponse::m_requiresSubIdGeneration))
|
|
->Property("sourcesToReprocess", BehaviorValueProperty(&ProcessJobResponse::m_sourcesToReprocess))
|
|
->Enum<aznumeric_cast<int>(ProcessJobResultCode::ProcessJobResult_Success)>("Success")
|
|
->Enum<aznumeric_cast<int>(ProcessJobResultCode::ProcessJobResult_Failed)>("Failed")
|
|
->Enum<aznumeric_cast<int>(ProcessJobResultCode::ProcessJobResult_Crashed)>("Crashed")
|
|
->Enum<aznumeric_cast<int>(ProcessJobResultCode::ProcessJobResult_Cancelled)>("Cancelled")
|
|
->Enum<aznumeric_cast<int>(ProcessJobResultCode::ProcessJobResult_NetworkIssue)>("NetworkIssue");
|
|
}
|
|
}
|
|
|
|
bool ProcessJobResponse::Succeeded() const
|
|
{
|
|
return m_resultCode == ProcessJobResultCode::ProcessJobResult_Success;
|
|
}
|
|
|
|
void InitializeReflectContext(AZ::ReflectContext* context)
|
|
{
|
|
ProductPathDependency::Reflect(context);
|
|
SourceFileDependency::Reflect(context);
|
|
JobDependency::Reflect(context);
|
|
JobDescriptor::Reflect(context);
|
|
AssetBuilderPattern::Reflect(context);
|
|
ProductDependency::Reflect(context);
|
|
JobProduct::Reflect(context);
|
|
AssetBuilderDesc::Reflect(context);
|
|
|
|
RegisterBuilderRequest::Reflect(context);
|
|
RegisterBuilderResponse::Reflect(context);
|
|
CreateJobsRequest::Reflect(context);
|
|
CreateJobsResponse::Reflect(context);
|
|
ProcessJobRequest::Reflect(context);
|
|
ProcessJobResponse::Reflect(context);
|
|
|
|
BuilderHelloRequest::Reflect(context);
|
|
BuilderHelloResponse::Reflect(context);
|
|
CreateJobsNetRequest::Reflect(context);
|
|
CreateJobsNetResponse::Reflect(context);
|
|
ProcessJobNetRequest::Reflect(context);
|
|
ProcessJobNetResponse::Reflect(context);
|
|
}
|
|
|
|
void InitializeSerializationContext()
|
|
{
|
|
AZ::SerializeContext* serializeContext = nullptr;
|
|
|
|
EBUS_EVENT_RESULT(serializeContext, AZ::ComponentApplicationBus, GetSerializeContext);
|
|
AZ_Assert(serializeContext, "Unable to retrieve serialize context.");
|
|
|
|
InitializeReflectContext(serializeContext);
|
|
}
|
|
|
|
void InitializeBehaviorContext()
|
|
{
|
|
AZ::BehaviorContext* behaviorContext = nullptr;
|
|
|
|
EBUS_EVENT_RESULT(behaviorContext, AZ::ComponentApplicationBus, GetBehaviorContext);
|
|
AZ_Error("asset", behaviorContext, "Unable to retrieve behavior context.");
|
|
if (behaviorContext)
|
|
{
|
|
InitializeReflectContext(behaviorContext);
|
|
}
|
|
}
|
|
|
|
AssetBuilderSDK::JobCancelListener::JobCancelListener(AZ::u64 jobId)
|
|
: m_cancelled(false)
|
|
{
|
|
JobCommandBus::Handler::BusConnect(jobId);
|
|
}
|
|
|
|
AssetBuilderSDK::JobCancelListener::~JobCancelListener()
|
|
{
|
|
JobCommandBus::Handler::BusDisconnect();
|
|
}
|
|
|
|
void AssetBuilderSDK::JobCancelListener::Cancel()
|
|
{
|
|
m_cancelled = true;
|
|
}
|
|
|
|
bool AssetBuilderSDK::JobCancelListener::IsCancelled() const
|
|
{
|
|
return m_cancelled;
|
|
}
|
|
|
|
AZStd::string SourceFileDependency::ToString() const
|
|
{
|
|
return AZStd::string::format("SourceFileDependency UUID: %s NAME: %s", m_sourceFileDependencyUUID.ToString<AZStd::string>().c_str(), m_sourceFileDependencyPath.c_str());
|
|
}
|
|
|
|
void SourceFileDependency::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<SourceFileDependency>()->
|
|
Version(2)->
|
|
Field("Source File Dependency Path", &SourceFileDependency::m_sourceFileDependencyPath)->
|
|
Field("Source File Dependency UUID", &SourceFileDependency::m_sourceFileDependencyUUID)->
|
|
Field("Source Dependency Type", &SourceFileDependency::m_sourceDependencyType);
|
|
|
|
serializeContext->RegisterGenericType<AZStd::vector<SourceFileDependency>>();
|
|
}
|
|
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<SourceFileDependency>("SourceFileDependency")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Constructor()
|
|
->Constructor<const AZStd::string&, AZ::Uuid, SourceFileDependency::SourceFileDependencyType>()
|
|
->Property("sourceFileDependencyPath", BehaviorValueProperty(&SourceFileDependency::m_sourceFileDependencyPath))
|
|
->Property("sourceFileDependencyUUID", BehaviorValueProperty(&SourceFileDependency::m_sourceFileDependencyUUID))
|
|
->Property("sourceDependencyType", BehaviorValueProperty(&SourceFileDependency::m_sourceDependencyType))
|
|
->Enum<aznumeric_cast<int>(SourceFileDependency::SourceFileDependencyType::Absolute)>("Absolute")
|
|
->Enum<aznumeric_cast<int>(SourceFileDependency::SourceFileDependencyType::Wildcards)>("Wildcards");
|
|
}
|
|
}
|
|
|
|
void RegisterBuilderRequest::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<RegisterBuilderRequest>()->
|
|
Version(1)->
|
|
Field("FilePath", &RegisterBuilderRequest::m_filePath);
|
|
}
|
|
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<RegisterBuilderRequest>("RegisterBuilderRequest")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Property("filePath", BehaviorValueProperty(&RegisterBuilderRequest::m_filePath));
|
|
}
|
|
}
|
|
|
|
void AssetBuilderDesc::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<AssetBuilderDesc>()
|
|
->Version(2)
|
|
->Field("Flags", &AssetBuilderDesc::m_flags)
|
|
->Field("Name", &AssetBuilderDesc::m_name)
|
|
->Field("Patterns", &AssetBuilderDesc::m_patterns)
|
|
->Field("BusId", &AssetBuilderDesc::m_busId)
|
|
->Field("Version", &AssetBuilderDesc::m_version)
|
|
->Field("AnalysisFingerprint", &AssetBuilderDesc::m_analysisFingerprint)
|
|
->Field("ProductsToKeepOnFailure", &AssetBuilderDesc::m_productsToKeepOnFailure);
|
|
|
|
serializeContext->RegisterGenericType<AZStd::vector<AssetBuilderDesc>>();
|
|
}
|
|
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<AssetBuilderDesc>("AssetBuilderDesc")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Constructor()
|
|
->Property("analysisFingerprint", BehaviorValueProperty(&AssetBuilderDesc::m_analysisFingerprint))
|
|
->Property("busId", BehaviorValueProperty(&AssetBuilderDesc::m_busId))
|
|
->Property("flags", BehaviorValueProperty(&AssetBuilderDesc::m_flags))
|
|
->Property("name", BehaviorValueProperty(&AssetBuilderDesc::m_name))
|
|
->Property("patterns", BehaviorValueProperty(&AssetBuilderDesc::m_patterns))
|
|
->Property("version", BehaviorValueProperty(&AssetBuilderDesc::m_version));
|
|
}
|
|
}
|
|
|
|
void RegisterBuilderResponse::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<RegisterBuilderResponse>()
|
|
->Version(1)
|
|
->Field("Asset Builder Desc List", &RegisterBuilderResponse::m_assetBuilderDescList);
|
|
}
|
|
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<RegisterBuilderResponse>("RegisterBuilderResponse")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Constructor()
|
|
->Property("assetBuilderDescList", BehaviorValueProperty(&RegisterBuilderResponse::m_assetBuilderDescList));
|
|
}
|
|
}
|
|
|
|
bool CreateJobsResponse::Succeeded() const
|
|
{
|
|
return m_result == CreateJobsResultCode::Success;
|
|
}
|
|
|
|
void CreateJobsResponse::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<CreateJobsResponse>()->
|
|
Version(1)->
|
|
Field("Result Code", &CreateJobsResponse::m_result)->
|
|
Field("Source File Dependency List", &CreateJobsResponse::m_sourceFileDependencyList)->
|
|
Field("Create Job Outputs", &CreateJobsResponse::m_createJobOutputs);
|
|
}
|
|
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<CreateJobsResponse>("CreateJobsResponse")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Property("result", BehaviorValueProperty(&CreateJobsResponse::m_result))
|
|
->Property("sourceFileDependencyList", BehaviorValueProperty(&CreateJobsResponse::m_sourceFileDependencyList))
|
|
->Property("createJobOutputs", BehaviorValueProperty(&CreateJobsResponse::m_createJobOutputs))
|
|
->Enum<aznumeric_cast<int>(CreateJobsResultCode::Failed)>("ResultFailed")
|
|
->Enum<aznumeric_cast<int>(CreateJobsResultCode::ShuttingDown)>("ResultShuttingDown")
|
|
->Enum<aznumeric_cast<int>(CreateJobsResultCode::Success)>("ResultSuccess");
|
|
}
|
|
}
|
|
|
|
void BuilderHelloRequest::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
|
if (serialize)
|
|
{
|
|
serialize->Class<BuilderHelloRequest>()
|
|
->Version(1)
|
|
->Field("UUID", &BuilderHelloRequest::m_uuid);
|
|
}
|
|
}
|
|
|
|
unsigned int BuilderHelloRequest::MessageType()
|
|
{
|
|
static unsigned int messageType = AZ_CRC("AssetBuilderSDK::BuilderHelloRequest", 0x213a7248);
|
|
|
|
return messageType;
|
|
}
|
|
|
|
unsigned int BuilderHelloRequest::GetMessageType() const
|
|
{
|
|
return MessageType();
|
|
}
|
|
|
|
void BuilderHelloResponse::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
|
if (serialize)
|
|
{
|
|
serialize->Class<BuilderHelloResponse>()
|
|
->Version(1)
|
|
->Field("Accepted", &BuilderHelloResponse::m_accepted)
|
|
->Field("UUID", &BuilderHelloResponse::m_uuid);
|
|
}
|
|
}
|
|
|
|
unsigned int BuilderHelloResponse::GetMessageType() const
|
|
{
|
|
return BuilderHelloRequest::MessageType();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void CreateJobsNetRequest::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
|
if (serialize)
|
|
{
|
|
serialize->Class<CreateJobsNetRequest>()
|
|
->Version(1)
|
|
->Field("Request", &CreateJobsNetRequest::m_request);
|
|
}
|
|
}
|
|
|
|
unsigned int CreateJobsNetRequest::MessageType()
|
|
{
|
|
static unsigned int messageType = AZ_CRC("AssetBuilderSDK::CreateJobsNetRequest", 0xc48209c0);
|
|
|
|
return messageType;
|
|
}
|
|
|
|
unsigned int CreateJobsNetRequest::GetMessageType() const
|
|
{
|
|
return MessageType();
|
|
}
|
|
|
|
void CreateJobsNetResponse::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
|
if (serialize)
|
|
{
|
|
serialize->Class<CreateJobsNetResponse>()
|
|
->Version(1)
|
|
->Field("Response", &CreateJobsNetResponse::m_response);
|
|
}
|
|
}
|
|
|
|
unsigned int CreateJobsNetResponse::GetMessageType() const
|
|
{
|
|
return CreateJobsNetRequest::MessageType();
|
|
}
|
|
|
|
|
|
|
|
void ProcessJobNetRequest::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
|
if (serialize)
|
|
{
|
|
serialize->Class<ProcessJobNetRequest>()
|
|
->Version(1)
|
|
->Field("Request", &ProcessJobNetRequest::m_request);
|
|
}
|
|
}
|
|
|
|
unsigned int ProcessJobNetRequest::MessageType()
|
|
{
|
|
static unsigned int messageType = AZ_CRC("AssetBuilderSDK::ProcessJobNetRequest", 0x479f340f);
|
|
|
|
return messageType;
|
|
}
|
|
|
|
unsigned int ProcessJobNetRequest::GetMessageType() const
|
|
{
|
|
return MessageType();
|
|
}
|
|
|
|
void ProcessJobNetResponse::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
auto serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
|
if (serialize)
|
|
{
|
|
serialize->Class<ProcessJobNetResponse>()
|
|
->Version(1)
|
|
->Field("Response", &ProcessJobNetResponse::m_response);
|
|
}
|
|
}
|
|
|
|
unsigned int ProcessJobNetResponse::GetMessageType() const
|
|
{
|
|
return ProcessJobNetRequest::MessageType();
|
|
}
|
|
|
|
JobDependency::JobDependency(const AZStd::string& jobKey, const AZStd::string& platformIdentifier, const JobDependencyType& type, const SourceFileDependency& sourceFile)
|
|
: m_jobKey(jobKey)
|
|
, m_platformIdentifier(platformIdentifier)
|
|
, m_type(type)
|
|
, m_sourceFile(sourceFile)
|
|
{
|
|
}
|
|
|
|
void JobDependency::Reflect(AZ::ReflectContext* context)
|
|
{
|
|
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<JobDependency>()->
|
|
Version(1)->
|
|
Field("Source File", &JobDependency::m_sourceFile)->
|
|
Field("Job Key", &JobDependency::m_jobKey)->
|
|
Field("Platform Identifier", &JobDependency::m_platformIdentifier)->
|
|
Field("Job Dependency Type", &JobDependency::m_type);
|
|
|
|
serializeContext->RegisterGenericType<AZStd::vector<JobDependency>>();
|
|
}
|
|
|
|
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
|
{
|
|
behaviorContext->Class<JobDependency>("JobDependency")
|
|
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
|
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
|
|
->Property("sourceFile", BehaviorValueProperty(&JobDependency::m_sourceFile))
|
|
->Property("jobKey", BehaviorValueProperty(&JobDependency::m_jobKey))
|
|
->Property("platformIdentifier", BehaviorValueProperty(&JobDependency::m_platformIdentifier))
|
|
->Property("type", BehaviorValueProperty(&JobDependency::m_type))
|
|
->Enum<aznumeric_cast<int>(JobDependencyType::Fingerprint)>("Fingerprint")
|
|
->Enum<aznumeric_cast<int>(JobDependencyType::Order)>("Order")
|
|
->Enum<aznumeric_cast<int>(JobDependencyType::OrderOnce)>("OrderOnce");
|
|
}
|
|
}
|
|
|
|
AssertAbsorber::AssertAbsorber()
|
|
{
|
|
// only absorb asserts when this object is on scope in the thread that this object is on scope in.
|
|
s_onAbsorbThread = true;
|
|
BusConnect();
|
|
}
|
|
|
|
AssertAbsorber::~AssertAbsorber()
|
|
{
|
|
s_onAbsorbThread = false;
|
|
BusDisconnect();
|
|
}
|
|
|
|
bool AssertAbsorber::OnAssert(const char* message)
|
|
{
|
|
if (s_onAbsorbThread)
|
|
{
|
|
m_assertMessage = message;
|
|
return true; // I handled this, do not forward it
|
|
}
|
|
return false;
|
|
}
|
|
|
|
AZ_THREAD_LOCAL bool AssertAbsorber::s_onAbsorbThread = false;
|
|
|
|
|
|
AssertAndErrorAbsorber::AssertAndErrorAbsorber(bool errorsWillFailJob)
|
|
: m_errorsWillFailJob(errorsWillFailJob)
|
|
, m_jobThreadId(AZStd::this_thread::get_id())
|
|
{
|
|
BusConnect();
|
|
}
|
|
|
|
AssertAndErrorAbsorber::~AssertAndErrorAbsorber()
|
|
{
|
|
BusDisconnect();
|
|
}
|
|
|
|
bool AssertAndErrorAbsorber::OnError(const char*, [[maybe_unused]] const char* message)
|
|
{
|
|
if (AZStd::this_thread::get_id() != m_jobThreadId)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (m_errorsWillFailJob)
|
|
{
|
|
++m_errorsOccurred;
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
AZ_Warning("AssetBuilder", false, "Error: %s", message);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool AssertAndErrorAbsorber::OnAssert([[maybe_unused]] const char* message)
|
|
{
|
|
if (AZStd::this_thread::get_id() != m_jobThreadId)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (m_errorsWillFailJob)
|
|
{
|
|
++m_errorsOccurred;
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
AZ_Warning("", false, "Assert failed: %s", message);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
size_t AssertAndErrorAbsorber::GetErrorCount() const
|
|
{
|
|
return m_errorsOccurred;
|
|
}
|
|
}
|