Add support for configuring default Archive File Search Mode through a Cache Var (#5668)

* Renamed ArchiveLocationPriority enum to FileSearchPriority and made it a proper enum class

Added an ArchiveVars.cpp which checks the a new define: `LY_ARCHIVE_FILE_SEARCH_MODE_DEFAULT`
That define represents the default value to use for the Archive system search mode

Moved the FileSearchLocation enum to the ArchiveVars.h header

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Updated the AssetBundleComponent to use AZ::IO::Path for level dirs

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Added a LY_ARCHIVE_FILE_SEARCH_MODE cache variable

The Cache Variable default value is to Archive File Search Mode to PakOnly
in Release. This can be overridden using a value for all configurations
by specifying a number of 0, 1 or 2.
Alternatively a generator expression can be used to set the Archive File
Search Mode in specific configurations.
For example to set the FileSearchMode to 1 in profile and 2 in release
the following LY_ARCHIVE_FILE_SEARCH_MODE value can be used
`$<$<CONFIG:profile>:1>$<$<CONFIG:release>:2>`

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Updated AssetBundler(Batch) VS Debugger arguments to populate the
project-path optoin if a single project is configured.

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Add support for serializing older versions of the AssetBundleManifest

This is done by attaching the "ObjectStreamWriteElementOverride"
attribute to the AssetBundleManifest reflection.
That attribute contains a function which outputs an older serialized
version of the AssetBundleManifest based on the `m_bundleVersion` member
value.

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* AZStd::variant Serialization fix

The AttributeData<T> type is no longer suitable for storing the
ObjectStreamWriterOverrideCB function

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
This commit is contained in:
lumberyard-employee-dm
2021-11-18 10:22:08 -06:00
committed by GitHub
parent 489877b82a
commit 9d22c98c26
31 changed files with 396 additions and 304 deletions
@@ -10,6 +10,7 @@
#include <AzCore/EBus/EBus.h>
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/IO/Path/Path_fwd.h>
#include <AzCore/std/string/string.h>
#include <AzCore/std/containers/bitset.h>
#include <AzCore/Outcome/Outcome.h>
@@ -129,7 +130,8 @@ namespace AZ
/// Remove a catalog from our delta list and rebuild the catalog from remaining items
virtual bool RemoveDeltaCatalog(AZStd::shared_ptr<AzFramework::AssetRegistry> /*deltaCatalog*/) { return true; }
/// Creates a manifest with the given DeltaCatalog name
virtual bool CreateBundleManifest(const AZStd::string& /*deltaCatalogPath*/, const AZStd::vector<AZStd::string>& /*dependentBundleNames*/, const AZStd::string& /*fileDirectory*/, int /*bundleVersion*/, const AZStd::vector<AZStd::string>& /*levelDirs*/) { return false; }
virtual bool CreateBundleManifest(const AZStd::string& /*deltaCatalogPath*/, const AZStd::vector<AZStd::string>& /*dependentBundleNames*/,
const AZStd::string& /*fileDirectory*/, int /*bundleVersion*/, const AZStd::vector<AZ::IO::Path>& /*levelDirs*/) { return false; }
/// Creates an instance of a registry containing info for just the specified files, and writes it out to a file at the specified path
virtual bool CreateDeltaCatalog(const AZStd::vector<AZStd::string>& /*files*/, const AZStd::string& /*filePath*/) { return false; }
@@ -54,12 +54,8 @@ namespace AZStd
namespace AZ
{
//template<class T>
//class ScriptProperty;
namespace Internal
{
template <class ValueType>
void SetupClassElementFromType(SerializeContext::ClassElement& classElement)
{
@@ -86,8 +82,7 @@ namespace AZ
{
auto uuid = AzTypeInfo<ValueType>::Uuid();
using ContainerType = AttributeContainerType<AZ::TypeId>;
classElement.m_attributes.emplace_back(AZ_CRC("EnumType", 0xb177e1b5), CreateModuleAttribute<ContainerType>(AZStd::move(uuid)));
classElement.m_attributes.emplace_back(AZ_CRC("EnumType", 0xb177e1b5), CreateModuleAttribute(AZStd::move(uuid)));
}
}
@@ -648,7 +643,6 @@ namespace AZ
// Register our key type within an lvalue to rvalue wrapper as an attribute
AZ::TypeId uuid = azrtti_typeid<WrappedKeyType>();
using ContainerType = AttributeContainerType<AZ::TypeId>;
/**
* This should technically bind the reference value from the GetCurrentSerializeContextModule() call
@@ -658,7 +652,7 @@ namespace AZ
*/
m_classElement.m_attributes.set_allocator(AZStdFunctorAllocator([]() -> IAllocatorAllocate& { return GetCurrentSerializeContextModule().GetAllocator(); }));
m_classElement.m_attributes.emplace_back(AZ_CRC("KeyType", 0x15bc5303), CreateModuleAttribute<ContainerType>(AZStd::move(uuid)));
m_classElement.m_attributes.emplace_back(AZ_CRC("KeyType", 0x15bc5303), CreateModuleAttribute(AZStd::move(uuid)));
}
// Reflect our wrapped key and value types to serializeContext so that may later be used
@@ -1643,12 +1643,15 @@ namespace AZ
m_writeElementResultStack.push_back(WriteElement(ptr, classData, classElement));
return m_writeElementResultStack.back();
};
auto closeElementCB = [this, classData]()
auto closeElementCB = [this, classTypeId = classData->m_typeId]()
{
if (m_writeElementResultStack.empty())
{
AZ_UNUSED(classData); // Prevent unused warning in release builds
AZ_Error("Serialize", false, "CloseElement is attempted to be called without a corresponding WriteElement when writing class %s", classData->m_name);
// ClassData could be dangling pointer if it was unreflected by the ObjectStreamWriteOverrideCB
// So use the classTypeId instead
AZ_UNUSED(classTypeId);
AZ_Error("Serialize", false, "CloseElement is attempted to be called without a corresponding WriteElement when writing class %s",
classTypeId.ToString<AZStd::fixed_string<AZ::TypeId::MaxStringBuffer>>().c_str());
return true;
}
if (m_writeElementResultStack.back())
@@ -1665,16 +1668,14 @@ namespace AZ
SerializeContext::ENUM_ACCESS_FOR_READ,
&m_errorLogger
);
ObjectStreamWriteOverrideCB writeCB;
if (objectStreamWriteOverrideCB.Read<ObjectStreamWriteOverrideCB>(writeCB))
if (objectStreamWriteOverrideCB.Invoke<void>(callContext, objectPtr, *classData, classElement))
{
writeCB(callContext, objectPtr, *classData, classElement);
return false;
}
else
{
auto objectStreamError = AZStd::string::format("Unable to invoke ObjectStream Write Element Override for class element %s of class data %s",
classElement->m_name ? classElement->m_name : "", classData->m_name);
classElement && classElement->m_name ? classElement->m_name : "", classData->m_name);
m_errorLogger.ReportError(objectStreamError.c_str());
}
}
@@ -90,7 +90,7 @@ namespace AZ
using AttributePtr = AZStd::shared_ptr<Attribute>;
using AttributeSharedPair = AZStd::pair<AttributeId, AttributePtr>;
template <typename ContainerType, typename T>
template <typename T, typename ContainerType = AttributeContainerType<T>>
AttributePtr CreateModuleAttribute(T&& attrValue);
/**
@@ -540,6 +540,7 @@ namespace AZ
*/
struct ClassElement
{
AZ_TYPE_INFO(ClassElement, "{7D386902-A1D9-4525-8284-F68435FE1D05}");
enum Flags
{
FLG_POINTER = (1 << 0), ///< Element is stored as pointer (it's not a value).
@@ -563,22 +564,22 @@ namespace AZ
void ClearAttributes();
Attribute* FindAttribute(AttributeId attributeId) const;
const char* m_name; ///< Used in XML output and debugging purposes
u32 m_nameCrc; ///< CRC32 of m_name
Uuid m_typeId;
size_t m_dataSize;
size_t m_offset;
const char* m_name{ "" }; ///< Used in XML output and debugging purposes
u32 m_nameCrc{}; ///< CRC32 of m_name
Uuid m_typeId = AZ::TypeId::CreateNull();
size_t m_dataSize{};
size_t m_offset{};
IRttiHelper* m_azRtti; ///< Interface used to support RTTI.
IRttiHelper* m_azRtti{}; ///< Interface used to support RTTI.
GenericClassInfo* m_genericClassInfo = nullptr; ///< Valid when the generic class is set. So you don't search for the actual type in the class register.
Edit::ElementData* m_editData; ///< Pointer to edit data (generated by EditContext).
Edit::ElementData* m_editData{}; ///< Pointer to edit data (generated by EditContext).
AZStd::vector<AttributeSharedPair, AZStdFunctorAllocator> m_attributes{
AZStdFunctorAllocator([]() -> IAllocatorAllocate& { return AZ::AllocatorInstance<AZ::SystemAllocator>::Get(); })
}; ///< Attributes attached to ClassElement. Lambda is required here as AZStdFunctorAllocator expects a function pointer
///< that returns an IAllocatorAllocate& and the AZ::AllocatorInstance<AZ::SystemAllocator>::Get returns an AZ::SystemAllocator&
/// which while it inherits from IAllocatorAllocate, does not work as function pointers do not support covariant return types
AttributeOwnership m_attributeOwnership = AttributeOwnership::Parent;
int m_flags; ///<
int m_flags{}; ///<
};
typedef AZStd::vector<ClassElement> ClassElementArray;
@@ -589,6 +590,8 @@ namespace AZ
class ClassData
{
public:
AZ_TYPE_INFO(ClassData, "{20EB8E2E-D807-4039-84E2-CE37D7647CD4}");
ClassData();
~ClassData() { ClearAttributes(); }
ClassData(ClassData&&) = default;
@@ -1040,6 +1043,7 @@ namespace AZ
*/
struct EnumerateInstanceCallContext
{
AZ_TYPE_INFO(EnumerateInstanceCallContext, "{FCC1DB4B-72BD-4D78-9C23-C84B91589D33}");
EnumerateInstanceCallContext(const BeginElemEnumCB& beginElemCB, const EndElemEnumCB& endElemCB, const SerializeContext* context, unsigned int accessflags, ErrorHandler* errorHandler);
BeginElemEnumCB m_beginElemCB; ///< Optional callback when entering an element's hierarchy.
@@ -2539,7 +2543,7 @@ namespace AZ
/// associated with current module
/// @param attrValue value to store within the attribute
/// @param ContainerType second parameter which is used for function parameter deduction
template <typename ContainerType, typename T>
template <typename T, typename ContainerType>
AttributePtr CreateModuleAttribute(T&& attrValue)
{
IAllocatorAllocate& moduleAllocator = GetCurrentSerializeContextModule().GetAllocator();
@@ -433,9 +433,7 @@ namespace AZ
m_classData.m_attributes.set_allocator(AZStd::move(dllAllocator));
// Create the ObjectStreamWriteOverrideCB in the current module
using ContainerType = AttributeData<AZStd::function<void(SerializeContext::EnumerateInstanceCallContext&,
const void*, const SerializeContext::ClassData&, const SerializeContext::ClassElement*)>>;
m_classData.m_attributes.emplace_back(AZ_CRC("ObjectStreamWriteElementOverride", 0x35eb659f), CreateModuleAttribute<ContainerType>(&ObjectStreamWriter));
m_classData.m_attributes.emplace_back(AZ_CRC("ObjectStreamWriteElementOverride", 0x35eb659f), CreateModuleAttribute(&ObjectStreamWriter));
}
SerializeContext::ClassData* GetClassData() override