Merge branch 'development' into Prefab/DestroyGameEntitySupport
Signed-off-by: srikappa-amzn <srikappa@amazon.com>
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/functional.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
//! Sets a variable upon construction and again when the object goes out of scope.
|
||||
template<typename T>
|
||||
class ScopedValue
|
||||
{
|
||||
private:
|
||||
T* m_ptr;
|
||||
T m_finalValue;
|
||||
|
||||
public:
|
||||
ScopedValue(T* ptr, T initialValue, T finalValue) :
|
||||
m_ptr(ptr), m_finalValue(finalValue)
|
||||
{
|
||||
AZ_Assert(m_ptr, "ScopedValue::m_ptr is null");
|
||||
*m_ptr = initialValue;
|
||||
}
|
||||
|
||||
~ScopedValue()
|
||||
{
|
||||
*m_ptr = m_finalValue;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace AZ
|
||||
@@ -19,4 +19,5 @@ set(FILES
|
||||
std/containers/vector_set.h
|
||||
std/containers/vector_set_base.h
|
||||
std/parallel/concurrency_checker.h
|
||||
Utils/ScopedValue.h
|
||||
)
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AtomCore/Utils/ScopedValue.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
TEST(ScopedValueTest, TestBoolValue)
|
||||
{
|
||||
bool localValue = false;
|
||||
|
||||
{
|
||||
AZ::ScopedValue<bool> scopedValue(&localValue, true, false);
|
||||
EXPECT_EQ(true, localValue);
|
||||
}
|
||||
|
||||
EXPECT_EQ(false, localValue);
|
||||
}
|
||||
|
||||
TEST(ScopedValueTest, TestIntValue)
|
||||
{
|
||||
int localValue = 0;
|
||||
|
||||
{
|
||||
AZ::ScopedValue<int> scopedValue(&localValue, 1, 2);
|
||||
EXPECT_EQ(1, localValue);
|
||||
}
|
||||
|
||||
EXPECT_EQ(2, localValue);
|
||||
}
|
||||
}
|
||||
@@ -12,5 +12,6 @@ set(FILES
|
||||
InstanceDatabase.cpp
|
||||
lru_cache.cpp
|
||||
Main.cpp
|
||||
ScopedValueTest.cpp
|
||||
vector_set.cpp
|
||||
)
|
||||
|
||||
@@ -266,7 +266,7 @@ namespace AZ
|
||||
_ComponentClass::RTTI_Type().ToString<AZStd::string>().c_str(), descriptor->GetName(), _ComponentClass::RTTI_TypeName()); \
|
||||
return nullptr; \
|
||||
} \
|
||||
else if (descriptor->GetName() != _ComponentClass::RTTI_TypeName()) \
|
||||
if (descriptor->GetName() != _ComponentClass::RTTI_TypeName()) \
|
||||
{ \
|
||||
AZ_Error("Component", false, "The same component UUID (%s) / name (%s) was registered twice. This isn't allowed, " \
|
||||
"it can cause lifetime management issues / crashes.\nThis situation can happen by declaring a component " \
|
||||
|
||||
@@ -1251,6 +1251,8 @@ namespace AZ
|
||||
|
||||
return AZ::SettingsRegistryInterface::VisitResponse::Continue;
|
||||
}
|
||||
|
||||
using SettingsRegistryInterface::Visitor::Visit;
|
||||
void Visit(AZStd::string_view path, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type, bool value) override
|
||||
{
|
||||
// By default the auto load option is true
|
||||
|
||||
@@ -196,14 +196,14 @@ namespace AZ
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ComponentApplicationRequests
|
||||
void RegisterComponentDescriptor(const ComponentDescriptor* descriptor) override final;
|
||||
void UnregisterComponentDescriptor(const ComponentDescriptor* descriptor) override final;
|
||||
void RegisterEntityAddedEventHandler(EntityAddedEvent::Handler& handler) override final;
|
||||
void RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler& handler) override final;
|
||||
void RegisterEntityActivatedEventHandler(EntityActivatedEvent::Handler& handler) override final;
|
||||
void RegisterEntityDeactivatedEventHandler(EntityDeactivatedEvent::Handler& handler) override final;
|
||||
void SignalEntityActivated(Entity* entity) override final;
|
||||
void SignalEntityDeactivated(Entity* entity) override final;
|
||||
void RegisterComponentDescriptor(const ComponentDescriptor* descriptor) final;
|
||||
void UnregisterComponentDescriptor(const ComponentDescriptor* descriptor) final;
|
||||
void RegisterEntityAddedEventHandler(EntityAddedEvent::Handler& handler) final;
|
||||
void RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler& handler) final;
|
||||
void RegisterEntityActivatedEventHandler(EntityActivatedEvent::Handler& handler) final;
|
||||
void RegisterEntityDeactivatedEventHandler(EntityDeactivatedEvent::Handler& handler) final;
|
||||
void SignalEntityActivated(Entity* entity) final;
|
||||
void SignalEntityDeactivated(Entity* entity) final;
|
||||
bool AddEntity(Entity* entity) override;
|
||||
bool RemoveEntity(Entity* entity) override;
|
||||
bool DeleteEntity(const EntityId& id) override;
|
||||
|
||||
@@ -207,12 +207,6 @@ namespace AZ
|
||||
ActivateComponent(**it);
|
||||
}
|
||||
|
||||
// Cache the transform interface to the transform interface
|
||||
// Generally this pattern is not recommended unless for component event buses
|
||||
// As we have a guarantee (by design) that components can't change during active state)
|
||||
// Even though technically they can connect disconnect from the bus.
|
||||
m_transform = TransformBus::FindFirstHandler(m_id);
|
||||
|
||||
SetState(State::Active);
|
||||
|
||||
EBUS_EVENT_ID(m_id, EntityBus, OnEntityActivated, m_id);
|
||||
@@ -1330,6 +1324,19 @@ namespace AZ
|
||||
return *processSignature;
|
||||
}
|
||||
|
||||
AZ::TransformInterface* Entity::GetTransform() const
|
||||
{
|
||||
// Lazy evaluation of the cached entity transform.
|
||||
if(!m_transform)
|
||||
{
|
||||
// Generally this pattern is not recommended unless for component event buses
|
||||
// As we have a guarantee (by design) that components can't change during active state)
|
||||
// Even though technically they can connect disconnect from the bus.
|
||||
m_transform = TransformBus::FindFirstHandler(m_id);
|
||||
}
|
||||
return m_transform;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// MakeId
|
||||
// Ids must be unique across a project at authoring time. Runtime doesn't matter
|
||||
|
||||
@@ -362,10 +362,9 @@ namespace AZ
|
||||
//! @return The Process Signature of the local machine.
|
||||
static AZ::u32 GetProcessSignature();
|
||||
|
||||
/// @cond EXCLUDE_DOCS
|
||||
//! @deprecated Use the TransformBus to communicate with the TransformInterface.
|
||||
inline TransformInterface* GetTransform() const { return m_transform; }
|
||||
/// @endcond
|
||||
//! Gets the TransformInterface for the entity.
|
||||
//! @return The TransformInterface for the entity.
|
||||
TransformInterface* GetTransform() const;
|
||||
|
||||
//! Sorts an entity's components based on the dependencies between components.
|
||||
//! If all dependencies are met, the required services can be activated
|
||||
@@ -414,7 +413,7 @@ namespace AZ
|
||||
//! A cached pointer to the transform interface.
|
||||
//! We recommend using AZ::TransformBus and caching locally instead of accessing
|
||||
//! the transform interface directly through this pointer.
|
||||
TransformInterface* m_transform;
|
||||
mutable TransformInterface* m_transform;
|
||||
|
||||
//! A user-friendly name for the entity. This makes error messages easier to read.
|
||||
AZStd::string m_name;
|
||||
|
||||
@@ -86,6 +86,7 @@ namespace AZ
|
||||
class AssetTreeNodeBase
|
||||
{
|
||||
public:
|
||||
virtual ~AssetTreeNodeBase() = default;
|
||||
virtual const AssetPrimaryInfo* GetAssetPrimaryInfo() const = 0;
|
||||
virtual AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetPrimaryInfo* info) = 0;
|
||||
};
|
||||
@@ -94,6 +95,7 @@ namespace AZ
|
||||
class AssetTreeBase
|
||||
{
|
||||
public:
|
||||
virtual ~AssetTreeBase() = default;
|
||||
virtual AssetTreeNodeBase& GetRoot() = 0;
|
||||
};
|
||||
|
||||
@@ -101,6 +103,7 @@ namespace AZ
|
||||
class AssetAllocationTableBase
|
||||
{
|
||||
public:
|
||||
virtual ~AssetAllocationTableBase() = default;
|
||||
virtual AssetTreeNodeBase* FindAllocation(void* ptr) const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ namespace AZ
|
||||
{
|
||||
}
|
||||
|
||||
~AssetTreeNode() override = default;
|
||||
|
||||
const AssetPrimaryInfo* GetAssetPrimaryInfo() const override
|
||||
{
|
||||
return m_primaryinfo;
|
||||
@@ -67,6 +69,8 @@ namespace AZ
|
||||
class AssetTree : public AssetTreeBase
|
||||
{
|
||||
public:
|
||||
~AssetTree() override = default;
|
||||
|
||||
AssetTreeNodeBase& GetRoot() override
|
||||
{
|
||||
return m_rootAssets;
|
||||
@@ -99,6 +103,7 @@ namespace AZ
|
||||
AllocationTable(mutex_type& mutex) : m_mutex(mutex)
|
||||
{
|
||||
}
|
||||
~AllocationTable() override = default;
|
||||
|
||||
AssetTreeNodeBase* FindAllocation(void* ptr) const override
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace AZ::Debug
|
||||
class BudgetTracker
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(BudgetTracker, "{E14A746D-BFFE-4C02-90FB-4699B79864A5}");
|
||||
AZ_TYPE_INFO(BudgetTracker, "{E14A746D-BFFE-4C02-90FB-4699B79864A5}");
|
||||
static Budget* GetBudgetFromEnvironment(const char* budgetName, uint32_t crc);
|
||||
|
||||
~BudgetTracker();
|
||||
|
||||
@@ -59,6 +59,20 @@ namespace AZStd
|
||||
|
||||
namespace AZ::Debug
|
||||
{
|
||||
// interface for externally defined profiler systems
|
||||
class Profiler
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(Profiler, "{3E5D6329-72D1-41BA-9158-68A349D1A4D5}");
|
||||
|
||||
Profiler() = default;
|
||||
virtual ~Profiler() = default;
|
||||
|
||||
// support for the extra macro args (e.g. format strings) will come in a later PR
|
||||
virtual void BeginRegion(const Budget* budget, const char* eventName) = 0;
|
||||
virtual void EndRegion(const Budget* budget) = 0;
|
||||
};
|
||||
|
||||
class ProfileScope
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
|
||||
namespace AZ::Debug
|
||||
{
|
||||
template<typename... T>
|
||||
@@ -22,9 +24,11 @@ namespace AZ::Debug
|
||||
PIXBeginEvent(PIX_COLOR_INDEX(budget->Crc() & 0xff), eventName, args...);
|
||||
#endif
|
||||
budget->BeginProfileRegion();
|
||||
// TODO: injecting instrumentation for other profilers
|
||||
// NOTE: external profiler registration won't occur inline in a header necessarily in this manner, but the exact mechanism
|
||||
// will be introduced in a future PR
|
||||
|
||||
if (auto profiler = AZ::Interface<Profiler>::Get(); profiler)
|
||||
{
|
||||
profiler->BeginRegion(budget, eventName);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -39,6 +43,10 @@ namespace AZ::Debug
|
||||
#if defined(USE_PIX)
|
||||
PIXEndEvent();
|
||||
#endif
|
||||
if (auto profiler = AZ::Interface<Profiler>::Get(); profiler)
|
||||
{
|
||||
profiler->EndRegion(budget);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -28,21 +28,21 @@ namespace AZ
|
||||
protected:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Driller
|
||||
virtual const char* GroupName() const { return "SystemDrillers"; }
|
||||
virtual const char* GetName() const { return "TraceMessagesDriller"; }
|
||||
virtual const char* GetDescription() const { return "Handles all system messages like Assert, Exception, Error, Warning, Printf, etc."; }
|
||||
virtual void Start(const Param* params = NULL, int numParams = 0);
|
||||
virtual void Stop();
|
||||
const char* GroupName() const override { return "SystemDrillers"; }
|
||||
const char* GetName() const override { return "TraceMessagesDriller"; }
|
||||
const char* GetDescription() const override { return "Handles all system messages like Assert, Exception, Error, Warning, Printf, etc."; }
|
||||
void Start(const Param* params = NULL, int numParams = 0) override;
|
||||
void Stop() override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TraceMessagesDrillerBus
|
||||
/// Triggered when a AZ_Assert failed. This is terminating event! (the code will break, crash).
|
||||
virtual void OnAssert(const char* message);
|
||||
virtual void OnException(const char* message);
|
||||
virtual void OnError(const char* window, const char* message);
|
||||
virtual void OnWarning(const char* window, const char* message);
|
||||
virtual void OnPrintf(const char* window, const char* message);
|
||||
void OnAssert(const char* message) override;
|
||||
void OnException(const char* message) override;
|
||||
void OnError(const char* window, const char* message) override;
|
||||
void OnWarning(const char* window, const char* message) override;
|
||||
void OnPrintf(const char* window, const char* message) override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
} // namespace Debug
|
||||
|
||||
@@ -443,7 +443,7 @@ namespace AZ
|
||||
const unsigned char* GetData() const { return m_data.data(); }
|
||||
unsigned int GetDataSize() const { return static_cast<unsigned int>(m_data.size()); }
|
||||
inline void Reset() { m_data.clear(); }
|
||||
virtual void WriteBinary(const void* data, unsigned int dataSize)
|
||||
void WriteBinary(const void* data, unsigned int dataSize) override
|
||||
{
|
||||
m_data.insert(m_data.end(), reinterpret_cast<const unsigned char*>(data), reinterpret_cast<const unsigned char*>(data) + dataSize);
|
||||
}
|
||||
@@ -489,7 +489,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
unsigned int GetDataLeft() const { return static_cast<unsigned int>(m_dataEnd - m_data); }
|
||||
virtual unsigned int ReadBinary(void* data, unsigned int maxDataSize)
|
||||
unsigned int ReadBinary(void* data, unsigned int maxDataSize) override
|
||||
{
|
||||
AZ_Assert(m_data != nullptr, "You must call SetData function, before you can read data!");
|
||||
AZ_Assert(data != nullptr && maxDataSize > 0, "We must have a valid pointer and max data size!");
|
||||
@@ -523,7 +523,7 @@ namespace AZ
|
||||
bool Open(const char* fileName, int mode, int platformFlags = 0);
|
||||
void Close();
|
||||
|
||||
virtual void WriteBinary(const void* data, unsigned int dataSize);
|
||||
void WriteBinary(const void* data, unsigned int dataSize) override;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -540,7 +540,7 @@ namespace AZ
|
||||
DrillerInputFileStream();
|
||||
~DrillerInputFileStream();
|
||||
bool Open(const char* fileName, int mode, int platformFlags = 0);
|
||||
virtual unsigned int ReadBinary(void* data, unsigned int maxDataSize);
|
||||
unsigned int ReadBinary(void* data, unsigned int maxDataSize) override;
|
||||
void Close();
|
||||
};
|
||||
|
||||
|
||||
@@ -1717,6 +1717,7 @@ AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
EBusRouterNode<typename EBus::InterfaceType> m_routerNode;
|
||||
public:
|
||||
virtual ~EBusNestedVersionRouter() = default;
|
||||
template<class Container>
|
||||
void BusRouterConnect(Container& container, int order = 0);
|
||||
|
||||
|
||||
@@ -98,21 +98,21 @@ namespace AZ
|
||||
|
||||
/// Return compressor type id.
|
||||
static AZ::u32 TypeId();
|
||||
virtual AZ::u32 GetTypeId() const { return TypeId(); }
|
||||
AZ::u32 GetTypeId() const override { return TypeId(); }
|
||||
/// Called when we open a stream to Read for the first time. Data contains the first. dataSize <= m_maxHeaderSize.
|
||||
virtual bool ReadHeaderAndData(CompressorStream* stream, AZ::u8* data, unsigned int dataSize);
|
||||
bool ReadHeaderAndData(CompressorStream* stream, AZ::u8* data, unsigned int dataSize) override;
|
||||
/// Called when we are about to start writing to a compressed stream.
|
||||
virtual bool WriteHeaderAndData(CompressorStream* stream);
|
||||
bool WriteHeaderAndData(CompressorStream* stream) override;
|
||||
/// Forwarded function from the Device when we from a compressed stream.
|
||||
virtual SizeType Read(CompressorStream* stream, SizeType byteSize, SizeType offset, void* buffer);
|
||||
SizeType Read(CompressorStream* stream, SizeType byteSize, SizeType offset, void* buffer) override;
|
||||
/// Forwarded function from the Device when we write to a compressed stream.
|
||||
virtual SizeType Write(CompressorStream* stream, SizeType byteSize, const void* data, SizeType offset = SizeType(-1));
|
||||
SizeType Write(CompressorStream* stream, SizeType byteSize, const void* data, SizeType offset = SizeType(-1)) override;
|
||||
/// Write a seek point.
|
||||
virtual bool WriteSeekPoint(CompressorStream* stream);
|
||||
bool WriteSeekPoint(CompressorStream* stream) override;
|
||||
/// Set auto seek point even dataSize bytes.
|
||||
virtual bool StartCompressor(CompressorStream* stream, int compressionLevel, SizeType autoSeekDataSize);
|
||||
bool StartCompressor(CompressorStream* stream, int compressionLevel, SizeType autoSeekDataSize) override;
|
||||
/// Called just before we close the stream. All compression data will be flushed and finalized. (You can't add data afterwards).
|
||||
virtual bool Close(CompressorStream* stream);
|
||||
bool Close(CompressorStream* stream) override;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/IO/FileReader.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
FileReader::FileReader() = default;
|
||||
|
||||
FileReader::FileReader(AZ::IO::FileIOBase* fileIoBase, const char* filePath)
|
||||
{
|
||||
Open(fileIoBase, filePath);
|
||||
}
|
||||
|
||||
FileReader::~FileReader()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
FileReader::FileReader(FileReader&& other)
|
||||
{
|
||||
AZStd::swap(m_file, other.m_file);
|
||||
AZStd::swap(m_fileIoBase, other.m_fileIoBase);
|
||||
}
|
||||
|
||||
FileReader& FileReader::operator=(FileReader&& other)
|
||||
{
|
||||
// Close the current file and take over other file
|
||||
Close();
|
||||
m_file = AZStd::move(other.m_file);
|
||||
m_fileIoBase = AZStd::move(other.m_fileIoBase);
|
||||
other.m_file = AZStd::monostate{};
|
||||
other.m_fileIoBase = {};
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool FileReader::Open(AZ::IO::FileIOBase* fileIoBase, const char* filePath)
|
||||
{
|
||||
// Close file if the FileReader has an instance open
|
||||
Close();
|
||||
|
||||
if (fileIoBase != nullptr)
|
||||
{
|
||||
AZ::IO::HandleType fileHandle;
|
||||
if (fileIoBase->Open(filePath, IO::OpenMode::ModeRead, fileHandle))
|
||||
{
|
||||
m_file = fileHandle;
|
||||
m_fileIoBase = fileIoBase;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ::IO::SystemFile file;
|
||||
if (file.Open(filePath, IO::SystemFile::OpenMode::SF_OPEN_READ_ONLY))
|
||||
{
|
||||
m_file = AZStd::move(file);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileReader::IsOpen() const
|
||||
{
|
||||
if (auto fileHandle = AZStd::get_if<AZ::IO::HandleType>(&m_file); fileHandle != nullptr)
|
||||
{
|
||||
return *fileHandle != AZ::IO::InvalidHandle;
|
||||
}
|
||||
else if (auto systemFile = AZStd::get_if<AZ::IO::SystemFile>(&m_file); systemFile != nullptr)
|
||||
{
|
||||
return systemFile->IsOpen();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void FileReader::Close()
|
||||
{
|
||||
if (auto fileHandle = AZStd::get_if<AZ::IO::HandleType>(&m_file); fileHandle != nullptr)
|
||||
{
|
||||
if (AZ::IO::FileIOBase* fileIo = m_fileIoBase; fileIo != nullptr)
|
||||
{
|
||||
fileIo->Close(*fileHandle);
|
||||
}
|
||||
}
|
||||
|
||||
m_file = AZStd::monostate{};
|
||||
m_fileIoBase = {};
|
||||
}
|
||||
|
||||
auto FileReader::Length() const -> SizeType
|
||||
{
|
||||
if (auto fileHandle = AZStd::get_if<AZ::IO::HandleType>(&m_file); fileHandle != nullptr)
|
||||
{
|
||||
if (SizeType fileSize{}; m_fileIoBase->Size(*fileHandle, fileSize))
|
||||
{
|
||||
return fileSize;
|
||||
}
|
||||
}
|
||||
else if (auto systemFile = AZStd::get_if<AZ::IO::SystemFile>(&m_file); systemFile != nullptr)
|
||||
{
|
||||
return systemFile->Length();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto FileReader::Read(SizeType byteSize, void* buffer) -> SizeType
|
||||
{
|
||||
if (auto fileHandle = AZStd::get_if<AZ::IO::HandleType>(&m_file); fileHandle != nullptr)
|
||||
{
|
||||
if (SizeType bytesRead{}; m_fileIoBase->Read(*fileHandle, buffer, byteSize, false, &bytesRead))
|
||||
{
|
||||
return bytesRead;
|
||||
}
|
||||
}
|
||||
else if (auto systemFile = AZStd::get_if<AZ::IO::SystemFile>(&m_file); systemFile != nullptr)
|
||||
{
|
||||
return systemFile->Read(byteSize, buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto FileReader::Tell() const -> SizeType
|
||||
{
|
||||
if (auto fileHandle = AZStd::get_if<AZ::IO::HandleType>(&m_file); fileHandle != nullptr)
|
||||
{
|
||||
if (SizeType fileOffset{}; m_fileIoBase->Tell(*fileHandle, fileOffset))
|
||||
{
|
||||
return fileOffset;
|
||||
}
|
||||
}
|
||||
else if (auto systemFile = AZStd::get_if<AZ::IO::SystemFile>(&m_file); systemFile != nullptr)
|
||||
{
|
||||
return systemFile->Tell();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FileReader::Seek(AZ::s64 offset, SeekType type)
|
||||
{
|
||||
if (auto fileHandle = AZStd::get_if<AZ::IO::HandleType>(&m_file); fileHandle != nullptr)
|
||||
{
|
||||
return m_fileIoBase->Seek(*fileHandle, offset, type);
|
||||
}
|
||||
else if (auto systemFile = AZStd::get_if<AZ::IO::SystemFile>(&m_file); systemFile != nullptr)
|
||||
{
|
||||
systemFile->Seek(offset, static_cast<AZ::IO::SystemFile::SeekMode>(type));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileReader::Eof() const
|
||||
{
|
||||
if (auto fileHandle = AZStd::get_if<AZ::IO::HandleType>(&m_file); fileHandle != nullptr)
|
||||
{
|
||||
return m_fileIoBase->Eof(*fileHandle);
|
||||
}
|
||||
else if (auto systemFile = AZStd::get_if<AZ::IO::SystemFile>(&m_file); systemFile != nullptr)
|
||||
{
|
||||
return systemFile->Eof();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileReader::GetFilePath(AZ::IO::FixedMaxPath& filePath) const
|
||||
{
|
||||
if (auto fileHandle = AZStd::get_if<AZ::IO::HandleType>(&m_file); fileHandle != nullptr)
|
||||
{
|
||||
AZ::IO::FixedMaxPathString& pathStringRef = filePath.Native();
|
||||
if (m_fileIoBase->GetFilename(*fileHandle, pathStringRef.data(), pathStringRef.capacity()))
|
||||
{
|
||||
pathStringRef.resize_no_construct(AZStd::char_traits<char>::length(pathStringRef.data()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (auto systemFile = AZStd::get_if<AZ::IO::SystemFile>(&m_file); systemFile != nullptr)
|
||||
{
|
||||
filePath = systemFile->Name();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/IO/Path/Path_fwd.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
class FileIOBase;
|
||||
enum class SeekType : AZ::u32;
|
||||
|
||||
//! Structure which encapsulates delegates File Read operations
|
||||
//! to either the FileIOBase or SystemFile classes based if a FileIOBase* instance has been supplied
|
||||
//! to the FileSystemReader class
|
||||
//! the SettingsRegistry option to use FileIO
|
||||
class FileReader
|
||||
{
|
||||
using HandleType = AZ::u32;
|
||||
using FileHandleType = AZStd::variant<AZStd::monostate, AZ::IO::SystemFile, HandleType>;
|
||||
public:
|
||||
using SizeType = AZ::u64;
|
||||
|
||||
//! Creates FileReader instance in the default state with no file opend
|
||||
FileReader();
|
||||
~FileReader();
|
||||
|
||||
//! Creates a new FileReader instance and attempts to open the file at the supplied path
|
||||
//! Uses the FileIOBase instance if supplied
|
||||
//! @param fileIOBase pointer to fileIOBase instance
|
||||
//! @param null-terminated filePath to open
|
||||
FileReader(AZ::IO::FileIOBase* fileIoBase, const char* filePath);
|
||||
|
||||
//! Takes ownership of the supplied FileReader handle
|
||||
FileReader(FileReader&& other);
|
||||
|
||||
//! Moves ownership of FileReader handle to this instance
|
||||
FileReader& operator=(FileReader&& other);
|
||||
|
||||
//! Opens a File using the FileIOBase instance if non-nullptr
|
||||
//! Otherwise fall back to use SystemFile
|
||||
//! @param fileIOBase pointer to fileIOBase instance
|
||||
//! @param null-terminated filePath to open
|
||||
//! @return true if the File is opened successfully
|
||||
bool Open(AZ::IO::FileIOBase* fileIoBase, const char* filePath);
|
||||
|
||||
//! Returns true if a file is currently open
|
||||
//! @return true if the file is open
|
||||
bool IsOpen() const;
|
||||
|
||||
//! Closes the File
|
||||
void Close();
|
||||
|
||||
//! Retrieve the length of the OpenFile
|
||||
SizeType Length() const;
|
||||
|
||||
//! Attempts to read up to byte size bytes into the supplied buffer
|
||||
//! @param byteSize - Maximum number of bytes to read
|
||||
//! @param buffer - Buffer to read bytes into
|
||||
//! @returns the number of bytes read if the file is open, otherwise 0
|
||||
SizeType Read(SizeType byteSize, void* buffer);
|
||||
|
||||
//! Returns the current file offset
|
||||
//! @returns file offset if the file is open, otherwise 0
|
||||
SizeType Tell() const;
|
||||
|
||||
//! Seeks within the open file to the offset supplied
|
||||
//! @param offset File offset to seek to
|
||||
//! @param type parameter to indicate the reference point to start the seek from
|
||||
//! @returns true if the file is open and the seek succeeded
|
||||
bool Seek(AZ::s64 offset, SeekType type);
|
||||
|
||||
//! Returns true if the file is open and in the EOF state
|
||||
bool Eof() const;
|
||||
|
||||
//! Store the file path of the open file into the output file path parameter
|
||||
//! The filePath reference is left unmodified, if the path was not stored
|
||||
//! @return true if the filePath was stored
|
||||
bool GetFilePath(AZ::IO::FixedMaxPath& filePath) const;
|
||||
|
||||
private:
|
||||
|
||||
FileHandleType m_file;
|
||||
AZ::IO::FileIOBase* m_fileIoBase{};
|
||||
};
|
||||
}
|
||||
@@ -160,12 +160,12 @@ void SystemFile::Seek(SeekSizeType offset, SeekMode mode)
|
||||
Platform::Seek(m_handle, this, offset, mode);
|
||||
}
|
||||
|
||||
SystemFile::SizeType SystemFile::Tell()
|
||||
SystemFile::SizeType SystemFile::Tell() const
|
||||
{
|
||||
return Platform::Tell(m_handle, this);
|
||||
}
|
||||
|
||||
bool SystemFile::Eof()
|
||||
bool SystemFile::Eof() const
|
||||
{
|
||||
return Platform::Eof(m_handle, this);
|
||||
}
|
||||
|
||||
@@ -72,9 +72,9 @@ namespace AZ
|
||||
/// Seek in current file.
|
||||
void Seek(SeekSizeType offset, SeekMode mode);
|
||||
/// Get the cursor position in the current file.
|
||||
SizeType Tell();
|
||||
SizeType Tell() const;
|
||||
/// Is the cursor at the end of the file?
|
||||
bool Eof();
|
||||
bool Eof() const;
|
||||
/// Get the time the file was last modified.
|
||||
AZ::u64 ModificationTime();
|
||||
/// Read data from a file synchronous. Return number of bytes actually read in the buffer.
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace AZ
|
||||
{
|
||||
}
|
||||
protected:
|
||||
virtual void Process()
|
||||
void Process() override
|
||||
{
|
||||
m_notifyFlag->store(true, AZStd::memory_order_release);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace AZ
|
||||
: public Sample<Vector3>
|
||||
{
|
||||
public:
|
||||
Vector3 GetInterpolatedValue(TimeType time) override final
|
||||
Vector3 GetInterpolatedValue(TimeType time) final
|
||||
{
|
||||
Vector3 interpolatedValue = m_previousValue;
|
||||
if (m_targetTimestamp != 0)
|
||||
@@ -108,7 +108,7 @@ namespace AZ
|
||||
: public Sample<Quaternion>
|
||||
{
|
||||
public:
|
||||
Quaternion GetInterpolatedValue(TimeType time) override final
|
||||
Quaternion GetInterpolatedValue(TimeType time) final
|
||||
{
|
||||
Quaternion interpolatedValue = m_previousValue;
|
||||
if (m_targetTimestamp != 0)
|
||||
@@ -144,7 +144,7 @@ namespace AZ
|
||||
: public Sample<Vector3>
|
||||
{
|
||||
public:
|
||||
Vector3 GetInterpolatedValue(TimeType /*time*/) override final
|
||||
Vector3 GetInterpolatedValue(TimeType /*time*/) final
|
||||
{
|
||||
return GetTargetValue();
|
||||
}
|
||||
@@ -155,7 +155,7 @@ namespace AZ
|
||||
: public Sample<Quaternion>
|
||||
{
|
||||
public:
|
||||
Quaternion GetInterpolatedValue(TimeType /*time*/) override final
|
||||
Quaternion GetInterpolatedValue(TimeType /*time*/) final
|
||||
{
|
||||
return GetTargetValue();
|
||||
}
|
||||
|
||||
@@ -353,6 +353,7 @@ namespace AZ
|
||||
Method("CreateFromMatrix3x3AndTranslation", &Transform::CreateFromMatrix3x3AndTranslation)->
|
||||
Method("CreateUniformScale", &Transform::CreateUniformScale)->
|
||||
Method("CreateTranslation", &Transform::CreateTranslation)->
|
||||
Method("CreateLookAt", &Transform::CreateLookAt)->
|
||||
Method("ConstructFromValuesNumeric", &Internal::ConstructTransformFromValues);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,18 +48,18 @@ namespace AZ
|
||||
HeapSchema(const Descriptor& desc);
|
||||
virtual ~HeapSchema();
|
||||
|
||||
virtual pointer_type Allocate(size_type byteSize, size_type alignment, int flags, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0);
|
||||
virtual void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0);
|
||||
virtual pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) { (void)ptr; (void)newSize; (void)newAlignment; return NULL; }
|
||||
virtual size_type Resize(pointer_type ptr, size_type newSize) { (void)ptr; (void)newSize; return 0; }
|
||||
virtual size_type AllocationSize(pointer_type ptr);
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override;
|
||||
void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override;
|
||||
pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) override { (void)ptr; (void)newSize; (void)newAlignment; return NULL; }
|
||||
size_type Resize(pointer_type ptr, size_type newSize) override { (void)ptr; (void)newSize; return 0; }
|
||||
size_type AllocationSize(pointer_type ptr) override;
|
||||
|
||||
virtual size_type NumAllocatedBytes() const { return m_used; }
|
||||
virtual size_type Capacity() const { return m_capacity; }
|
||||
virtual size_type GetMaxAllocationSize() const;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
virtual IAllocatorAllocate* GetSubAllocator() { return m_subAllocator; }
|
||||
virtual void GarbageCollect() {}
|
||||
size_type NumAllocatedBytes() const override { return m_used; }
|
||||
size_type Capacity() const override { return m_capacity; }
|
||||
size_type GetMaxAllocationSize() const override;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override { return m_subAllocator; }
|
||||
void GarbageCollect() override {}
|
||||
|
||||
private:
|
||||
AZ_FORCE_INLINE size_type ChunckSize(pointer_type ptr);
|
||||
|
||||
@@ -56,22 +56,22 @@ namespace AZ
|
||||
HphaSchema(const Descriptor& desc);
|
||||
virtual ~HphaSchema();
|
||||
|
||||
virtual pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0);
|
||||
virtual void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0);
|
||||
virtual pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment);
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags = 0, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override;
|
||||
void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override;
|
||||
pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) override;
|
||||
/// Resizes allocated memory block to the size possible and returns that size.
|
||||
virtual size_type Resize(pointer_type ptr, size_type newSize);
|
||||
virtual size_type AllocationSize(pointer_type ptr);
|
||||
size_type Resize(pointer_type ptr, size_type newSize) override;
|
||||
size_type AllocationSize(pointer_type ptr) override;
|
||||
|
||||
virtual size_type NumAllocatedBytes() const;
|
||||
virtual size_type Capacity() const;
|
||||
virtual size_type GetMaxAllocationSize() const;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
virtual size_type GetUnAllocatedMemory(bool isPrint = false) const;
|
||||
virtual IAllocatorAllocate* GetSubAllocator() { return m_desc.m_subAllocator; }
|
||||
size_type NumAllocatedBytes() const override;
|
||||
size_type Capacity() const override;
|
||||
size_type GetMaxAllocationSize() const override;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
size_type GetUnAllocatedMemory(bool isPrint = false) const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override { return m_desc.m_subAllocator; }
|
||||
|
||||
/// Return unused memory to the OS (if we don't use fixed block). Don't call this unless you really need free memory, it is slow.
|
||||
virtual void GarbageCollect();
|
||||
void GarbageCollect() override;
|
||||
|
||||
private:
|
||||
// [LY-84974][sconel@][2018-08-10] SliceStrike integration up to CL 671758
|
||||
|
||||
@@ -41,18 +41,18 @@ namespace AZ
|
||||
//---------------------------------------------------------------------
|
||||
// IAllocatorAllocate
|
||||
//---------------------------------------------------------------------
|
||||
virtual pointer_type Allocate(size_type byteSize, size_type alignment, int flags, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override;
|
||||
virtual void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override;
|
||||
virtual pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) override;
|
||||
virtual size_type Resize(pointer_type ptr, size_type newSize) override;
|
||||
virtual size_type AllocationSize(pointer_type ptr) override;
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override;
|
||||
void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override;
|
||||
pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) override;
|
||||
size_type Resize(pointer_type ptr, size_type newSize) override;
|
||||
size_type AllocationSize(pointer_type ptr) override;
|
||||
|
||||
virtual size_type NumAllocatedBytes() const override;
|
||||
virtual size_type Capacity() const override;
|
||||
virtual size_type GetMaxAllocationSize() const override;
|
||||
virtual size_type GetMaxContiguousAllocationSize() const override;
|
||||
virtual IAllocatorAllocate* GetSubAllocator() override;
|
||||
virtual void GarbageCollect() override;
|
||||
size_type NumAllocatedBytes() const override;
|
||||
size_type Capacity() const override;
|
||||
size_type GetMaxAllocationSize() const override;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
IAllocatorAllocate* GetSubAllocator() override;
|
||||
void GarbageCollect() override;
|
||||
|
||||
private:
|
||||
typedef void* (*MallocFn)(size_t);
|
||||
|
||||
@@ -849,7 +849,7 @@ namespace AZ
|
||||
return AZ::AllocatorInstance<Parent>::Get().GetUnAllocatedMemory(isPrint);
|
||||
}
|
||||
|
||||
virtual IAllocatorAllocate* GetSubAllocator() override
|
||||
IAllocatorAllocate* GetSubAllocator() override
|
||||
{
|
||||
return AZ::AllocatorInstance<Parent>::Get().GetSubAllocator();
|
||||
}
|
||||
|
||||
@@ -38,24 +38,24 @@ namespace AZ
|
||||
protected:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Driller
|
||||
virtual const char* GroupName() const { return "SystemDrillers"; }
|
||||
virtual const char* GetName() const { return "MemoryDriller"; }
|
||||
virtual const char* GetDescription() const { return "Reports all allocators and memory allocations."; }
|
||||
virtual void Start(const Param* params = NULL, int numParams = 0);
|
||||
virtual void Stop();
|
||||
const char* GroupName() const override { return "SystemDrillers"; }
|
||||
const char* GetName() const override { return "MemoryDriller"; }
|
||||
const char* GetDescription() const override { return "Reports all allocators and memory allocations."; }
|
||||
void Start(const Param* params = NULL, int numParams = 0) override;
|
||||
void Stop() override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MemoryDrillerBus
|
||||
virtual void RegisterAllocator(IAllocator* allocator);
|
||||
virtual void UnregisterAllocator(IAllocator* allocator);
|
||||
void RegisterAllocator(IAllocator* allocator) override;
|
||||
void UnregisterAllocator(IAllocator* allocator) override;
|
||||
|
||||
virtual void RegisterAllocation(IAllocator* allocator, void* address, size_t byteSize, size_t alignment, const char* name, const char* fileName, int lineNum, unsigned int stackSuppressCount);
|
||||
virtual void UnregisterAllocation(IAllocator* allocator, void* address, size_t byteSize, size_t alignment, AllocationInfo* info);
|
||||
virtual void ReallocateAllocation(IAllocator* allocator, void* prevAddress, void* newAddress, size_t newByteSize, size_t newAlignment);
|
||||
virtual void ResizeAllocation(IAllocator* allocator, void* address, size_t newSize);
|
||||
void RegisterAllocation(IAllocator* allocator, void* address, size_t byteSize, size_t alignment, const char* name, const char* fileName, int lineNum, unsigned int stackSuppressCount) override;
|
||||
void UnregisterAllocation(IAllocator* allocator, void* address, size_t byteSize, size_t alignment, AllocationInfo* info) override;
|
||||
void ReallocateAllocation(IAllocator* allocator, void* prevAddress, void* newAddress, size_t newByteSize, size_t newAlignment) override;
|
||||
void ResizeAllocation(IAllocator* allocator, void* address, size_t newSize) override;
|
||||
|
||||
virtual void DumpAllAllocations();
|
||||
void DumpAllAllocations() override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RegisterAllocatorOutput(IAllocator* allocator);
|
||||
|
||||
@@ -77,18 +77,18 @@ namespace AZ
|
||||
//---------------------------------------------------------------------
|
||||
// IAllocatorAllocate
|
||||
//---------------------------------------------------------------------
|
||||
virtual pointer_type Allocate(size_type byteSize, size_type alignment, int flags, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override;
|
||||
virtual void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override;
|
||||
virtual pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) override;
|
||||
virtual size_type Resize(pointer_type ptr, size_type newSize) override;
|
||||
virtual size_type AllocationSize(pointer_type ptr) override;
|
||||
pointer_type Allocate(size_type byteSize, size_type alignment, int flags, const char* name = 0, const char* fileName = 0, int lineNum = 0, unsigned int suppressStackRecord = 0) override;
|
||||
void DeAllocate(pointer_type ptr, size_type byteSize = 0, size_type alignment = 0) override;
|
||||
pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment) override;
|
||||
size_type Resize(pointer_type ptr, size_type newSize) override;
|
||||
size_type AllocationSize(pointer_type ptr) override;
|
||||
|
||||
virtual size_type NumAllocatedBytes() const override;
|
||||
virtual size_type Capacity() const override;
|
||||
virtual size_type GetMaxAllocationSize() const override;
|
||||
size_type NumAllocatedBytes() const override;
|
||||
size_type Capacity() const override;
|
||||
size_type GetMaxAllocationSize() const override;
|
||||
size_type GetMaxContiguousAllocationSize() const override;
|
||||
virtual IAllocatorAllocate* GetSubAllocator() override;
|
||||
virtual void GarbageCollect() override;
|
||||
IAllocatorAllocate* GetSubAllocator() override;
|
||||
void GarbageCollect() override;
|
||||
|
||||
private:
|
||||
OverrunDetectionSchemaImpl* m_impl;
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace AZ
|
||||
* DO NOT OVERRIDE. This method will return in the future, but at this point things reflected here are not unreflected for all ReflectContexts (Serialize, Editor, Network, Script, etc.)
|
||||
* Place all calls to non-component reflect functions inside of a component reflect function to ensure that your types are unreflected.
|
||||
*/
|
||||
virtual void Reflect(AZ::ReflectContext*) final { }
|
||||
void Reflect(AZ::ReflectContext*) {}
|
||||
|
||||
/**
|
||||
* Override to require specific components on the system entity.
|
||||
|
||||
@@ -594,8 +594,8 @@ namespace AZ
|
||||
void SetArgumentName(size_t index, const AZStd::string& name) override;
|
||||
const AZStd::string* GetArgumentToolTip(size_t index) const override;
|
||||
void SetArgumentToolTip(size_t index, const AZStd::string& name) override;
|
||||
virtual void SetDefaultValue(size_t index, BehaviorDefaultValuePtr defaultValue) override;
|
||||
virtual BehaviorDefaultValuePtr GetDefaultValue(size_t index) const override;
|
||||
void SetDefaultValue(size_t index, BehaviorDefaultValuePtr defaultValue) override;
|
||||
BehaviorDefaultValuePtr GetDefaultValue(size_t index) const override;
|
||||
const BehaviorParameter* GetResult() const override;
|
||||
|
||||
void OverrideParameterTraits(size_t index, AZ::u32 addTraits, AZ::u32 removeTraits) override;
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#ifndef AZCORE_RTTI_H
|
||||
#define AZCORE_RTTI_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/RTTI/TypeInfo.h>
|
||||
#include <AzCore/Module/Environment.h>
|
||||
@@ -44,21 +44,9 @@ namespace AZ
|
||||
/// RTTI typeId
|
||||
typedef void (* RTTI_EnumCallback)(const AZ::TypeId& /*typeId*/, void* /*userData*/);
|
||||
|
||||
// Disabling missing override warning because we intentionally want to allow for declaring RTTI base classes that don't impelment RTTI.
|
||||
#if defined(AZ_COMPILER_CLANG)
|
||||
# define AZ_PUSH_DISABLE_OVERRIDE_WARNING \
|
||||
_Pragma("clang diagnostic push") \
|
||||
_Pragma("clang diagnostic ignored \"-Winconsistent-missing-override\"")
|
||||
# define AZ_POP_DISABLE_OVERRIDE_WARNING \
|
||||
_Pragma("clang diagnostic pop")
|
||||
#else
|
||||
# define AZ_PUSH_DISABLE_OVERRIDE_WARNING
|
||||
# define AZ_POP_DISABLE_OVERRIDE_WARNING
|
||||
#endif
|
||||
|
||||
// We require AZ_TYPE_INFO to be declared
|
||||
#define AZ_RTTI_COMMON() \
|
||||
AZ_PUSH_DISABLE_OVERRIDE_WARNING \
|
||||
AZ_PUSH_DISABLE_WARNING(26433, "-Winconsistent-missing-override") \
|
||||
void RTTI_Enable(); \
|
||||
virtual inline const AZ::TypeId& RTTI_GetType() const { return RTTI_Type(); } \
|
||||
virtual inline const char* RTTI_GetTypeName() const { return RTTI_TypeName(); } \
|
||||
@@ -66,7 +54,7 @@ namespace AZ
|
||||
virtual void RTTI_EnumTypes(AZ::RTTI_EnumCallback cb, void* userData) { RTTI_EnumHierarchy(cb, userData); } \
|
||||
static inline const AZ::TypeId& RTTI_Type() { return TYPEINFO_Uuid(); } \
|
||||
static inline const char* RTTI_TypeName() { return TYPEINFO_Name(); } \
|
||||
AZ_POP_DISABLE_OVERRIDE_WARNING
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
//#define AZ_RTTI_1(_1) static_assert(false,"You must provide a valid classUuid!")
|
||||
|
||||
@@ -74,8 +62,10 @@ namespace AZ
|
||||
#define AZ_RTTI_1() AZ_RTTI_COMMON() \
|
||||
static bool RTTI_IsContainType(const AZ::TypeId& id) { return id == RTTI_Type(); } \
|
||||
static void RTTI_EnumHierarchy(AZ::RTTI_EnumCallback cb, void* userData) { cb(RTTI_Type(), userData); } \
|
||||
AZ_PUSH_DISABLE_WARNING(26433, "-Winconsistent-missing-override") \
|
||||
virtual inline const void* RTTI_AddressOf(const AZ::TypeId& id) const { return (id == RTTI_Type()) ? this : nullptr; } \
|
||||
virtual inline void* RTTI_AddressOf(const AZ::TypeId& id) { return (id == RTTI_Type()) ? this : nullptr; }
|
||||
virtual inline void* RTTI_AddressOf(const AZ::TypeId& id) { return (id == RTTI_Type()) ? this : nullptr; } \
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
/// AZ_RTTI(BaseClass)
|
||||
#define AZ_RTTI_2(_1) AZ_RTTI_COMMON() \
|
||||
@@ -85,14 +75,14 @@ namespace AZ
|
||||
static void RTTI_EnumHierarchy(AZ::RTTI_EnumCallback cb, void* userData) { \
|
||||
cb(RTTI_Type(), userData); \
|
||||
AZ::Internal::RttiCaller<_1>::RTTI_EnumHierarchy(cb, userData); } \
|
||||
AZ_PUSH_DISABLE_OVERRIDE_WARNING \
|
||||
AZ_PUSH_DISABLE_WARNING(26433, "-Winconsistent-missing-override") \
|
||||
virtual inline const void* RTTI_AddressOf(const AZ::TypeId& id) const { \
|
||||
if (id == RTTI_Type()) { return this; } \
|
||||
return AZ::Internal::RttiCaller<_1>::RTTI_AddressOf(this, id); } \
|
||||
virtual inline void* RTTI_AddressOf(const AZ::TypeId& id) { \
|
||||
if (id == RTTI_Type()) { return this; } \
|
||||
return AZ::Internal::RttiCaller<_1>::RTTI_AddressOf(this, id); } \
|
||||
AZ_POP_DISABLE_OVERRIDE_WARNING
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
/// AZ_RTTI(BaseClass1,BaseClass2)
|
||||
#define AZ_RTTI_3(_1, _2) AZ_RTTI_COMMON() \
|
||||
@@ -104,7 +94,7 @@ namespace AZ
|
||||
cb(RTTI_Type(), userData); \
|
||||
AZ::Internal::RttiCaller<_1>::RTTI_EnumHierarchy(cb, userData); \
|
||||
AZ::Internal::RttiCaller<_2>::RTTI_EnumHierarchy(cb, userData); } \
|
||||
AZ_PUSH_DISABLE_OVERRIDE_WARNING \
|
||||
AZ_PUSH_DISABLE_WARNING(26433, "-Winconsistent-missing-override") \
|
||||
virtual inline const void* RTTI_AddressOf(const AZ::TypeId& id) const { \
|
||||
if (id == RTTI_Type()) { return this; } \
|
||||
const void* r = AZ::Internal::RttiCaller<_1>::RTTI_AddressOf(this, id); if (r) { return r; } \
|
||||
@@ -113,7 +103,7 @@ namespace AZ
|
||||
if (id == RTTI_Type()) { return this; } \
|
||||
void* r = AZ::Internal::RttiCaller<_1>::RTTI_AddressOf(this, id); if (r) { return r; } \
|
||||
return AZ::Internal::RttiCaller<_2>::RTTI_AddressOf(this, id); } \
|
||||
AZ_POP_DISABLE_OVERRIDE_WARNING
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
/// AZ_RTTI(BaseClass1,BaseClass2,BaseClass3)
|
||||
#define AZ_RTTI_4(_1, _2, _3) AZ_RTTI_COMMON() \
|
||||
@@ -127,7 +117,7 @@ namespace AZ
|
||||
AZ::Internal::RttiCaller<_1>::RTTI_EnumHierarchy(cb, userData); \
|
||||
AZ::Internal::RttiCaller<_2>::RTTI_EnumHierarchy(cb, userData); \
|
||||
AZ::Internal::RttiCaller<_3>::RTTI_EnumHierarchy(cb, userData); } \
|
||||
AZ_PUSH_DISABLE_OVERRIDE_WARNING \
|
||||
AZ_PUSH_DISABLE_WARNING(26433, "-Winconsistent-missing-override") \
|
||||
virtual inline const void* RTTI_AddressOf(const AZ::TypeId& id) const { \
|
||||
if (id == RTTI_Type()) { return this; } \
|
||||
const void* r = AZ::Internal::RttiCaller<_1>::RTTI_AddressOf(this, id); if (r) { return r; } \
|
||||
@@ -138,7 +128,7 @@ namespace AZ
|
||||
void* r = AZ::Internal::RttiCaller<_1>::RTTI_AddressOf(this, id); if (r) { return r; } \
|
||||
r = AZ::Internal::RttiCaller<_2>::RTTI_AddressOf(this, id); if (r) { return r; } \
|
||||
return AZ::Internal::RttiCaller<_3>::RTTI_AddressOf(this, id); } \
|
||||
AZ_POP_DISABLE_OVERRIDE_WARNING
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
/// AZ_RTTI(BaseClass1,BaseClass2,BaseClass3,BaseClass4)
|
||||
#define AZ_RTTI_5(_1, _2, _3, _4) AZ_RTTI_COMMON() \
|
||||
@@ -154,7 +144,7 @@ namespace AZ
|
||||
AZ::Internal::RttiCaller<_2>::RTTI_EnumHierarchy(cb, userData); \
|
||||
AZ::Internal::RttiCaller<_3>::RTTI_EnumHierarchy(cb, userData); \
|
||||
AZ::Internal::RttiCaller<_4>::RTTI_EnumHierarchy(cb, userData); } \
|
||||
AZ_PUSH_DISABLE_OVERRIDE_WARNING \
|
||||
AZ_PUSH_DISABLE_WARNING(26433, "-Winconsistent-missing-override") \
|
||||
virtual inline const void* RTTI_AddressOf(const AZ::TypeId& id) const { \
|
||||
if (id == RTTI_Type()) { return this; } \
|
||||
const void* r = AZ::Internal::RttiCaller<_1>::RTTI_AddressOf(this, id); if (r) { return r; } \
|
||||
@@ -167,7 +157,7 @@ namespace AZ
|
||||
r = AZ::Internal::RttiCaller<_2>::RTTI_AddressOf(this, id); if (r) { return r; } \
|
||||
r = AZ::Internal::RttiCaller<_3>::RTTI_AddressOf(this, id); if (r) { return r; } \
|
||||
return AZ::Internal::RttiCaller<_4>::RTTI_AddressOf(this, id); } \
|
||||
AZ_POP_DISABLE_OVERRIDE_WARNING
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
/// AZ_RTTI(BaseClass1,BaseClass2,BaseClass3,BaseClass4,BaseClass5)
|
||||
#define AZ_RTTI_6(_1, _2, _3, _4, _5) AZ_RTTI_COMMON() \
|
||||
@@ -185,7 +175,7 @@ namespace AZ
|
||||
AZ::Internal::RttiCaller<_3>::RTTI_EnumHierarchy(cb, userData); \
|
||||
AZ::Internal::RttiCaller<_4>::RTTI_EnumHierarchy(cb, userData); \
|
||||
AZ::Internal::RttiCaller<_5>::RTTI_EnumHierarchy(cb, userData); } \
|
||||
AZ_PUSH_DISABLE_OVERRIDE_WARNING \
|
||||
AZ_PUSH_DISABLE_WARNING(26433, "-Winconsistent-missing-override") \
|
||||
virtual inline const void* RTTI_AddressOf(const AZ::TypeId& id) const { \
|
||||
if (id == RTTI_Type()) { return this; } \
|
||||
const void* r = AZ::Internal::RttiCaller<_1>::RTTI_AddressOf(this, id); if (r) { return r; } \
|
||||
@@ -200,7 +190,7 @@ namespace AZ
|
||||
r = AZ::Internal::RttiCaller<_3>::RTTI_AddressOf(this, id); if (r) { return r; } \
|
||||
r = AZ::Internal::RttiCaller<_4>::RTTI_AddressOf(this, id); if (r) { return r; } \
|
||||
return AZ::Internal::RttiCaller<_5>::RTTI_AddressOf(this, id); } \
|
||||
AZ_POP_DISABLE_OVERRIDE_WARNING
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MACRO specialization to allow optional parameters for template version of AZ_RTTI
|
||||
@@ -951,10 +941,7 @@ namespace AZ
|
||||
{
|
||||
return AZStd::shared_ptr<DestType>(ptr, castPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
return AZStd::shared_ptr<DestType>();
|
||||
}
|
||||
return AZStd::shared_ptr<DestType>();
|
||||
}
|
||||
|
||||
// RttiCast specialization for intrusive_ptr.
|
||||
@@ -1077,7 +1064,6 @@ namespace AZ
|
||||
{
|
||||
return AZ::Internal::RttiIsTypeOfIdHelper<U>::Check(id, data, typename HasAZRtti<AZStd::remove_pointer_t<U>>::kind_type());
|
||||
}
|
||||
|
||||
} // namespace AZ
|
||||
|
||||
#endif // AZCORE_RTTI_H
|
||||
#pragma once
|
||||
|
||||
@@ -19,8 +19,8 @@ namespace AZ
|
||||
public:
|
||||
AZ_COMPONENT(JsonSystemComponent, "{3C2C7234-9512-4E24-86F0-C40865D7EECE}", Component);
|
||||
|
||||
void Activate();
|
||||
void Deactivate();
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
|
||||
static void Reflect(ReflectContext* reflectContext);
|
||||
};
|
||||
|
||||
@@ -46,7 +46,8 @@ namespace AZ
|
||||
public:
|
||||
AZ_RTTI(JsonUnorderedMapSerializer, "{EF4478D3-1820-4FDB-A7B7-C9711EB41602}", JsonMapSerializer);
|
||||
AZ_CLASS_ALLOCATOR_DECL;
|
||||
|
||||
|
||||
using JsonMapSerializer::Store;
|
||||
JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
|
||||
const Uuid& valueTypeId, JsonSerializerContext& context) override;
|
||||
};
|
||||
@@ -63,6 +64,7 @@ namespace AZ
|
||||
const SerializeContext::ClassElement* keyElement, const SerializeContext::ClassElement* valueElement,
|
||||
const rapidjson::Value& key, const rapidjson::Value& value, JsonDeserializerContext& context) override;
|
||||
|
||||
using JsonMapSerializer::Store;
|
||||
JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
|
||||
const Uuid& valueTypeId, JsonSerializerContext& context) override;
|
||||
};
|
||||
|
||||
@@ -370,6 +370,11 @@ namespace AZ
|
||||
//! @param applyPatchSettings The ApplyPatchSettings which are using during JSON Merging
|
||||
virtual void SetApplyPatchSettings(const AZ::JsonApplyPatchSettings& applyPatchSettings) = 0;
|
||||
virtual void GetApplyPatchSettings(AZ::JsonApplyPatchSettings& applyPatchSettings) = 0;
|
||||
|
||||
//! Stores option to indicate whether the FileIOBase instance should be used for file operations
|
||||
//! @param useFileIo If true the FileIOBase instance will attempted to be used for FileIOBase
|
||||
//! operations before falling back to use SystemFile
|
||||
virtual void SetUseFileIO(bool useFileIo) = 0;
|
||||
};
|
||||
|
||||
inline SettingsRegistryInterface::Visitor::~Visitor() = default;
|
||||
|
||||
@@ -9,11 +9,15 @@
|
||||
#include <cctype>
|
||||
#include <cerrno>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/FileReader.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/JSON/error/en.h>
|
||||
#include <AzCore/NativeUI//NativeUIRequests.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
#include <AzCore/Serialization/Json/StackedString.h>
|
||||
#include <AzCore/Settings/SettingsRegistryImpl.h>
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <AzCore/std/sort.h>
|
||||
#include <AzCore/std/parallel/scoped_lock.h>
|
||||
|
||||
@@ -131,6 +135,12 @@ namespace AZ
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetArray();
|
||||
}
|
||||
|
||||
SettingsRegistryImpl::SettingsRegistryImpl(bool useFileIo)
|
||||
: SettingsRegistryImpl()
|
||||
{
|
||||
m_useFileIo = useFileIo;
|
||||
}
|
||||
|
||||
void SettingsRegistryImpl::SetContext(SerializeContext* context)
|
||||
{
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
@@ -723,15 +733,10 @@ namespace AZ
|
||||
RegistryFileList fileList;
|
||||
scratchBuffer->clear();
|
||||
|
||||
AZ::IO::FixedMaxPathString folderPath{ path };
|
||||
constexpr AZStd::string_view pathSeparators{ AZ_CORRECT_AND_WRONG_DATABASE_SEPARATOR };
|
||||
if (pathSeparators.find_first_of(folderPath.back()) == AZStd::string_view::npos)
|
||||
{
|
||||
folderPath.push_back(AZ_CORRECT_DATABASE_SEPARATOR);
|
||||
}
|
||||
AZ::IO::FixedMaxPath folderPath{ path };
|
||||
|
||||
const size_t platformKeyOffset = folderPath.size();
|
||||
folderPath.push_back('*');
|
||||
const size_t platformKeyOffset = folderPath.Native().size();
|
||||
folderPath /= '*';
|
||||
|
||||
Value specialzationArray(kArrayType);
|
||||
size_t specializationCount = specializations.GetCount();
|
||||
@@ -741,47 +746,13 @@ namespace AZ
|
||||
specialzationArray.PushBack(Value(name.data(), aznumeric_caster(name.length()), m_settings.GetAllocator()), m_settings.GetAllocator());
|
||||
}
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
.AddMember(StringRef("Folder"), Value(folderPath.c_str(), aznumeric_caster(folderPath.size()), m_settings.GetAllocator()), m_settings.GetAllocator())
|
||||
.AddMember(StringRef("Folder"), Value(folderPath.c_str(), aznumeric_caster(folderPath.Native().size()), m_settings.GetAllocator()), m_settings.GetAllocator())
|
||||
.AddMember(StringRef("Specializations"), AZStd::move(specialzationArray), m_settings.GetAllocator());
|
||||
|
||||
auto callback = [this, &fileList, &specializations, &pointer, &folderPath](const char* filename, bool isFile) -> bool
|
||||
|
||||
auto CreateSettingsFindCallback = [this, &fileList, &specializations, &pointer, &folderPath](bool isPlatformFile)
|
||||
{
|
||||
if (isFile)
|
||||
{
|
||||
if (fileList.size() >= MaxRegistryFolderEntries)
|
||||
{
|
||||
AZ_Error("Settings Registry", false, "Too many files in registry folder.");
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
.AddMember(StringRef("Error"), StringRef("Too many files in registry folder."), m_settings.GetAllocator())
|
||||
.AddMember(StringRef("Path"), Value(folderPath.c_str(), aznumeric_caster(folderPath.size()), m_settings.GetAllocator()), m_settings.GetAllocator())
|
||||
.AddMember(StringRef("File"), Value(filename, m_settings.GetAllocator()), m_settings.GetAllocator());
|
||||
return false;
|
||||
}
|
||||
|
||||
fileList.push_back();
|
||||
RegistryFile& registryFile = fileList.back();
|
||||
if (!ExtractFileDescription(registryFile, filename, specializations))
|
||||
{
|
||||
fileList.pop_back();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
SystemFile::FindFiles(folderPath.c_str(), callback);
|
||||
|
||||
|
||||
if (!platform.empty())
|
||||
{
|
||||
// Move the folderPath prefix back to the supplied path before the wildcard
|
||||
folderPath.erase(platformKeyOffset);
|
||||
folderPath += PlatformFolder;
|
||||
folderPath.push_back(AZ_CORRECT_DATABASE_SEPARATOR);
|
||||
folderPath += platform;
|
||||
folderPath.push_back(AZ_CORRECT_DATABASE_SEPARATOR);
|
||||
folderPath.push_back('*');
|
||||
|
||||
auto platformCallback = [this, &fileList, &specializations, &pointer, &folderPath](const char* filename, bool isFile) -> bool
|
||||
return [this, &fileList, &specializations, &pointer, &folderPath, isPlatformFile](AZStd::string_view filename, bool isFile) -> bool
|
||||
{
|
||||
if (isFile)
|
||||
{
|
||||
@@ -791,8 +762,8 @@ namespace AZ
|
||||
AZStd::scoped_lock lock(m_settingMutex);
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
.AddMember(StringRef("Error"), StringRef("Too many files in registry folder."), m_settings.GetAllocator())
|
||||
.AddMember(StringRef("Path"), Value(folderPath.c_str(), aznumeric_caster(folderPath.size()), m_settings.GetAllocator()), m_settings.GetAllocator())
|
||||
.AddMember(StringRef("File"), Value(filename, m_settings.GetAllocator()), m_settings.GetAllocator());
|
||||
.AddMember(StringRef("Path"), Value(folderPath.c_str(), aznumeric_caster(folderPath.Native().size()), m_settings.GetAllocator()), m_settings.GetAllocator())
|
||||
.AddMember(StringRef("File"), Value(filename.data(), aznumeric_caster(filename.size()), m_settings.GetAllocator()), m_settings.GetAllocator());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -800,7 +771,7 @@ namespace AZ
|
||||
RegistryFile& registryFile = fileList.back();
|
||||
if (ExtractFileDescription(registryFile, filename, specializations))
|
||||
{
|
||||
registryFile.m_isPlatformFile = true;
|
||||
registryFile.m_isPlatformFile = isPlatformFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -809,7 +780,42 @@ namespace AZ
|
||||
}
|
||||
return true;
|
||||
};
|
||||
SystemFile::FindFiles(folderPath.c_str(), platformCallback);
|
||||
};
|
||||
|
||||
struct FindFilesPayload
|
||||
{
|
||||
bool m_isPlatformFile{};
|
||||
AZStd::fixed_vector<AZStd::string_view, 2> m_pathSegmentsToAppend;
|
||||
};
|
||||
|
||||
AZStd::fixed_vector<FindFilesPayload, 2> findFilesPayloads{ {false} };
|
||||
if (!platform.empty())
|
||||
{
|
||||
findFilesPayloads.push_back(FindFilesPayload{ true, { PlatformFolder, platform } });
|
||||
}
|
||||
|
||||
for (const FindFilesPayload& findFilesPayload : findFilesPayloads)
|
||||
{
|
||||
// Erase back to initial path
|
||||
folderPath.Native().erase(platformKeyOffset);
|
||||
for (AZStd::string_view pathSegmentToAppend : findFilesPayload.m_pathSegmentsToAppend)
|
||||
{
|
||||
folderPath /= pathSegmentToAppend;
|
||||
}
|
||||
|
||||
auto findFilesCallback = CreateSettingsFindCallback(findFilesPayload.m_isPlatformFile);
|
||||
if (AZ::IO::FileIOBase* fileIo = m_useFileIo ? AZ::IO::FileIOBase::GetInstance() : nullptr; fileIo != nullptr)
|
||||
{
|
||||
auto FileIoToSystemFileFindFiles = [findFilesCallback = AZStd::move(findFilesCallback), fileIo](const char* filePath) -> bool
|
||||
{
|
||||
return findFilesCallback(AZ::IO::PathView(filePath).Filename().Native(), !fileIo->IsDirectory(filePath));
|
||||
};
|
||||
fileIo->FindFiles(folderPath.c_str(), "*", FileIoToSystemFileFindFiles);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemFile::FindFiles((folderPath / "*").c_str(), findFilesCallback);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileList.empty())
|
||||
@@ -831,16 +837,14 @@ namespace AZ
|
||||
// Load the registry files in the sorted order.
|
||||
for (RegistryFile& registryFile : fileList)
|
||||
{
|
||||
folderPath.erase(platformKeyOffset); // Erase all characters after the platformKeyOffset
|
||||
folderPath.Native().erase(platformKeyOffset); // Erase all characters after the platformKeyOffset
|
||||
if (registryFile.m_isPlatformFile)
|
||||
{
|
||||
folderPath += PlatformFolder;
|
||||
folderPath.push_back(AZ_CORRECT_DATABASE_SEPARATOR);
|
||||
folderPath += platform;
|
||||
folderPath.push_back(AZ_CORRECT_DATABASE_SEPARATOR);
|
||||
folderPath /= PlatformFolder;
|
||||
folderPath /= platform;
|
||||
}
|
||||
|
||||
folderPath += registryFile.m_relativePath;
|
||||
folderPath /= registryFile.m_relativePath;
|
||||
|
||||
if (!registryFile.m_isPatch)
|
||||
{
|
||||
@@ -1027,39 +1031,44 @@ namespace AZ
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SettingsRegistryImpl::ExtractFileDescription(RegistryFile& output, const char* filename, const Specializations& specializations)
|
||||
bool SettingsRegistryImpl::ExtractFileDescription(RegistryFile& output, AZStd::string_view filename, const Specializations& specializations)
|
||||
{
|
||||
if (!filename || filename[0] == 0)
|
||||
static constexpr auto PatchExtensionWithDot = AZStd::fixed_string<32>(".") + PatchExtension;
|
||||
static constexpr auto ExtensionWithDot = AZStd::fixed_string<32>(".") + Extension;
|
||||
static constexpr AZ::IO::PathView PatchExtensionView(PatchExtensionWithDot);
|
||||
static constexpr AZ::IO::PathView ExtensionView(ExtensionWithDot);
|
||||
|
||||
if (filename.empty())
|
||||
{
|
||||
AZ_Error("Settings Registry", false, "Settings file without name found");
|
||||
return false;
|
||||
}
|
||||
|
||||
AZStd::string_view filePath{ filename };
|
||||
const size_t filePathSize = filePath.size();
|
||||
AZ::IO::PathView filePath{ filename };
|
||||
const size_t filePathSize = filePath.Native().size();
|
||||
|
||||
// The filePath.empty() check makes sure that the file extension after the final <dot> isn't added to the output.m_tags
|
||||
AZStd::optional<AZStd::string_view> pathTag = AZ::StringFunc::TokenizeNext(filePath, '.');
|
||||
for (; pathTag && !filePath.empty(); pathTag = AZ::StringFunc::TokenizeNext(filePath, '.'))
|
||||
auto AppendSpecTags = [&output](AZStd::string_view pathTag)
|
||||
{
|
||||
output.m_tags.push_back(Specializations::Hash(*pathTag));
|
||||
}
|
||||
output.m_tags.push_back(Specializations::Hash(pathTag));
|
||||
};
|
||||
AZ::StringFunc::TokenizeVisitor(filePath.Stem().Native(), AppendSpecTags, '.');
|
||||
|
||||
// If token is invalid, then the filename has no <dot> characters and therefore no extension
|
||||
if (pathTag)
|
||||
if (AZ::IO::PathView fileExtension = filePath.Extension(); !fileExtension.empty())
|
||||
{
|
||||
if (pathTag->size() >= AZStd::char_traits<char>::length(PatchExtension) && azstrnicmp(pathTag->data(), PatchExtension, pathTag->size()) == 0)
|
||||
if (fileExtension == PatchExtensionView)
|
||||
{
|
||||
output.m_isPatch = true;
|
||||
}
|
||||
else if (pathTag->size() != AZStd::char_traits<char>::length(Extension) || azstrnicmp(pathTag->data(), Extension, pathTag->size()) != 0)
|
||||
else if (fileExtension != ExtensionView)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("Settings Registry", false, R"(Settings file without extension found: "%s")", filename);
|
||||
AZ_Error("Settings Registry", false, R"(Settings file without extension found: "%.*s")", AZ_STRING_ARG(filename));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1074,7 +1083,7 @@ namespace AZ
|
||||
{
|
||||
if (*currentIt == *(currentIt - 1))
|
||||
{
|
||||
AZ_Error("Settings Registry", false, R"(One or more tags are duplicated in registry file "%s")", filename);
|
||||
AZ_Error("Settings Registry", false, R"(One or more tags are duplicated in registry file "%.*s")", AZ_STRING_ARG(filename));
|
||||
return false;
|
||||
}
|
||||
++currentIt;
|
||||
@@ -1103,7 +1112,7 @@ namespace AZ
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("Settings Registry", false, R"(Found relative path to settings file "%s" is too long.)", filename);
|
||||
AZ_Error("Settings Registry", false, R"(Found relative path to settings file "%.*s" is too long.)", AZ_STRING_ARG(filename));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1116,8 +1125,8 @@ namespace AZ
|
||||
|
||||
Pointer pointer(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/-");
|
||||
|
||||
SystemFile file;
|
||||
if (!file.Open(path, SystemFile::OpenMode::SF_OPEN_READ_ONLY))
|
||||
FileReader fileReader(m_useFileIo ? AZ::IO::FileIOBase::GetInstance(): nullptr, path);
|
||||
if (!fileReader.IsOpen())
|
||||
{
|
||||
AZ_Error("Settings Registry", false, R"(Unable to open registry file "%s".)", path);
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
@@ -1126,7 +1135,7 @@ namespace AZ
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 fileSize = file.Length();
|
||||
u64 fileSize = fileReader.Length();
|
||||
if (fileSize == 0)
|
||||
{
|
||||
AZ_Warning("Settings Registry", false, R"(Registry file "%s" is 0 bytes in length. There is no nothing to merge)", path);
|
||||
@@ -1136,9 +1145,10 @@ namespace AZ
|
||||
.AddMember(StringRef("Path"), Value(path, m_settings.GetAllocator()), m_settings.GetAllocator());
|
||||
return false;
|
||||
}
|
||||
|
||||
scratchBuffer.clear();
|
||||
scratchBuffer.resize_no_construct(fileSize + 1);
|
||||
if (file.Read(fileSize, scratchBuffer.data()) != fileSize)
|
||||
if (fileReader.Read(fileSize, scratchBuffer.data()) != fileSize)
|
||||
{
|
||||
AZ_Error("Settings Registry", false, R"(Unable to read registry file "%s".)", path);
|
||||
pointer.Create(m_settings, m_settings.GetAllocator()).SetObject()
|
||||
@@ -1268,4 +1278,9 @@ namespace AZ
|
||||
{
|
||||
applyPatchSettings = m_applyPatchSettings;
|
||||
}
|
||||
|
||||
void SettingsRegistryImpl::SetUseFileIO(bool useFileIo)
|
||||
{
|
||||
m_useFileIo = useFileIo;
|
||||
}
|
||||
} // namespace AZ
|
||||
|
||||
@@ -35,6 +35,10 @@ namespace AZ
|
||||
static constexpr size_t MaxRegistryFolderEntries = 128;
|
||||
|
||||
SettingsRegistryImpl();
|
||||
//! @param useFileIo - If true attempt to redirect
|
||||
//! file read operations through the FileIOBase instance first before falling back to SystemFile
|
||||
//! otherwise always use SystemFile
|
||||
explicit SettingsRegistryImpl(bool useFileIo);
|
||||
AZ_DISABLE_COPY_MOVE(SettingsRegistryImpl);
|
||||
~SettingsRegistryImpl() override = default;
|
||||
|
||||
@@ -83,6 +87,8 @@ namespace AZ
|
||||
void SetApplyPatchSettings(const AZ::JsonApplyPatchSettings& applyPatchSettings) override;
|
||||
void GetApplyPatchSettings(AZ::JsonApplyPatchSettings& applyPatchSettings) override;
|
||||
|
||||
void SetUseFileIO(bool useFileIo) override;
|
||||
|
||||
private:
|
||||
using TagList = AZStd::fixed_vector<size_t, Specializations::MaxCount + 1>;
|
||||
struct RegistryFile
|
||||
@@ -104,7 +110,7 @@ namespace AZ
|
||||
// Compares if lhs is less than rhs in terms of processing order. This can also detect and report conflicts.
|
||||
bool IsLessThan(bool& collisionFound, const RegistryFile& lhs, const RegistryFile& rhs, const Specializations& specializations,
|
||||
const rapidjson::Pointer& historyPointer, AZStd::string_view folderPath);
|
||||
bool ExtractFileDescription(RegistryFile& output, const char* filename, const Specializations& specializations);
|
||||
bool ExtractFileDescription(RegistryFile& output, AZStd::string_view filename, const Specializations& specializations);
|
||||
bool MergeSettingsFileInternal(const char* path, Format format, AZStd::string_view rootKey, AZStd::vector<char>& scratchBuffer);
|
||||
|
||||
void SignalNotifier(AZStd::string_view jsonPath, Type type);
|
||||
@@ -119,5 +125,7 @@ namespace AZ
|
||||
JsonSerializerSettings m_serializationSettings;
|
||||
JsonDeserializerSettings m_deserializationSettings;
|
||||
JsonApplyPatchSettings m_applyPatchSettings;
|
||||
|
||||
bool m_useFileIo{};
|
||||
};
|
||||
} // namespace AZ
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/FileReader.h>
|
||||
#include <AzCore/IO/GenericStreams.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/IO/TextStreamWriters.h>
|
||||
@@ -78,6 +80,7 @@ namespace AZ::Internal
|
||||
|
||||
struct EnginePathsVisitor : public AZ::SettingsRegistryInterface::Visitor
|
||||
{
|
||||
using AZ::SettingsRegistryInterface::Visitor::Visit;
|
||||
void Visit(
|
||||
[[maybe_unused]] AZStd::string_view path, AZStd::string_view valueName,
|
||||
[[maybe_unused]] AZ::SettingsRegistryInterface::Type type, AZStd::string_view value) override
|
||||
@@ -355,6 +358,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
: m_settingsSpecialization{ specializations }
|
||||
{}
|
||||
|
||||
using AZ::SettingsRegistryInterface::Visitor::Visit;
|
||||
void Visit([[maybe_unused]] AZStd::string_view path, AZStd::string_view valueName,
|
||||
[[maybe_unused]] AZ::SettingsRegistryInterface::Type type, bool value) override
|
||||
{
|
||||
@@ -386,8 +390,36 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
const ConfigParserSettings& configParserSettings)
|
||||
{
|
||||
auto configPath = FindEngineRoot(registry) / filePath;
|
||||
IO::SystemFile configFile;
|
||||
if (!configFile.Open(configPath.c_str(), IO::SystemFile::OpenMode::SF_OPEN_READ_ONLY))
|
||||
IO::FileReader configFile;
|
||||
bool configFileOpened{};
|
||||
switch (configParserSettings.m_fileReaderClass)
|
||||
{
|
||||
case ConfigParserSettings::FileReaderClass::UseFileIOIfAvailableFallbackToSystemFile:
|
||||
{
|
||||
auto fileIo = AZ::IO::FileIOBase::GetInstance();
|
||||
configFileOpened = configFile.Open(fileIo, configPath.c_str());
|
||||
break;
|
||||
}
|
||||
case ConfigParserSettings::FileReaderClass::UseSystemFileOnly:
|
||||
{
|
||||
configFileOpened = configFile.Open(nullptr, configPath.c_str());
|
||||
break;
|
||||
}
|
||||
case ConfigParserSettings::FileReaderClass::UseFileIOOnly:
|
||||
{
|
||||
auto fileIo = AZ::IO::FileIOBase::GetInstance();
|
||||
if (fileIo == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
configFileOpened = configFile.Open(fileIo, configPath.c_str());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
AZ_Error("SettingsRegistryMergeUtils", false, "An Invalid FileReaderClass enum value has been supplied");
|
||||
return false;
|
||||
}
|
||||
if (!configFileOpened)
|
||||
{
|
||||
AZ_Warning("SettingsRegistryMergeUtils", false, R"(Unable to open file "%s")", configPath.c_str());
|
||||
return false;
|
||||
@@ -478,7 +510,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
AZ_Error("SettingsRegistryMergeUtils", false,
|
||||
R"(The config file "%s" contains a line which is longer than the max line length of %zu.)" "\n"
|
||||
R"(Parsing will halt. The line content so far is:)" "\n"
|
||||
R"("%.*s")" "\n", configFile.Name(), configBuffer.max_size(),
|
||||
R"("%.*s")" "\n", configPath.c_str(), configBuffer.max_size(),
|
||||
aznumeric_cast<int>(configBuffer.size()), configBuffer.data());
|
||||
configFileParsed = false;
|
||||
break;
|
||||
@@ -761,6 +793,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
return SettingsRegistryInterface::VisitResponse::Continue;
|
||||
}
|
||||
|
||||
using AZ::SettingsRegistryInterface::Visitor::Visit;
|
||||
void Visit(AZStd::string_view, [[maybe_unused]] AZStd::string_view valueName, SettingsRegistryInterface::Type, AZStd::string_view value) override
|
||||
{
|
||||
if (processingSourcePathKey)
|
||||
@@ -896,6 +929,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
struct CommandLineVisitor
|
||||
: AZ::SettingsRegistryInterface::Visitor
|
||||
{
|
||||
using AZ::SettingsRegistryInterface::Visitor::Visit;
|
||||
void Visit(AZStd::string_view, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type
|
||||
, AZStd::string_view value) override
|
||||
{
|
||||
|
||||
@@ -155,6 +155,15 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
//! structure which is forwarded to the SettingsRegistryInterface MergeCommandLineArgument function
|
||||
//! The structure contains a functor which returns true if a character is a valid delimiter
|
||||
SettingsRegistryInterface::CommandLineArgumentSettings m_commandLineSettings;
|
||||
|
||||
//! enumeration to indicate if AZ::IO::FileIOBase should be used to open the config file over AZ::IO::SystemFile
|
||||
enum class FileReaderClass
|
||||
{
|
||||
UseFileIOIfAvailableFallbackToSystemFile,
|
||||
UseSystemFileOnly,
|
||||
UseFileIOOnly
|
||||
};
|
||||
FileReaderClass m_fileReaderClass = FileReaderClass::UseFileIOIfAvailableFallbackToSystemFile;
|
||||
};
|
||||
//! Loads basic configuration files which have structures similar to Windows INI files
|
||||
//! It is inspired by the Python configparser module: https://docs.python.org/3.10/library/configparser.html
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace AZ
|
||||
|
||||
MOCK_METHOD1(SetApplyPatchSettings, void(const JsonApplyPatchSettings&));
|
||||
MOCK_METHOD1(GetApplyPatchSettings, void(JsonApplyPatchSettings&));
|
||||
MOCK_METHOD1(SetUseFileIO, void(bool));
|
||||
};
|
||||
} // namespace AZ
|
||||
|
||||
|
||||
@@ -131,17 +131,23 @@ namespace UnitTest
|
||||
, public AllocatorsBase
|
||||
{
|
||||
public:
|
||||
// Bring in both const and non-const SetUp and TearDown function into scope to resolve warning 4266
|
||||
// no override available for virtual member function from base 'benchmark::Fixture'; function is hidden
|
||||
using ::benchmark::Fixture::SetUp, ::benchmark::Fixture::TearDown;
|
||||
|
||||
//Benchmark interface
|
||||
void SetUp(const ::benchmark::State& st) override
|
||||
{
|
||||
AZ_UNUSED(st);
|
||||
SetupAllocator();
|
||||
}
|
||||
void SetUp(::benchmark::State& st) override
|
||||
{
|
||||
AZ_UNUSED(st);
|
||||
SetupAllocator();
|
||||
}
|
||||
|
||||
void TearDown(const ::benchmark::State& st) override
|
||||
{
|
||||
AZ_UNUSED(st);
|
||||
TeardownAllocator();
|
||||
}
|
||||
void TearDown(::benchmark::State& st) override
|
||||
{
|
||||
AZ_UNUSED(st);
|
||||
|
||||
@@ -116,9 +116,9 @@ namespace AZ
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// UserSettingsBus
|
||||
virtual AZStd::intrusive_ptr<UserSettings> FindUserSettings(u32 id);
|
||||
virtual void AddUserSettings(u32 id, UserSettings* settings);
|
||||
virtual bool Save(const char* settingsPath, SerializeContext* sc);
|
||||
AZStd::intrusive_ptr<UserSettings> FindUserSettings(u32 id) override;
|
||||
void AddUserSettings(u32 id, UserSettings* settings) override;
|
||||
bool Save(const char* settingsPath, SerializeContext* sc) override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Reflect(ReflectContext* reflection);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
// the intention is that you only include the customized version of rapidXML through this header, so that
|
||||
// you can override behavior here.
|
||||
#include <stdio.h>
|
||||
#include <rapidxml/rapidxml.h>
|
||||
|
||||
#endif // AZCORE_RAPIDXML_RAPIDXML_H_INCLUDED
|
||||
|
||||
@@ -166,6 +166,8 @@ set(FILES
|
||||
IO/FileIO.cpp
|
||||
IO/FileIO.h
|
||||
IO/FileIOEventBus.h
|
||||
IO/FileReader.cpp
|
||||
IO/FileReader.h
|
||||
IO/IOUtils.h
|
||||
IO/IOUtils.cpp
|
||||
IO/IStreamer.h
|
||||
|
||||
@@ -831,7 +831,6 @@ namespace AZStd
|
||||
// find first element that value is before, using operator<
|
||||
typename iterator_traits<ForwardIterator>::difference_type count = AZStd::distance(first, last);
|
||||
typename iterator_traits<ForwardIterator>::difference_type step{};
|
||||
count = AZStd::distance(first, last);
|
||||
for (; 0 < count; )
|
||||
{ // divide and conquer, find half that contains answer
|
||||
step = count / 2;
|
||||
|
||||
@@ -187,7 +187,7 @@ namespace AZStd
|
||||
: m_f(AZStd::move(f)) {}
|
||||
thread_info_impl(Internal::thread_move_t<F> f)
|
||||
: m_f(f) {}
|
||||
virtual void execute() { m_f(); }
|
||||
void execute() override { m_f(); }
|
||||
private:
|
||||
F m_f;
|
||||
|
||||
|
||||
@@ -129,16 +129,16 @@ namespace AZStd
|
||||
{
|
||||
}
|
||||
|
||||
virtual void dispose() // nothrow
|
||||
void dispose() override // nothrow
|
||||
{
|
||||
AZStd::checked_delete(px_);
|
||||
}
|
||||
virtual void destroy() // nothrow
|
||||
void destroy() override // nothrow
|
||||
{
|
||||
this->~this_type();
|
||||
a_.deallocate(this, sizeof(this_type), AZStd::alignment_of<this_type>::value);
|
||||
}
|
||||
virtual void* get_deleter(Internal::sp_typeinfo const&)
|
||||
void* get_deleter(Internal::sp_typeinfo const&) override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -176,18 +176,18 @@ namespace AZStd
|
||||
{
|
||||
}
|
||||
|
||||
virtual void dispose() // nothrow
|
||||
void dispose() override // nothrow
|
||||
{
|
||||
d_(p_);
|
||||
}
|
||||
|
||||
virtual void destroy() // nothrow
|
||||
void destroy() override // nothrow
|
||||
{
|
||||
this->~this_type();
|
||||
a_.deallocate(this, sizeof(this_type), AZStd::alignment_of<this_type>::value);
|
||||
}
|
||||
|
||||
virtual void* get_deleter(Internal::sp_typeinfo const& ti)
|
||||
void* get_deleter(Internal::sp_typeinfo const& ti) override
|
||||
{
|
||||
return ti == aztypeid(D) ? &reinterpret_cast<char&>(d_) : 0;
|
||||
}
|
||||
|
||||
@@ -96,6 +96,10 @@ namespace AZStd
|
||||
&& !is_convertible_v<const T&, const Element*>>>
|
||||
constexpr basic_fixed_string(const T& convertibleToView, size_type rhsOffset, size_type count);
|
||||
|
||||
|
||||
// #12
|
||||
constexpr basic_fixed_string(AZStd::nullptr_t) = delete;
|
||||
|
||||
constexpr operator AZStd::basic_string_view<Element, Traits>() const;
|
||||
|
||||
constexpr auto begin() -> iterator;
|
||||
@@ -120,6 +124,7 @@ namespace AZStd
|
||||
constexpr auto operator=(const T& convertible_to_view)
|
||||
-> AZStd::enable_if_t<is_convertible_v<const T&, basic_string_view<Element, Traits>>
|
||||
&& !is_convertible_v<const T&, const Element*>, basic_fixed_string&>;
|
||||
constexpr auto operator=(AZStd::nullptr_t) -> basic_fixed_string& = delete;
|
||||
|
||||
constexpr auto operator+=(const basic_fixed_string& rhs) -> basic_fixed_string&;
|
||||
constexpr auto operator+=(const_pointer ptr) -> basic_fixed_string&;
|
||||
|
||||
@@ -215,6 +215,7 @@ namespace AZStd
|
||||
|
||||
struct ErrorSink
|
||||
{
|
||||
virtual ~ErrorSink() = default;
|
||||
virtual void RegexError(regex_constants::error_type code) = 0;
|
||||
};
|
||||
}
|
||||
@@ -1079,7 +1080,7 @@ namespace AZStd
|
||||
NodeBase* m_next;
|
||||
NodeBase* m_previous;
|
||||
|
||||
virtual ~NodeBase() { }
|
||||
virtual ~NodeBase() = default;
|
||||
};
|
||||
|
||||
inline void DestroyNode(NodeBase* node, NodeBase* end = nullptr)
|
||||
@@ -1758,7 +1759,7 @@ namespace AZStd
|
||||
return (*this);
|
||||
}
|
||||
|
||||
~basic_regex()
|
||||
~basic_regex() override
|
||||
{ // destroy the object
|
||||
Clear();
|
||||
}
|
||||
@@ -2916,7 +2917,7 @@ namespace AZStd
|
||||
}
|
||||
|
||||
template<class ForwardIterator, class Element, class RegExTraits>
|
||||
inline NodeBase* Builder<ForwardIterator, Element, RegExTraits>::BeginGroup(void)
|
||||
inline NodeBase* Builder<ForwardIterator, Element, RegExTraits>::BeginGroup()
|
||||
{ // add group node
|
||||
return (NewNode(NT_group));
|
||||
}
|
||||
@@ -3026,7 +3027,7 @@ namespace AZStd
|
||||
}
|
||||
|
||||
template<class ForwardIterator, class Element, class RegExTraits>
|
||||
inline RootNode* Builder<ForwardIterator, Element, RegExTraits>::EndPattern(void)
|
||||
inline RootNode* Builder<ForwardIterator, Element, RegExTraits>::EndPattern()
|
||||
{ // wrap up
|
||||
NewNode(NT_end);
|
||||
return m_root;
|
||||
|
||||
@@ -168,6 +168,9 @@ namespace AZStd
|
||||
{
|
||||
}
|
||||
|
||||
// C++23 overload to prevent initializing a string_view via a nullptr or integer type
|
||||
constexpr basic_string(AZStd::nullptr_t) = delete;
|
||||
|
||||
inline ~basic_string()
|
||||
{
|
||||
// destroy the string
|
||||
@@ -197,6 +200,7 @@ namespace AZStd
|
||||
inline this_type& operator=(AZStd::basic_string_view<Element, Traits> view) { return assign(view); }
|
||||
inline this_type& operator=(const_pointer ptr) { return assign(ptr); }
|
||||
inline this_type& operator=(Element ch) { return assign(1, ch); }
|
||||
inline this_type& operator=(AZStd::nullptr_t) = delete;
|
||||
inline this_type& operator+=(const this_type& rhs) { return append(rhs); }
|
||||
inline this_type& operator+=(const_pointer ptr) { return append(ptr); }
|
||||
inline this_type& operator+=(Element ch) { return append(1, ch); }
|
||||
|
||||
@@ -502,6 +502,9 @@ namespace AZStd
|
||||
swap(other);
|
||||
}
|
||||
|
||||
// C++23 overload to prevent initializing a string_view via a nullptr or integer type
|
||||
constexpr basic_string_view(AZStd::nullptr_t) = delete;
|
||||
|
||||
constexpr const_reference operator[](size_type index) const { return data()[index]; }
|
||||
/// Returns value, not reference. If index is out of bounds, 0 is returned (can't be reference).
|
||||
constexpr value_type at(size_type index) const
|
||||
|
||||
+18
@@ -72,6 +72,7 @@ namespace AZ
|
||||
{
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
bool fileFound = false;
|
||||
if (AZ::IO::FixedMaxPath projectModulePath;
|
||||
settingsRegistry->Get(projectModulePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectConfigurationBinPath))
|
||||
{
|
||||
@@ -79,6 +80,23 @@ namespace AZ
|
||||
if (AZ::IO::SystemFile::Exists(projectModulePath.c_str()))
|
||||
{
|
||||
m_fileName.assign(projectModulePath.c_str(), projectModulePath.Native().size());
|
||||
fileFound = true;
|
||||
}
|
||||
}
|
||||
if (!fileFound)
|
||||
{
|
||||
if (AZ::IO::FixedMaxPath installedBinariesPath;
|
||||
settingsRegistry->Get(installedBinariesPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_InstalledBinaryFolder))
|
||||
{
|
||||
if (AZ::IO::FixedMaxPath engineRootFolder;
|
||||
settingsRegistry->Get(engineRootFolder.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder))
|
||||
{
|
||||
installedBinariesPath = engineRootFolder / installedBinariesPath / fullFilePath;
|
||||
if (AZ::IO::SystemFile::Exists(installedBinariesPath.c_str()))
|
||||
{
|
||||
m_fileName.assign(installedBinariesPath.c_str(), installedBinariesPath.Native().size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <pwd.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -39,6 +40,14 @@ namespace AZ
|
||||
AZ::IO::FixedMaxPath path{homePath};
|
||||
return path.Native();
|
||||
}
|
||||
|
||||
struct passwd* pass = getpwuid(getuid());
|
||||
if (pass)
|
||||
{
|
||||
AZ::IO::FixedMaxPath path{pass->pw_dir};
|
||||
return path.Native();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -21,7 +21,7 @@ namespace AZ
|
||||
class WinAPIOverrunDetectionSchema : public OverrunDetectionSchema::PlatformAllocator
|
||||
{
|
||||
public:
|
||||
virtual SystemInformation GetSystemInformation() override
|
||||
SystemInformation GetSystemInformation() override
|
||||
{
|
||||
SystemInformation result;
|
||||
SYSTEM_INFO info;
|
||||
@@ -32,7 +32,7 @@ namespace AZ
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void* ReserveBytes(size_t amount) override
|
||||
void* ReserveBytes(size_t amount) override
|
||||
{
|
||||
void* result = VirtualAlloc(0, amount, MEM_RESERVE, PAGE_NOACCESS);
|
||||
|
||||
@@ -45,12 +45,12 @@ namespace AZ
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void ReleaseReservedBytes(void* base) override
|
||||
void ReleaseReservedBytes(void* base) override
|
||||
{
|
||||
VirtualFree(base, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
virtual void* CommitBytes(void* base, size_t amount) override
|
||||
void* CommitBytes(void* base, size_t amount) override
|
||||
{
|
||||
void* result = VirtualAlloc(base, amount, MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace AZ
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void DecommitBytes(void* base, size_t amount) override
|
||||
void DecommitBytes(void* base, size_t amount) override
|
||||
{
|
||||
VirtualFree(base, amount, MEM_DECOMMIT);
|
||||
}
|
||||
|
||||
+1
@@ -267,6 +267,7 @@ namespace AZ::IO
|
||||
SettingsRegistryInterface::VisitResponse::Continue : SettingsRegistryInterface::VisitResponse::Skip;
|
||||
}
|
||||
|
||||
using SettingsRegistryInterface::Visitor::Visit;
|
||||
void Visit([[maybe_unused]] AZStd::string_view path, [[maybe_unused]] AZStd::string_view valueName,
|
||||
[[maybe_unused]] AZ::SettingsRegistryInterface::Type type, AZStd::string_view value) override
|
||||
{
|
||||
|
||||
@@ -1210,9 +1210,6 @@ namespace UnitTest
|
||||
|
||||
AZStd::string findStr("Hay");
|
||||
string_view view3(findStr);
|
||||
string_view nullptrView4(nullptr);
|
||||
|
||||
EXPECT_EQ(emptyView1, nullptrView4);
|
||||
|
||||
// copy
|
||||
const size_t destBufferSize = 32;
|
||||
@@ -1264,9 +1261,6 @@ namespace UnitTest
|
||||
AZStd::size_t rfindResult = view3.rfind('a', 2);
|
||||
EXPECT_EQ(1, rfindResult);
|
||||
|
||||
rfindResult = nullptrView4.rfind("");
|
||||
EXPECT_EQ(string_view::npos, rfindResult);
|
||||
|
||||
rfindResult = emptyView1.rfind("");
|
||||
EXPECT_EQ(string_view::npos, rfindResult);
|
||||
|
||||
@@ -1373,17 +1367,11 @@ namespace UnitTest
|
||||
{
|
||||
string_view view1("The quick brown fox jumped over the lazy dog");
|
||||
string_view view2("Needle in Haystack");
|
||||
string_view nullBeaverView(nullptr);
|
||||
string_view emptyBeaverView;
|
||||
string_view superEmptyBeaverView("");
|
||||
|
||||
EXPECT_EQ(nullBeaverView, emptyBeaverView);
|
||||
EXPECT_EQ(superEmptyBeaverView, nullBeaverView);
|
||||
EXPECT_EQ(emptyBeaverView, superEmptyBeaverView);
|
||||
EXPECT_EQ(nullBeaverView, "");
|
||||
EXPECT_EQ(nullBeaverView, nullptr);
|
||||
EXPECT_EQ("", emptyBeaverView);
|
||||
EXPECT_EQ(nullptr, superEmptyBeaverView);
|
||||
EXPECT_EQ("", superEmptyBeaverView);
|
||||
|
||||
EXPECT_EQ("The quick brown fox jumped over the lazy dog", view1);
|
||||
EXPECT_NE("The slow brown fox jumped over the lazy dog", view1);
|
||||
@@ -1421,8 +1409,6 @@ namespace UnitTest
|
||||
EXPECT_LE(beaverView, "Busy Beaver");
|
||||
EXPECT_LE("Likable Beaver", notBeaverView);
|
||||
EXPECT_LE("Busy Beaver", beaverView);
|
||||
EXPECT_LE(nullBeaverView, nullBeaverView);
|
||||
EXPECT_LE(nullBeaverView, lowerBeaverStr);
|
||||
EXPECT_LE(microBeaverStr, view1);
|
||||
EXPECT_LE(compareStr, beaverView);
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@ namespace JsonSerializationTests
|
||||
AZ::AllocatorInstance<AZ::PoolAllocator>::Destroy();
|
||||
}
|
||||
|
||||
using JsonSerializerConformityTestDescriptor<AZ::Data::Asset<TestAssetData>>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
context->RegisterGenericType<Asset>();
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include <AzCore/IO/FileReader.h>
|
||||
#include <FileIOBaseTestTypes.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
template <typename FileIOType>
|
||||
class FileReaderTestFixture
|
||||
: public ScopedAllocatorSetupFixture
|
||||
{
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
if constexpr (AZStd::is_same_v<FileIOType, TestFileIOBase>)
|
||||
{
|
||||
m_fileIo = AZStd::make_unique<TestFileIOBase>();
|
||||
}
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_fileIo.reset();
|
||||
}
|
||||
|
||||
protected:
|
||||
AZStd::unique_ptr<AZ::IO::FileIOBase> m_fileIo{};
|
||||
};
|
||||
|
||||
using FileIOTypes = ::testing::Types<void, TestFileIOBase>;
|
||||
|
||||
TYPED_TEST_CASE(FileReaderTestFixture, FileIOTypes);
|
||||
|
||||
TYPED_TEST(FileReaderTestFixture, ConstructorWithFilePath_OpensFileSuccessfully)
|
||||
{
|
||||
AZ::IO::FileReader fileReader(this->m_fileIo.get(), AZ::IO::SystemFile::GetNullFilename());
|
||||
EXPECT_TRUE(fileReader.IsOpen());
|
||||
}
|
||||
|
||||
TYPED_TEST(FileReaderTestFixture, Open_OpensFileSucessfully)
|
||||
{
|
||||
AZ::IO::FileReader fileReader;
|
||||
fileReader.Open(this->m_fileIo.get(), AZ::IO::SystemFile::GetNullFilename());
|
||||
EXPECT_TRUE(fileReader.IsOpen());
|
||||
}
|
||||
|
||||
TYPED_TEST(FileReaderTestFixture, Eof_OnNULDeviceFile_Succeeds)
|
||||
{
|
||||
AZ::IO::FileReader fileReader(this->m_fileIo.get(), AZ::IO::SystemFile::GetNullFilename());
|
||||
EXPECT_TRUE(fileReader.Eof());
|
||||
}
|
||||
|
||||
TYPED_TEST(FileReaderTestFixture, GetFilePath_ReturnsNULDeviceFilename_Succeeds)
|
||||
{
|
||||
AZ::IO::FileReader fileReader(this->m_fileIo.get(), AZ::IO::SystemFile::GetNullFilename());
|
||||
AZ::IO::FixedMaxPath filePath;
|
||||
EXPECT_TRUE(fileReader.GetFilePath(filePath));
|
||||
AZ::IO::FixedMaxPath nulFilename{ AZ::IO::SystemFile::GetNullFilename() };
|
||||
if (this->m_fileIo)
|
||||
{
|
||||
EXPECT_TRUE(this->m_fileIo->ResolvePath(nulFilename, nulFilename));
|
||||
}
|
||||
EXPECT_EQ(nulFilename, filePath);
|
||||
}
|
||||
|
||||
} // namespace UnitTest
|
||||
@@ -956,18 +956,8 @@ AZ_POP_DISABLE_WARNING
|
||||
namespace Benchmark
|
||||
{
|
||||
class PathBenchmarkFixture
|
||||
: public ::benchmark::Fixture
|
||||
, public ::UnitTest::AllocatorsBase
|
||||
: public ::UnitTest::AllocatorsBenchmarkFixture
|
||||
{
|
||||
public:
|
||||
void SetUp([[maybe_unused]] const ::benchmark::State& state) override
|
||||
{
|
||||
::UnitTest::AllocatorsBase::SetupAllocator();
|
||||
}
|
||||
void TearDown([[maybe_unused]] const ::benchmark::State& state) override
|
||||
{
|
||||
::UnitTest::AllocatorsBase::TeardownAllocator();
|
||||
}
|
||||
protected:
|
||||
AZStd::fixed_vector<const char*, 20> m_appendPaths{ "foo", "bar", "baz", "bazzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
|
||||
"boo/bar/base", "C:\\path\\to\\O3DE", "C", "\\\\", "/", R"(test\\path/with\mixed\separators)" };
|
||||
|
||||
@@ -1704,7 +1704,7 @@ namespace Benchmark
|
||||
static const AZ::u32 MEDIUM_NUMBER_OF_JOBS = 1024;
|
||||
static const AZ::u32 LARGE_NUMBER_OF_JOBS = 16384;
|
||||
|
||||
void SetUp([[maybe_unused]] ::benchmark::State& state) override
|
||||
void internalSetUp()
|
||||
{
|
||||
AllocatorInstance<PoolAllocator>::Create();
|
||||
AllocatorInstance<ThreadPoolAllocator>::Create();
|
||||
@@ -1749,8 +1749,16 @@ namespace Benchmark
|
||||
return randomDepthDistribution(randomDepthGenerator);
|
||||
});
|
||||
}
|
||||
void SetUp(::benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(const ::benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
|
||||
void TearDown([[maybe_unused]] ::benchmark::State& state) override
|
||||
void internalTearDown()
|
||||
{
|
||||
JobContext::SetGlobalContext(nullptr);
|
||||
|
||||
@@ -1763,6 +1771,14 @@ namespace Benchmark
|
||||
AllocatorInstance<ThreadPoolAllocator>::Destroy();
|
||||
AllocatorInstance<PoolAllocator>::Destroy();
|
||||
}
|
||||
void TearDown(::benchmark::State&) override
|
||||
{
|
||||
internalTearDown();
|
||||
}
|
||||
void TearDown(const ::benchmark::State&) override
|
||||
{
|
||||
internalTearDown();
|
||||
}
|
||||
|
||||
protected:
|
||||
inline void RunCalculatePiJob(AZ::s32 depth, AZ::s8 priority)
|
||||
|
||||
@@ -19,8 +19,7 @@ namespace Benchmark
|
||||
class BM_MathFrustum
|
||||
: public benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
void SetUp([[maybe_unused]] const ::benchmark::State& state) override
|
||||
void internalSetUp()
|
||||
{
|
||||
m_testFrustum = AZ::Frustum(AZ::ViewFrustumAttributes(AZ::Transform::CreateIdentity(), 1.0f, 2.0f * atanf(0.5f), 10.0f, 90.0f));
|
||||
|
||||
@@ -40,6 +39,15 @@ namespace Benchmark
|
||||
return data;
|
||||
});
|
||||
}
|
||||
public:
|
||||
void SetUp(const benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
|
||||
struct Data
|
||||
{
|
||||
|
||||
@@ -23,8 +23,7 @@ namespace Benchmark
|
||||
class BM_MathMatrix3x3
|
||||
: public benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
void SetUp([[maybe_unused]] const ::benchmark::State& state) override
|
||||
void internalSetUp()
|
||||
{
|
||||
m_testDataArray.resize(1000);
|
||||
|
||||
@@ -44,6 +43,15 @@ namespace Benchmark
|
||||
return testData;
|
||||
});
|
||||
}
|
||||
public:
|
||||
void SetUp(const benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
|
||||
struct TestData
|
||||
{
|
||||
|
||||
@@ -21,8 +21,7 @@ namespace Benchmark
|
||||
class BM_MathMatrix3x4
|
||||
: public benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
void SetUp([[maybe_unused]] const::benchmark::State& state) override
|
||||
void internalSetUp()
|
||||
{
|
||||
m_testDataArray.resize(1000);
|
||||
|
||||
@@ -58,6 +57,15 @@ namespace Benchmark
|
||||
return testData;
|
||||
});
|
||||
}
|
||||
public:
|
||||
void SetUp(const benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
|
||||
struct TestData
|
||||
{
|
||||
|
||||
@@ -20,8 +20,7 @@ namespace Benchmark
|
||||
class BM_MathMatrix4x4
|
||||
: public benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
void SetUp([[maybe_unused]] const ::benchmark::State& state) override
|
||||
void internalSetUp()
|
||||
{
|
||||
m_testDataArray.resize(1000);
|
||||
|
||||
@@ -41,6 +40,15 @@ namespace Benchmark
|
||||
return testData;
|
||||
});
|
||||
}
|
||||
public:
|
||||
void SetUp(const benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
|
||||
struct TestData
|
||||
{
|
||||
|
||||
@@ -19,8 +19,7 @@ namespace Benchmark
|
||||
class BM_MathObb
|
||||
: public benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
void SetUp([[maybe_unused]] const ::benchmark::State& state) override
|
||||
void internalSetUp()
|
||||
{
|
||||
m_position.Set(1.0f, 2.0f, 3.0f);
|
||||
m_rotation = AZ::Quaternion::CreateRotationZ(AZ::Constants::QuarterPi);
|
||||
@@ -28,6 +27,16 @@ namespace Benchmark
|
||||
m_obb = AZ::Obb::CreateFromPositionRotationAndHalfLengths(m_position, m_rotation, m_halfLengths);
|
||||
}
|
||||
|
||||
public:
|
||||
void SetUp(const benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
|
||||
AZ::Obb m_obb;
|
||||
AZ::Vector3 m_position;
|
||||
AZ::Quaternion m_rotation;
|
||||
|
||||
@@ -18,14 +18,7 @@ namespace Benchmark
|
||||
class BM_MathPlane
|
||||
: public benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
BM_MathPlane()
|
||||
{
|
||||
const unsigned int seed = 1;
|
||||
rng = std::mt19937_64(seed);
|
||||
}
|
||||
|
||||
void SetUp([[maybe_unused]] const ::benchmark::State& state) override
|
||||
void internalSetUp()
|
||||
{
|
||||
for (int i = 0; i < m_numIters; ++i)
|
||||
{
|
||||
@@ -39,7 +32,7 @@ namespace Benchmark
|
||||
m_distance = unif(rng);
|
||||
m_dists.push_back(m_distance);
|
||||
|
||||
//set these differently so they don't overlap with same values as other vectors
|
||||
// set these differently so they don't overlap with same values as other vectors
|
||||
m_normal = AZ::Vector3(unif(rng), unif(rng), unif(rng));
|
||||
m_normal.Normalize();
|
||||
m_distance = unif(rng);
|
||||
@@ -47,6 +40,21 @@ namespace Benchmark
|
||||
m_planes.push_back(m_plane);
|
||||
}
|
||||
}
|
||||
public:
|
||||
BM_MathPlane()
|
||||
{
|
||||
const unsigned int seed = 1;
|
||||
rng = std::mt19937_64(seed);
|
||||
}
|
||||
|
||||
void SetUp(const benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
|
||||
AZ::Plane m_plane;
|
||||
AZ::Vector3 m_normal;
|
||||
|
||||
@@ -17,8 +17,7 @@ namespace Benchmark
|
||||
class BM_MathQuaternion
|
||||
: public benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
void SetUp([[maybe_unused]] const ::benchmark::State& state) override
|
||||
void internalSetUp()
|
||||
{
|
||||
m_quatDataArray.resize(1000);
|
||||
|
||||
@@ -42,6 +41,15 @@ namespace Benchmark
|
||||
return quatData;
|
||||
});
|
||||
}
|
||||
public:
|
||||
void SetUp(const benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
|
||||
struct QuatData
|
||||
{
|
||||
|
||||
@@ -35,8 +35,7 @@ namespace Benchmark
|
||||
class BM_MathShapeIntersection
|
||||
: public benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
void SetUp([[maybe_unused]] const ::benchmark::State& state) override
|
||||
void internalSetUp()
|
||||
{
|
||||
m_testDataArray.resize(1000);
|
||||
|
||||
@@ -58,6 +57,15 @@ namespace Benchmark
|
||||
return testData;
|
||||
});
|
||||
}
|
||||
public:
|
||||
void SetUp(const benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
|
||||
struct TestData
|
||||
{
|
||||
|
||||
@@ -22,8 +22,7 @@ namespace Benchmark
|
||||
class BM_MathTransform
|
||||
: public benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
void SetUp([[maybe_unused]] const ::benchmark::State& state) override
|
||||
void internalSetUp()
|
||||
{
|
||||
m_testDataArray.resize(1000);
|
||||
|
||||
@@ -51,6 +50,15 @@ namespace Benchmark
|
||||
return testData;
|
||||
});
|
||||
}
|
||||
public:
|
||||
void SetUp(const benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
|
||||
struct TestData
|
||||
{
|
||||
|
||||
@@ -19,8 +19,7 @@ namespace Benchmark
|
||||
class BM_MathVector2
|
||||
: public benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
void SetUp([[maybe_unused]] const ::benchmark::State& state) override
|
||||
void internalSetUp()
|
||||
{
|
||||
m_vecDataArray.resize(1000);
|
||||
|
||||
@@ -37,6 +36,15 @@ namespace Benchmark
|
||||
return vecData;
|
||||
});
|
||||
}
|
||||
public:
|
||||
void SetUp(const benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
|
||||
struct VecData
|
||||
{
|
||||
|
||||
@@ -19,8 +19,7 @@ namespace Benchmark
|
||||
class BM_MathVector3
|
||||
: public benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
void SetUp([[maybe_unused]] const ::benchmark::State& state) override
|
||||
void internalSetUp()
|
||||
{
|
||||
m_vecDataArray.resize(1000);
|
||||
|
||||
@@ -37,6 +36,15 @@ namespace Benchmark
|
||||
return vecData;
|
||||
});
|
||||
}
|
||||
public:
|
||||
void SetUp(const benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
|
||||
struct VecData
|
||||
{
|
||||
|
||||
@@ -19,8 +19,7 @@ namespace Benchmark
|
||||
class BM_MathVector4
|
||||
: public benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
void SetUp([[maybe_unused]] const ::benchmark::State& state) override
|
||||
void internalSetUp()
|
||||
{
|
||||
m_vecDataArray.resize(1000);
|
||||
|
||||
@@ -38,6 +37,15 @@ namespace Benchmark
|
||||
return vecData;
|
||||
});
|
||||
}
|
||||
public:
|
||||
void SetUp(const benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
|
||||
struct VecData
|
||||
{
|
||||
|
||||
@@ -120,19 +120,34 @@ namespace Benchmark
|
||||
class HphaSchemaBenchmarkFixture
|
||||
: public ::benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
void SetUp(const ::benchmark::State& state) override
|
||||
void internalSetUp()
|
||||
{
|
||||
AZ_UNUSED(state);
|
||||
AZ::AllocatorInstance<HphaSchema_TestAllocator>::Create();
|
||||
}
|
||||
|
||||
void TearDown(const ::benchmark::State& state) override
|
||||
void internalTearDown()
|
||||
{
|
||||
AZ_UNUSED(state);
|
||||
AZ::AllocatorInstance<HphaSchema_TestAllocator>::Destroy();
|
||||
}
|
||||
|
||||
public:
|
||||
void SetUp(const benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void TearDown(const benchmark::State&) override
|
||||
{
|
||||
internalTearDown();
|
||||
}
|
||||
void TearDown(benchmark::State&) override
|
||||
{
|
||||
internalTearDown();
|
||||
}
|
||||
|
||||
static void BM_Allocations(benchmark::State& state, const AllocationSizeArray& allocationArray)
|
||||
{
|
||||
AZStd::vector<void*> allocations;
|
||||
|
||||
@@ -362,7 +362,7 @@ namespace UnitTest
|
||||
// Test specific construction case that was failing.
|
||||
// The constructor calls Name::SetName() which does a move assignment
|
||||
// Name& Name::operator=(Name&& rhs) was leaving m_view pointing to the m_data in a temporary Name object.
|
||||
AZ::Name emptyName(AZStd::string_view(nullptr));
|
||||
AZ::Name emptyName(AZStd::string_view{});
|
||||
EXPECT_TRUE(emptyName.IsEmpty());
|
||||
EXPECT_EQ(0, emptyName.GetStringView().data()[0]);
|
||||
}
|
||||
|
||||
+23
-13
@@ -1155,6 +1155,23 @@ namespace Benchmark
|
||||
{
|
||||
class StorageDriveWindowsFixture : public benchmark::Fixture
|
||||
{
|
||||
void internalTearDown()
|
||||
{
|
||||
using namespace AZ::IO;
|
||||
|
||||
AZStd::string temp;
|
||||
m_absolutePath.swap(temp);
|
||||
|
||||
delete m_streamer;
|
||||
m_streamer = nullptr;
|
||||
|
||||
SystemFile::Delete(TestFileName);
|
||||
|
||||
AZ::IO::FileIOBase::SetInstance(nullptr);
|
||||
AZ::IO::FileIOBase::SetInstance(m_previousFileIO);
|
||||
delete m_fileIO;
|
||||
m_fileIO = nullptr;
|
||||
}
|
||||
public:
|
||||
constexpr static const char* TestFileName = "StreamerBenchmark.bin";
|
||||
constexpr static size_t FileSize = 64_mib;
|
||||
@@ -1197,20 +1214,13 @@ namespace Benchmark
|
||||
}
|
||||
}
|
||||
|
||||
void TearDown([[maybe_unused]] const ::benchmark::State& state) override
|
||||
void TearDown(const benchmark::State&) override
|
||||
{
|
||||
using namespace AZ::IO;
|
||||
|
||||
AZStd::string temp;
|
||||
m_absolutePath.swap(temp);
|
||||
|
||||
delete m_streamer;
|
||||
|
||||
SystemFile::Delete(TestFileName);
|
||||
|
||||
AZ::IO::FileIOBase::SetInstance(nullptr);
|
||||
AZ::IO::FileIOBase::SetInstance(m_previousFileIO);
|
||||
delete m_fileIO;
|
||||
internalTearDown();
|
||||
}
|
||||
void TearDown(benchmark::State&) override
|
||||
{
|
||||
internalTearDown();
|
||||
}
|
||||
|
||||
void RepeatedlyReadFile(benchmark::State& state)
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace JsonSerializationTests
|
||||
features.m_fixedSizeArray = true;
|
||||
}
|
||||
|
||||
using JsonSerializerConformityTestDescriptor<T>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
context->RegisterGenericType<T>();
|
||||
@@ -243,6 +244,7 @@ namespace JsonSerializationTests
|
||||
])";
|
||||
}
|
||||
|
||||
using ArraySerializerTestDescriptionBase<AZStd::array<BaseClass2*, 4>>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
Base::Reflect(context);
|
||||
@@ -299,6 +301,7 @@ namespace JsonSerializationTests
|
||||
AZ::JsonArraySerializer m_serializer;
|
||||
|
||||
public:
|
||||
using BaseJsonSerializerFixture::RegisterAdditional;
|
||||
void RegisterAdditional(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
context->RegisterGenericType<Array>();
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace JsonSerializationTests
|
||||
return "[188, 288, 388]";
|
||||
}
|
||||
|
||||
using BasicContainerConformityTestDescriptor<Container>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
context->RegisterGenericType<Container>();
|
||||
@@ -133,6 +134,7 @@ namespace JsonSerializationTests
|
||||
return "[188, 288, 388]";
|
||||
}
|
||||
|
||||
using BasicContainerConformityTestDescriptor<Container>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
context->RegisterGenericType<Container>();
|
||||
@@ -225,6 +227,7 @@ namespace JsonSerializationTests
|
||||
features.m_supportsPartialInitialization = true;
|
||||
}
|
||||
|
||||
using BasicContainerConformityTestDescriptor<Container>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
SimpleClass::Reflect(context, true);
|
||||
@@ -291,6 +294,7 @@ namespace JsonSerializationTests
|
||||
using Container = AZStd::vector<SimpleClass>;
|
||||
using BaseClassContainer = AZStd::vector<AZStd::shared_ptr<BaseClass>>;
|
||||
|
||||
using JsonBasicContainerSerializerTests::RegisterAdditional;
|
||||
void RegisterAdditional(AZStd::unique_ptr<AZ::SerializeContext>& serializeContext) override
|
||||
{
|
||||
SimpleClass::Reflect(serializeContext, true);
|
||||
@@ -352,6 +356,7 @@ namespace JsonSerializationTests
|
||||
static constexpr size_t ContainerSize = 4;
|
||||
using Container = AZStd::fixed_vector<int, ContainerSize>;
|
||||
|
||||
using JsonBasicContainerSerializerTests::RegisterAdditional;
|
||||
void RegisterAdditional(AZStd::unique_ptr<AZ::SerializeContext>& serializeContext) override
|
||||
{
|
||||
serializeContext->RegisterGenericType<Container>();
|
||||
@@ -387,6 +392,7 @@ namespace JsonSerializationTests
|
||||
public:
|
||||
using Set = AZStd::set<int>;
|
||||
|
||||
using JsonBasicContainerSerializerTests::RegisterAdditional;
|
||||
void RegisterAdditional(AZStd::unique_ptr<AZ::SerializeContext>& serializeContext) override
|
||||
{
|
||||
serializeContext->RegisterGenericType<Set>();
|
||||
|
||||
@@ -83,6 +83,7 @@ namespace JsonSerializationTests
|
||||
BaseJsonSerializerFixture::TearDown();
|
||||
}
|
||||
|
||||
using BaseJsonSerializerFixture::RegisterAdditional;
|
||||
void RegisterAdditional(AZStd::unique_ptr<AZ::SerializeContext>& serializeContext) override
|
||||
{
|
||||
serializeContext->Class<BoolPointerWrapper>()
|
||||
|
||||
@@ -95,6 +95,7 @@ namespace JsonSerializationTests
|
||||
BaseJsonSerializerFixture::TearDown();
|
||||
}
|
||||
|
||||
using BaseJsonSerializerFixture::RegisterAdditional;
|
||||
void RegisterAdditional(AZStd::unique_ptr<AZ::SerializeContext>& serializeContext) override
|
||||
{
|
||||
serializeContext->Class<DoublePointerWrapper>()
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace JsonSerializationTests
|
||||
features.m_supportsPartialInitialization = false;
|
||||
}
|
||||
|
||||
using JsonSerializerConformityTestDescriptor<Map>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
context->RegisterGenericType<Map>();
|
||||
@@ -247,6 +248,7 @@ namespace JsonSerializationTests
|
||||
features.m_supportsPartialInitialization = true;
|
||||
}
|
||||
|
||||
using MapBaseTestDescription<T<SimpleClass*, SimpleClass*>, Serializer>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
SimpleClass::Reflect(context, true);
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace JsonSerializationTests
|
||||
return AZStd::make_shared<SmartPointer>();
|
||||
}
|
||||
|
||||
using JsonSerializerConformityTestDescriptor<SmartPointer>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
context->RegisterGenericType<SmartPointer>();
|
||||
@@ -102,6 +103,7 @@ namespace JsonSerializationTests
|
||||
return *lhs == *rhs;
|
||||
}
|
||||
|
||||
using Base::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
SimpleClass::Reflect(context, true);
|
||||
@@ -176,6 +178,7 @@ namespace JsonSerializationTests
|
||||
features.m_supportsPartialInitialization = true;
|
||||
}
|
||||
|
||||
using SmartPointerBaseTestDescription<T<BaseClass>>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
SimpleInheritence::Reflect(context, true);
|
||||
@@ -340,6 +343,7 @@ namespace JsonSerializationTests
|
||||
features.m_supportsPartialInitialization = true;
|
||||
}
|
||||
|
||||
using SmartPointerBaseTestDescription<T<BaseClass2>>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
MultipleInheritence::Reflect(context, true);
|
||||
@@ -513,7 +517,8 @@ namespace JsonSerializationTests
|
||||
public:
|
||||
using SmartPointer = typename SmartPointerSimpleDerivedClassTestDescription<AZStd::shared_ptr>::SmartPointer;
|
||||
using InstanceSmartPointer = AZStd::shared_ptr<SimpleInheritence>;
|
||||
|
||||
|
||||
using BaseJsonSerializerFixture::RegisterAdditional;
|
||||
void RegisterAdditional(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
m_description.Reflect(context);
|
||||
|
||||
@@ -72,6 +72,7 @@ namespace JsonSerializationTests
|
||||
TupleSerializerTestsInternal::ConfigureFeatures(features);
|
||||
}
|
||||
|
||||
using JsonSerializerConformityTestDescriptor<AZStd::pair<int, double>>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
context->Class<PairPlaceholder>()->Field("pair", &PairPlaceholder::m_pair);
|
||||
@@ -126,6 +127,7 @@ namespace JsonSerializationTests
|
||||
TupleSerializerTestsInternal::ConfigureFeatures(features);
|
||||
}
|
||||
|
||||
using JsonSerializerConformityTestDescriptor<Tuple>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
context->RegisterGenericType<Tuple>();
|
||||
@@ -344,6 +346,7 @@ namespace JsonSerializationTests
|
||||
features.m_enableNewInstanceTests = false;
|
||||
}
|
||||
|
||||
using JsonSerializerConformityTestDescriptor::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
context->Class<TupleClass>()
|
||||
@@ -477,6 +480,7 @@ namespace JsonSerializationTests
|
||||
features.m_typeToInject = rapidjson::kNullType;
|
||||
}
|
||||
|
||||
using JsonSerializerConformityTestDescriptor<Tuple>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
context->RegisterGenericType<Tuple>();
|
||||
@@ -535,6 +539,7 @@ namespace JsonSerializationTests
|
||||
BaseJsonSerializerFixture::TearDown();
|
||||
}
|
||||
|
||||
using BaseJsonSerializerFixture::RegisterAdditional;
|
||||
void RegisterAdditional(AZStd::unique_ptr<AZ::SerializeContext>& serializeContext) override
|
||||
{
|
||||
SimpleClass::Reflect(serializeContext, true);
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace JsonSerializationTests
|
||||
features.m_supportsPartialInitialization = false;
|
||||
}
|
||||
|
||||
using JsonSerializerConformityTestDescriptor<AZStd::unordered_set<int>>::Reflect;
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
context->RegisterGenericType<Set>();
|
||||
@@ -108,6 +109,7 @@ namespace JsonSerializationTests
|
||||
context->RegisterGenericType<MultiSet>();
|
||||
}
|
||||
|
||||
using JsonSerializerConformityTestDescriptor<MultiSet>::Reflect;
|
||||
bool AreEqual(const MultiSet& lhs, const MultiSet& rhs) override
|
||||
{
|
||||
return
|
||||
@@ -139,6 +141,7 @@ namespace JsonSerializationTests
|
||||
BaseJsonSerializerFixture::TearDown();
|
||||
}
|
||||
|
||||
using BaseJsonSerializerFixture::RegisterAdditional;
|
||||
void RegisterAdditional(AZStd::unique_ptr<AZ::SerializeContext>& serializeContext) override
|
||||
{
|
||||
serializeContext->RegisterGenericType<Set>();
|
||||
|
||||
@@ -423,6 +423,8 @@ namespace SettingsRegistryTests
|
||||
|
||||
struct : public AZ::SettingsRegistryInterface::Visitor
|
||||
{
|
||||
using AZ::SettingsRegistryInterface::Visitor::Visit;
|
||||
|
||||
using ValueType [[maybe_unused]] = typename SettingsType<TypeParam>::ValueType;
|
||||
void Visit([[maybe_unused]] AZStd::string_view path, [[maybe_unused]] AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type type, ValueType value) override
|
||||
{
|
||||
@@ -452,6 +454,8 @@ namespace SettingsRegistryTests
|
||||
|
||||
struct : public AZ::SettingsRegistryInterface::Visitor
|
||||
{
|
||||
using AZ::SettingsRegistryInterface::Visitor::Visit;
|
||||
|
||||
using ValueType [[maybe_unused]] = typename SettingsType<TypeParam>::ValueType;
|
||||
void Visit([[maybe_unused]] AZStd::string_view path, [[maybe_unused]] AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type type, ValueType value) override
|
||||
{
|
||||
@@ -482,6 +486,7 @@ namespace SettingsRegistryTests
|
||||
|
||||
struct : public AZ::SettingsRegistryInterface::Visitor
|
||||
{
|
||||
using AZ::SettingsRegistryInterface::Visitor::Visit;
|
||||
void Visit([[maybe_unused]] AZStd::string_view path, [[maybe_unused]] AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type type, AZ::s64 value) override
|
||||
{
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::Integer, type);
|
||||
@@ -517,6 +522,8 @@ namespace SettingsRegistryTests
|
||||
EXPECT_TRUE(path.ends_with(valueName));
|
||||
return AZ::SettingsRegistryInterface::VisitResponse::Continue;
|
||||
}
|
||||
|
||||
using AZ::SettingsRegistryInterface::Visitor::Visit;
|
||||
void Visit(AZStd::string_view path, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type , AZStd::string_view)override
|
||||
{
|
||||
EXPECT_TRUE(path.ends_with(valueName));
|
||||
@@ -1510,7 +1517,7 @@ namespace SettingsRegistryTests
|
||||
|
||||
m_testFolder->push_back(AZ_CORRECT_DATABASE_SEPARATOR);
|
||||
*m_testFolder += AZ::SettingsRegistryInterface::RegistryFolder;
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, {}, nullptr);
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, {});
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(4, counter);
|
||||
|
||||
@@ -1552,7 +1559,7 @@ namespace SettingsRegistryTests
|
||||
|
||||
m_testFolder->push_back(AZ_CORRECT_DATABASE_SEPARATOR);
|
||||
*m_testFolder += AZ::SettingsRegistryInterface::RegistryFolder;
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, "Special", nullptr);
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, "Special");
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(6, counter);
|
||||
|
||||
@@ -1591,7 +1598,7 @@ namespace SettingsRegistryTests
|
||||
|
||||
m_testFolder->push_back(AZ_CORRECT_DATABASE_SEPARATOR);
|
||||
*m_testFolder += AZ::SettingsRegistryInterface::RegistryFolder;
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, {}, nullptr);
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, {});
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(4, counter);
|
||||
|
||||
@@ -1632,7 +1639,7 @@ namespace SettingsRegistryTests
|
||||
|
||||
m_testFolder->push_back(AZ_CORRECT_DATABASE_SEPARATOR);
|
||||
*m_testFolder += AZ::SettingsRegistryInterface::RegistryFolder;
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, {}, nullptr);
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, {});
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(4, counter);
|
||||
|
||||
@@ -1665,7 +1672,7 @@ namespace SettingsRegistryTests
|
||||
|
||||
m_testFolder->push_back(AZ_CORRECT_DATABASE_SEPARATOR);
|
||||
*m_testFolder += AZ::SettingsRegistryInterface::RegistryFolder;
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, "Special", nullptr);
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, "Special");
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(1, counter);
|
||||
|
||||
@@ -1715,7 +1722,7 @@ namespace SettingsRegistryTests
|
||||
|
||||
TEST_F(SettingsRegistryTest, MergeSettingsFolder_EmptyFolder_ReportsSuccessButNothingAdded)
|
||||
{
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, {}, nullptr);
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, {});
|
||||
EXPECT_TRUE(result);
|
||||
|
||||
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::Object, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/0")); // Folder and specialization settings.
|
||||
@@ -1727,7 +1734,7 @@ namespace SettingsRegistryTests
|
||||
constexpr AZStd::fixed_string<AZ::IO::MaxPathLength + 1> path(AZ::IO::MaxPathLength + 1, 'a');
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
bool result = m_registry->MergeSettingsFolder(path, { "editor", "test" }, {}, nullptr);
|
||||
bool result = m_registry->MergeSettingsFolder(path, { "editor", "test" }, {});
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
EXPECT_FALSE(result);
|
||||
|
||||
@@ -1744,7 +1751,7 @@ namespace SettingsRegistryTests
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
m_testFolder->push_back(AZ_CORRECT_DATABASE_SEPARATOR);
|
||||
*m_testFolder += AZ::SettingsRegistryInterface::RegistryFolder;
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, {}, nullptr);
|
||||
bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, {});
|
||||
EXPECT_GT(::UnitTest::TestRunner::Instance().StopAssertTests(), 0);
|
||||
EXPECT_FALSE(result);
|
||||
|
||||
|
||||
@@ -551,19 +551,37 @@ namespace Benchmark
|
||||
{
|
||||
class TaskGraphBenchmarkFixture : public ::benchmark::Fixture
|
||||
{
|
||||
public:
|
||||
void SetUp(benchmark::State&) override
|
||||
void internalSetUp()
|
||||
{
|
||||
executor = new TaskExecutor;
|
||||
graph = new TaskGraph;
|
||||
}
|
||||
|
||||
void TearDown(benchmark::State&) override
|
||||
void internalTearDown()
|
||||
{
|
||||
delete graph;
|
||||
delete executor;
|
||||
}
|
||||
|
||||
public:
|
||||
void SetUp(const benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
void SetUp(benchmark::State&) override
|
||||
{
|
||||
internalSetUp();
|
||||
}
|
||||
|
||||
void TearDown(const benchmark::State&) override
|
||||
{
|
||||
internalTearDown();
|
||||
}
|
||||
void TearDown(benchmark::State&) override
|
||||
{
|
||||
internalTearDown();
|
||||
}
|
||||
|
||||
TaskDescriptor descriptors[4] = { { "critical", "benchmark", TaskPriority::CRITICAL },
|
||||
{ "high", "benchmark", TaskPriority::HIGH },
|
||||
{ "medium", "benchmark", TaskPriority::MEDIUM },
|
||||
|
||||
@@ -37,6 +37,7 @@ set(FILES
|
||||
FileIOBaseTestTypes.h
|
||||
Geometry2DUtils.cpp
|
||||
Interface.cpp
|
||||
IO/FileReaderTests.cpp
|
||||
IO/Path/PathTests.cpp
|
||||
IPC.cpp
|
||||
Jobs.cpp
|
||||
|
||||
@@ -81,71 +81,6 @@ namespace AzFramework
|
||||
static constexpr const char s_prefabSystemKey[] = "/Amazon/Preferences/EnablePrefabSystem";
|
||||
static constexpr const char s_prefabWipSystemKey[] = "/Amazon/Preferences/EnablePrefabSystemWipFeatures";
|
||||
static constexpr const char s_legacySlicesAssertKey[] = "/Amazon/Preferences/ShouldAssertForLegacySlicesUsage";
|
||||
|
||||
// A Helper function that can load an app descriptor from file.
|
||||
AZ::Outcome<AZStd::unique_ptr<AZ::ComponentApplication::Descriptor>, AZStd::string> LoadDescriptorFromFilePath(const char* appDescriptorFilePath, AZ::SerializeContext& serializeContext)
|
||||
{
|
||||
AZStd::unique_ptr<AZ::ComponentApplication::Descriptor> loadedDescriptor;
|
||||
|
||||
AZ::IO::SystemFile appDescriptorFile;
|
||||
if (!appDescriptorFile.Open(appDescriptorFilePath, AZ::IO::SystemFile::SF_OPEN_READ_ONLY))
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("Failed to open file: %s", appDescriptorFilePath));
|
||||
}
|
||||
|
||||
AZ::IO::SystemFileStream appDescriptorFileStream(&appDescriptorFile, true);
|
||||
if (!appDescriptorFileStream.IsOpen())
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("Failed to stream file: %s", appDescriptorFilePath));
|
||||
}
|
||||
|
||||
// Callback function for allocating the root elements in the file.
|
||||
AZ::ObjectStream::InplaceLoadRootInfoCB inplaceLoadCb =
|
||||
[](void** rootAddress, const AZ::SerializeContext::ClassData**, const AZ::Uuid& classId, AZ::SerializeContext*)
|
||||
{
|
||||
if (rootAddress && classId == azrtti_typeid<AZ::ComponentApplication::Descriptor>())
|
||||
{
|
||||
// ComponentApplication::Descriptor is normally a singleton.
|
||||
// Force a unique instance to be created.
|
||||
*rootAddress = aznew AZ::ComponentApplication::Descriptor();
|
||||
}
|
||||
};
|
||||
|
||||
// Callback function for saving the root elements in the file.
|
||||
AZ::ObjectStream::ClassReadyCB classReadyCb =
|
||||
[&loadedDescriptor](void* classPtr, const AZ::Uuid& classId, AZ::SerializeContext* context)
|
||||
{
|
||||
// Save descriptor, delete anything else loaded from file.
|
||||
if (classId == azrtti_typeid<AZ::ComponentApplication::Descriptor>())
|
||||
{
|
||||
loadedDescriptor.reset(static_cast<AZ::ComponentApplication::Descriptor*>(classPtr));
|
||||
}
|
||||
else if (const AZ::SerializeContext::ClassData* classData = context->FindClassData(classId))
|
||||
{
|
||||
classData->m_factory->Destroy(classPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("Application", false, "Unexpected type %s found in application descriptor file. This memory will leak.",
|
||||
classId.ToString<AZStd::string>().c_str());
|
||||
}
|
||||
};
|
||||
|
||||
// There's other stuff in the file we may not recognize (system components), but we're not interested in that stuff.
|
||||
AZ::ObjectStream::FilterDescriptor loadFilter(&AZ::Data::AssetFilterNoAssetLoading, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES);
|
||||
|
||||
if (!AZ::ObjectStream::LoadBlocking(&appDescriptorFileStream, serializeContext, classReadyCb, loadFilter, inplaceLoadCb))
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("Failed to load objects from file: %s", appDescriptorFilePath));
|
||||
}
|
||||
|
||||
if (!loadedDescriptor)
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("Failed to find descriptor object in file: %s", appDescriptorFilePath));
|
||||
}
|
||||
|
||||
return AZ::Success(AZStd::move(loadedDescriptor));
|
||||
}
|
||||
}
|
||||
|
||||
Application::Application()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,7 @@
|
||||
#include <AzCore/IO/CompressionBus.h>
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/std/containers/set.h>
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
#include <AzCore/std/parallel/lock.h>
|
||||
#include <AzCore/std/parallel/thread.h>
|
||||
@@ -26,7 +27,6 @@
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
#include <AzCore/std/string/osstring.h>
|
||||
|
||||
#include <AzFramework/Archive/IArchive.h>
|
||||
#include <AzFramework/Archive/ZipDirCache.h>
|
||||
@@ -115,12 +115,12 @@ namespace AZ::IO
|
||||
struct PackDesc
|
||||
{
|
||||
AZ::IO::Path m_pathBindRoot; // the zip binding root
|
||||
AZStd::string strFileName; // the zip file name (with path) - very useful for debugging so please don't remove
|
||||
AZ::IO::Path m_strFileName; // the zip file name (with path) - very useful for debugging so please don't remove
|
||||
|
||||
// [LYN-2376] Remove once legacy slice support is removed
|
||||
bool m_containsLevelPak = false; // indicates whether this archive has level.pak inside it or not
|
||||
|
||||
const char* GetFullPath() const { return pZip->GetFilePath(); }
|
||||
AZ::IO::PathView GetFullPath() const { return pZip->GetFilePath(); }
|
||||
|
||||
AZStd::intrusive_ptr<INestedArchive> pArchive;
|
||||
ZipDir::CachePtr pZip;
|
||||
@@ -129,10 +129,7 @@ namespace AZ::IO
|
||||
|
||||
// ArchiveFindDataSet entire purpose is to keep a reference to the intrusive_ptr of ArchiveFindData
|
||||
// so that it doesn't go out of scope
|
||||
using ArchiveFindDataSet = AZStd::set<AZStd::intrusive_ptr<AZ::IO::FindData>, AZ::OSStdAllocator>;
|
||||
|
||||
// given the source relative path, constructs the full path to the file according to the flags
|
||||
const char* AdjustFileName(AZStd::string_view src, char* dst, size_t dstSize, uint32_t nFlags, bool skipMods = false) override;
|
||||
using ArchiveFindDataSet = AZStd::set<AZStd::intrusive_ptr<AZ::IO::FindData>>;
|
||||
|
||||
|
||||
/**
|
||||
@@ -154,29 +151,17 @@ namespace AZ::IO
|
||||
//! CompressionBus Handler implementation.
|
||||
void FindCompressionInfo(bool& found, AZ::IO::CompressionInfo& info, const AZStd::string_view filename) override;
|
||||
|
||||
//! Processes an alias command line containing multiple aliases.
|
||||
void ParseAliases(AZStd::string_view szCommandLine) override;
|
||||
//! adds or removes an alias from the list - if bAdd set to false will remove it
|
||||
void SetAlias(AZStd::string_view szName, AZStd::string_view szAlias, bool bAdd) override;
|
||||
//! gets an alias from the list, if any exist.
|
||||
//! if bReturnSame==true, it will return the input name if an alias doesn't exist. Otherwise returns nullptr
|
||||
const char* GetAlias(AZStd::string_view szName, bool bReturnSame = true) override;
|
||||
|
||||
// Set the localization folder
|
||||
void SetLocalizationFolder(AZStd::string_view sLocalizationFolder) override;
|
||||
const char* GetLocalizationFolder() const override { return m_sLocalizationFolder.c_str(); }
|
||||
const char* GetLocalizationRoot() const override { return m_sLocalizationRoot.c_str(); }
|
||||
|
||||
// lock all the operations
|
||||
void Lock() override;
|
||||
void Unlock() override;
|
||||
|
||||
// open the physical archive file - creates if it doesn't exist
|
||||
// returns nullptr if it's invalid or can't open the file
|
||||
AZStd::intrusive_ptr<INestedArchive> OpenArchive(AZStd::string_view szPath, AZStd::string_view bindRoot = {}, uint32_t nFlags = 0, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = nullptr) override;
|
||||
AZStd::intrusive_ptr<INestedArchive> OpenArchive(AZStd::string_view szPath, AZStd::string_view bindRoot = {}, uint32_t nArchiveFlags = 0, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = nullptr) override;
|
||||
|
||||
// returns the path to the archive in which the file was opened
|
||||
const char* GetFileArchivePath(AZ::IO::HandleType fileHandle) override;
|
||||
AZ::IO::PathView GetFileArchivePath(AZ::IO::HandleType fileHandle) override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -192,40 +177,31 @@ namespace AZ::IO
|
||||
void RegisterFileAccessSink(IArchiveFileAccessSink* pSink) override;
|
||||
void UnregisterFileAccessSink(IArchiveFileAccessSink* pSink) override;
|
||||
|
||||
bool Init(AZStd::string_view szBasePath) override;
|
||||
void Release() override;
|
||||
|
||||
bool IsInstalledToHDD(AZStd::string_view acFilePath = 0) const override;
|
||||
|
||||
// [LYN-2376] Remove 'addLevels' parameter once legacy slice support is removed
|
||||
bool OpenPack(AZStd::string_view pName, uint32_t nFlags = 0, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = nullptr, AZ::IO::FixedMaxPathString* pFullPath = nullptr, bool addLevels = true) override;
|
||||
bool OpenPack(AZStd::string_view szBindRoot, AZStd::string_view pName, uint32_t nFlags = 0, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = nullptr, AZ::IO::FixedMaxPathString* pFullPath = nullptr, bool addLevels = true) override;
|
||||
bool OpenPack(AZStd::string_view pName, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = nullptr, AZ::IO::FixedMaxPathString* pFullPath = nullptr, bool addLevels = true) override;
|
||||
bool OpenPack(AZStd::string_view szBindRoot, AZStd::string_view pName, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = nullptr, AZ::IO::FixedMaxPathString* pFullPath = nullptr, bool addLevels = true) override;
|
||||
// after this call, the file will be unlocked and closed, and its contents won't be used to search for files
|
||||
bool ClosePack(AZStd::string_view pName, uint32_t nFlags = 0) override;
|
||||
bool OpenPacks(AZStd::string_view pWildcard, uint32_t nFlags = 0, AZStd::vector<AZ::IO::FixedMaxPathString>* pFullPaths = nullptr) override;
|
||||
bool OpenPacks(AZStd::string_view szBindRoot, AZStd::string_view pWildcard, uint32_t nFlags = 0, AZStd::vector<AZ::IO::FixedMaxPathString>* pFullPaths = nullptr) override;
|
||||
bool ClosePack(AZStd::string_view pName) override;
|
||||
bool OpenPacks(AZStd::string_view pWildcard, AZStd::vector<AZ::IO::FixedMaxPathString>* pFullPaths = nullptr) override;
|
||||
bool OpenPacks(AZStd::string_view szBindRoot, AZStd::string_view pWildcard, AZStd::vector<AZ::IO::FixedMaxPathString>* pFullPaths = nullptr) override;
|
||||
|
||||
// closes pack files by the path and wildcard
|
||||
bool ClosePacks(AZStd::string_view pWildcard, uint32_t nFlags = 0) override;
|
||||
bool ClosePacks(AZStd::string_view pWildcard) override;
|
||||
|
||||
//returns if a archive exists matching the wildcard
|
||||
bool FindPacks(AZStd::string_view pWildcardIn) override;
|
||||
|
||||
// prevent access to specific archive files
|
||||
bool SetPacksAccessible(bool bAccessible, AZStd::string_view pWildcard, uint32_t nFlags = 0) override;
|
||||
bool SetPackAccessible(bool bAccessible, AZStd::string_view pName, uint32_t nFlags = 0) override;
|
||||
bool SetPacksAccessible(bool bAccessible, AZStd::string_view pWildcard) override;
|
||||
bool SetPackAccessible(bool bAccessible, AZStd::string_view pName) override;
|
||||
|
||||
// returns the file modification time
|
||||
uint64_t GetModificationTime(AZ::IO::HandleType fileHandle) override;
|
||||
|
||||
bool LoadPakToMemory(AZStd::string_view pName, EInMemoryArchiveLocation nLoadArchiveToMemory, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pMemoryBlock = nullptr) override;
|
||||
void LoadPaksToMemory(int nMaxArchiveSize, bool bLoadToMemory) override;
|
||||
|
||||
AZ::IO::HandleType FOpen(AZStd::string_view pName, const char* mode, uint32_t nPathFlags = 0) override;
|
||||
size_t FReadRaw(void* data, size_t length, size_t elems, AZ::IO::HandleType handle) override;
|
||||
size_t FReadRawAll(void* data, size_t nFileSize, AZ::IO::HandleType handle) override;
|
||||
AZ::IO::HandleType FOpen(AZStd::string_view pName, const char* mode) override;
|
||||
size_t FRead(void* data, size_t bytesToRead, AZ::IO::HandleType handle) override;
|
||||
void* FGetCachedFileData(AZ::IO::HandleType handle, size_t& nFileSize) override;
|
||||
size_t FWrite(const void* data, size_t length, size_t elems, AZ::IO::HandleType handle) override;
|
||||
size_t FWrite(const void* data, size_t bytesToWrite, AZ::IO::HandleType handle) override;
|
||||
size_t FSeek(AZ::IO::HandleType handle, uint64_t seek, int mode) override;
|
||||
uint64_t FTell(AZ::IO::HandleType handle) override;
|
||||
int FFlush(AZ::IO::HandleType handle) override;
|
||||
@@ -234,9 +210,7 @@ namespace AZ::IO
|
||||
AZ::IO::ArchiveFileIterator FindNext(AZ::IO::ArchiveFileIterator fileIterator) override;
|
||||
bool FindClose(AZ::IO::ArchiveFileIterator fileIterator) override;
|
||||
int FEof(AZ::IO::HandleType handle) override;
|
||||
char* FGets(char*, int, AZ::IO::HandleType) override;
|
||||
int Getc(AZ::IO::HandleType) override;
|
||||
int FPrintf(AZ::IO::HandleType handle, const char* format, ...) override;
|
||||
|
||||
size_t FGetSize(AZ::IO::HandleType fileHandle) override;
|
||||
size_t FGetSize(AZStd::string_view sFilename, bool bAllowUseFileSystem = false) override;
|
||||
bool IsInPak(AZ::IO::HandleType handle) override;
|
||||
@@ -248,9 +222,6 @@ namespace AZ::IO
|
||||
bool IsFolder(AZStd::string_view sPath) override;
|
||||
IArchive::SignedFileSize GetFileSizeOnDisk(AZStd::string_view filename) override;
|
||||
|
||||
// creates a directory
|
||||
bool MakeDir(AZStd::string_view szPath) override;
|
||||
|
||||
// compresses the raw data into raw data. The buffer for compressed data itself with the heap passed. Uses method 8 (deflate)
|
||||
// returns one of the Z_* errors (Z_OK upon success)
|
||||
// MT-safe
|
||||
@@ -275,22 +246,12 @@ namespace AZ::IO
|
||||
IResourceList* GetResourceList(ERecordFileOpenList eList) override;
|
||||
void SetResourceList(ERecordFileOpenList eList, IResourceList* pResourceList) override;
|
||||
|
||||
uint32_t ComputeCRC(AZStd::string_view szPath, uint32_t nFileOpenFlags = 0) override;
|
||||
bool ComputeMD5(AZStd::string_view szPath, uint8_t* md5, uint32_t nFileOpenFlags = 0, bool useDirectFileAccess = false) override;
|
||||
|
||||
void DisableRuntimeFileAccess(bool status) override
|
||||
{
|
||||
m_disableRuntimeFileAccess[0] = status;
|
||||
m_disableRuntimeFileAccess[1] = status;
|
||||
m_disableRuntimeFileAccess = status;
|
||||
}
|
||||
|
||||
bool DisableRuntimeFileAccess(bool status, AZStd::thread_id threadId) override;
|
||||
bool CheckFileAccessDisabled(AZStd::string_view name, const char* mode) override;
|
||||
|
||||
void SetRenderThreadId(AZStd::thread_id renderThreadId) override
|
||||
{
|
||||
m_renderThreadId = renderThreadId;
|
||||
}
|
||||
|
||||
// gets the current archive priority
|
||||
ArchiveLocationPriority GetPakPriority() const override;
|
||||
@@ -307,11 +268,11 @@ namespace AZ::IO
|
||||
// Return cached file data for entries inside archive file.
|
||||
CCachedFileDataPtr GetOpenedFileDataInZip(AZ::IO::HandleType file);
|
||||
ZipDir::FileEntry* FindPakFileEntry(AZStd::string_view szPath, uint32_t& nArchiveFlags,
|
||||
ZipDir::CachePtr* pZip = {}, bool bSkipInMemoryArchives = {}) const;
|
||||
ZipDir::CachePtr* pZip = {}) const;
|
||||
private:
|
||||
|
||||
bool OpenPackCommon(AZStd::string_view szBindRoot, AZStd::string_view pName, uint32_t nArchiveFlags, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = nullptr, bool addLevels = true);
|
||||
bool OpenPacksCommon(AZStd::string_view szDir, AZStd::string_view pWildcardIn, uint32_t nArchiveFlags, AZStd::vector<AZ::IO::FixedMaxPathString>* pFullPaths = nullptr, bool addLevels = true);
|
||||
bool OpenPackCommon(AZStd::string_view szBindRoot, AZStd::string_view pName, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = nullptr, bool addLevels = true);
|
||||
bool OpenPacksCommon(AZStd::string_view szDir, AZStd::string_view pWildcardIn, AZStd::vector<AZ::IO::FixedMaxPathString>* pFullPaths = nullptr, bool addLevels = true);
|
||||
|
||||
ZipDir::FileEntry* FindPakFileEntry(AZStd::string_view szPath) const;
|
||||
|
||||
@@ -346,9 +307,6 @@ namespace AZ::IO
|
||||
AZStd::mutex m_cachedFileRawDataMutex;
|
||||
// For m_pCachedFileRawDataSet
|
||||
using RawDataCacheLockGuard = AZStd::scoped_lock<decltype(m_cachedFileRawDataMutex)>;
|
||||
// The F* emulation functions critical section: protects all F* functions
|
||||
// that don't have a chance to be called recursively (to avoid deadlocks)
|
||||
AZStd::mutex m_csMain;
|
||||
mutable AZStd::shared_mutex m_archiveMutex;
|
||||
ArchiveArray m_arrArchives;
|
||||
|
||||
@@ -360,8 +318,6 @@ namespace AZ::IO
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IArchive::ERecordFileOpenList m_eRecordFileOpenList = RFOM_Disabled;
|
||||
using RecordedFilesSet = AZStd::set<AZ::OSString, AZ::IO::AZStdStringLessCaseInsensitive, AZ::OSStdAllocator>;
|
||||
RecordedFilesSet m_recordedFilesSet;
|
||||
|
||||
AZStd::intrusive_ptr<IResourceList> m_pEngineStartupResourceList;
|
||||
|
||||
@@ -372,28 +328,16 @@ namespace AZ::IO
|
||||
float m_fFileAccessTime{}; // Time used to perform file operations
|
||||
AZStd::vector<IArchiveFileAccessSink*, AZ::OSStdAllocator> m_FileAccessSinks; // useful for gathering file access statistics
|
||||
|
||||
bool m_disableRuntimeFileAccess[2]{};
|
||||
bool m_disableRuntimeFileAccess{};
|
||||
|
||||
//threads which we don't want to access files from during the game
|
||||
AZStd::thread_id m_mainThreadId{};
|
||||
AZStd::thread_id m_renderThreadId{};
|
||||
|
||||
AZStd::fixed_string<128> m_sLocalizationFolder;
|
||||
AZStd::fixed_string<128> m_sLocalizationRoot;
|
||||
|
||||
AZStd::set<uint32_t, AZStd::less<>, AZ::OSStdAllocator> m_filesCachedOnHDD;
|
||||
|
||||
// [LYN-2376] Remove once legacy slice support is removed
|
||||
LevelPackOpenEvent m_levelOpenEvent;
|
||||
LevelPackCloseEvent m_levelCloseEvent;
|
||||
};
|
||||
}
|
||||
|
||||
namespace AZ::IO::ArchiveInternal
|
||||
{
|
||||
// Utility function to de-alias archive file opening and file-within-archive opening
|
||||
// if the file specified was an absolute path but it points at one of the aliases, de-alias it and replace it with that alias.
|
||||
// this works around problems where the level editor is in control but still mounts asset packs (ie, level.pak mounted as @assets@)
|
||||
AZStd::optional<AZ::IO::FixedMaxPath> ConvertAbsolutePathToAliasedPath(AZStd::string_view sourcePath,
|
||||
AZStd::string_view aliasToLookFor = "@devassets@", AZStd::string_view aliasToReplaceWith = "@assets@");
|
||||
}
|
||||
|
||||
@@ -5,10 +5,9 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/std/parallel/lock.h>
|
||||
#include <AzCore/std/functional.h> // for function<> in the find files callback.
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzFramework/Archive/ArchiveFileIO.h>
|
||||
#include <AzFramework/Archive/IArchive.h>
|
||||
|
||||
@@ -188,7 +187,7 @@ namespace AZ::IO
|
||||
return IO::ResultCode::Error;
|
||||
}
|
||||
|
||||
size_t result = m_archive->FReadRaw(buffer, 1, size, fileHandle);
|
||||
size_t result = m_archive->FRead(buffer, size, fileHandle);
|
||||
if (bytesRead)
|
||||
{
|
||||
*bytesRead = static_cast<AZ::u64>(result);
|
||||
@@ -213,7 +212,7 @@ namespace AZ::IO
|
||||
return IO::ResultCode::Error;
|
||||
}
|
||||
|
||||
size_t result = m_archive->FWrite(buffer, 1, size, fileHandle);
|
||||
size_t result = m_archive->FWrite(buffer, size, fileHandle);
|
||||
if (bytesWritten)
|
||||
{
|
||||
*bytesWritten = static_cast<AZ::u64>(result);
|
||||
@@ -357,14 +356,8 @@ namespace AZ::IO
|
||||
return IO::ResultCode::Error;
|
||||
}
|
||||
|
||||
// avoid using AZStd::string if possible - use OSString instead of StringFunc
|
||||
AZ::OSString destPath(destinationFilePath);
|
||||
IO::Path destPath(IO::PathView(destinationFilePath).ParentPath());
|
||||
|
||||
AZ::OSString::size_type pos = destPath.find_last_of(AZ_CORRECT_AND_WRONG_FILESYSTEM_SEPARATOR);
|
||||
if (pos != AZ::OSString::npos)
|
||||
{
|
||||
destPath.resize(pos);
|
||||
}
|
||||
CreatePath(destPath.c_str());
|
||||
|
||||
if (!Open(destinationFilePath, IO::OpenMode::ModeWrite | IO::OpenMode::ModeBinary, destinationFile))
|
||||
@@ -466,31 +459,25 @@ namespace AZ::IO
|
||||
return IO::ResultCode::Error;
|
||||
}
|
||||
|
||||
AZStd::fixed_string<AZ_MAX_PATH_LEN> total = filePath;
|
||||
AZ::IO::FixedMaxPath total = filePath;
|
||||
if (total.empty())
|
||||
{
|
||||
return IO::ResultCode::Error;
|
||||
}
|
||||
|
||||
if (!total.ends_with(AZ_CORRECT_FILESYSTEM_SEPARATOR) && !total.ends_with(AZ_WRONG_FILESYSTEM_SEPARATOR))
|
||||
{
|
||||
total.append(AZ_CORRECT_FILESYSTEM_SEPARATOR_STRING);
|
||||
}
|
||||
|
||||
total.append(filter);
|
||||
total /= filter;
|
||||
|
||||
AZ::IO::ArchiveFileIterator fileIterator = m_archive->FindFirst(total.c_str());
|
||||
if (!fileIterator)
|
||||
{
|
||||
return IO::ResultCode::Success; // its not an actual fatal error to not find anything.
|
||||
}
|
||||
for (;fileIterator; fileIterator = m_archive->FindNext(fileIterator))
|
||||
for (; fileIterator; fileIterator = m_archive->FindNext(fileIterator))
|
||||
{
|
||||
total = AZStd::fixed_string<AZ_MAX_PATH_LEN>::format("%s/%.*s", filePath, aznumeric_cast<int>(fileIterator.m_filename.size()), fileIterator.m_filename.data());
|
||||
AZStd::optional resolvedAliasLength = ConvertToAlias(total.data(), total.capacity());
|
||||
if (resolvedAliasLength)
|
||||
total = filePath;
|
||||
total /= fileIterator.m_filename;
|
||||
if (ConvertToAlias(total, total))
|
||||
{
|
||||
total.resize_no_construct(*resolvedAliasLength);
|
||||
if (!callback(total.c_str()))
|
||||
{
|
||||
break;
|
||||
@@ -510,8 +497,13 @@ namespace AZ::IO
|
||||
const auto fileIt = m_trackedFiles.find(fileHandle);
|
||||
if (fileIt != m_trackedFiles.end())
|
||||
{
|
||||
AZ_Assert(filenameSize >= fileIt->second.length(), "Filename size %" PRIu64 " is larger than the size of the tracked file %s:%zu", fileIt->second.c_str(), fileIt->second.size());
|
||||
azstrncpy(filename, filenameSize, fileIt->second.c_str(), fileIt->second.length());
|
||||
const AZStd::string_view trackedFileView = fileIt->second.Native();
|
||||
if (filenameSize <= trackedFileView.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
size_t trackedFileViewLength = trackedFileView.copy(filename, trackedFileView.size());
|
||||
filename[trackedFileViewLength] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
#include <AzCore/std/string/osstring.h>
|
||||
|
||||
|
||||
namespace AZ::IO
|
||||
@@ -65,7 +64,7 @@ namespace AZ::IO
|
||||
void SetAlias(const char* alias, const char* path) override;
|
||||
void ClearAlias(const char* alias) override;
|
||||
AZStd::optional<AZ::u64> ConvertToAlias(char* inOutBuffer, AZ::u64 bufferLength) const override;
|
||||
bool ConvertToAlias(AZ::IO::FixedMaxPath& convertedPath, const AZ::IO::PathView& path) const;
|
||||
bool ConvertToAlias(AZ::IO::FixedMaxPath& convertedPath, const AZ::IO::PathView& path) const override;
|
||||
using FileIOBase::ConvertToAlias;
|
||||
const char* GetAlias(const char* alias) const override;
|
||||
bool ResolvePath(const char* path, char* resolvedPath, AZ::u64 resolvedPathSize) const override;
|
||||
@@ -78,7 +77,7 @@ namespace AZ::IO
|
||||
protected:
|
||||
// we keep a list of file names ever opened so that we can easily return it.
|
||||
mutable AZStd::recursive_mutex m_operationGuard;
|
||||
AZStd::unordered_map<IO::HandleType, AZ::OSString, AZStd::hash<IO::HandleType>, AZStd::equal_to<IO::HandleType>, AZ::OSStdAllocator> m_trackedFiles;
|
||||
AZStd::unordered_map<IO::HandleType, AZ::IO::Path> m_trackedFiles;
|
||||
AZStd::fixed_vector<char, ArchiveFileIoMaxBuffersize> m_copyBuffer;
|
||||
IArchive* m_archive;
|
||||
};
|
||||
|
||||
@@ -15,34 +15,6 @@
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
size_t ArchiveFileIteratorHash::operator()(const AZ::IO::ArchiveFileIterator& iter) const
|
||||
{
|
||||
return iter.GetHash();
|
||||
}
|
||||
|
||||
bool AZStdStringLessCaseInsensitive::operator()(AZStd::string_view left, AZStd::string_view right) const
|
||||
{
|
||||
// If one or both strings are 0-length, return true if the left side is smaller, false if they're equal or left is larger.
|
||||
size_t compareLength = (AZStd::min)(left.size(), right.size());
|
||||
if (compareLength == 0)
|
||||
{
|
||||
return left.size() < right.size();
|
||||
}
|
||||
|
||||
// They're both non-zero, so compare the strings up until the length of the shorter string.
|
||||
int compareResult = azstrnicmp(left.data(), right.data(), compareLength);
|
||||
|
||||
// If both strings are equal for the number of characters compared, return true if the left side is shorter, false if
|
||||
// they're equal or left is longer.
|
||||
if (compareResult == 0)
|
||||
{
|
||||
return left.size() < right.size();
|
||||
}
|
||||
|
||||
// Return true if the left side should come first alphabetically, false if the right side should.
|
||||
return compareResult < 0;
|
||||
}
|
||||
|
||||
FileDesc::FileDesc(Attribute fileAttribute, uint64_t fileSize, time_t accessTime, time_t creationTime, time_t writeTime)
|
||||
: nAttrib{ fileAttribute }
|
||||
, nSize{ fileSize }
|
||||
@@ -52,10 +24,9 @@ namespace AZ::IO
|
||||
{
|
||||
}
|
||||
|
||||
ArchiveFileIterator::ArchiveFileIterator(FindData* findData, AZStd::string_view filename, const FileDesc& fileDesc)
|
||||
// ArchiveFileIterator
|
||||
ArchiveFileIterator::ArchiveFileIterator(FindData* findData)
|
||||
: m_findData{ findData }
|
||||
, m_filename{ filename }
|
||||
, m_fileDesc{ fileDesc }
|
||||
{
|
||||
}
|
||||
|
||||
@@ -73,21 +44,36 @@ namespace AZ::IO
|
||||
return operator++();
|
||||
}
|
||||
|
||||
bool ArchiveFileIterator::operator==(const AZ::IO::ArchiveFileIterator& rhs) const
|
||||
{
|
||||
return GetHash() == rhs.GetHash();
|
||||
}
|
||||
|
||||
ArchiveFileIterator::operator bool() const
|
||||
{
|
||||
return m_findData && m_lastFetchValid;
|
||||
}
|
||||
|
||||
size_t ArchiveFileIterator::GetHash() const
|
||||
// FindData::ArchiveFile
|
||||
FindData::ArchiveFile::ArchiveFile() = default;
|
||||
FindData::ArchiveFile::ArchiveFile(AZStd::string_view filename, const FileDesc& fileDesc)
|
||||
: m_filename(filename)
|
||||
, m_fileDesc(fileDesc)
|
||||
{
|
||||
}
|
||||
size_t FindData::ArchiveFile::GetHash() const
|
||||
{
|
||||
return AZStd::hash<AZ::IO::PathView>{}(m_filename.c_str());
|
||||
}
|
||||
|
||||
bool FindData::ArchiveFile::operator==(const ArchiveFile& rhs) const
|
||||
{
|
||||
return GetHash() == rhs.GetHash();
|
||||
}
|
||||
|
||||
// FindData::ArchiveFilehash
|
||||
size_t FindData::ArchiveFileHash::operator()(const ArchiveFile& archiveFile) const
|
||||
{
|
||||
return archiveFile.GetHash();
|
||||
}
|
||||
|
||||
// FindData
|
||||
void FindData::Scan(IArchive* archive, AZStd::string_view szDir, bool bAllowUseFS, bool bScanZips)
|
||||
{
|
||||
// get the priority into local variable to avoid it changing in the course of
|
||||
@@ -119,40 +105,37 @@ namespace AZ::IO
|
||||
|
||||
void FindData::ScanFS([[maybe_unused]] IArchive* archive, AZStd::string_view szDirIn)
|
||||
{
|
||||
AZStd::string searchDirectory;
|
||||
AZStd::string pattern;
|
||||
AZ::IO::PathView directory{ szDirIn };
|
||||
AZ::IO::FixedMaxPath searchDirectory = directory.ParentPath();
|
||||
AZ::IO::FixedMaxPath pattern = directory.Filename();
|
||||
auto ScanFileSystem = [this](const char* filePath) -> bool
|
||||
{
|
||||
AZ::IO::PathString directory{ szDirIn };
|
||||
AZ::StringFunc::Path::GetFullPath(directory.c_str(), searchDirectory);
|
||||
AZ::StringFunc::Path::GetFullFileName(directory.c_str(), pattern);
|
||||
}
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->FindFiles(searchDirectory.c_str(), pattern.c_str(), [&](const char* filePath) -> bool
|
||||
{
|
||||
AZ::IO::ArchiveFileIterator fileIterator{ nullptr, AZ::IO::PathView(filePath).Filename().Native(), {} };
|
||||
ArchiveFile archiveFile{ AZ::IO::PathView(filePath).Filename().Native(), {} };
|
||||
|
||||
if (AZ::IO::FileIOBase::GetDirectInstance()->IsDirectory(filePath))
|
||||
{
|
||||
fileIterator.m_fileDesc.nAttrib = fileIterator.m_fileDesc.nAttrib | AZ::IO::FileDesc::Attribute::Subdirectory;
|
||||
m_fileSet.emplace(AZStd::move(fileIterator));
|
||||
archiveFile.m_fileDesc.nAttrib = archiveFile.m_fileDesc.nAttrib | AZ::IO::FileDesc::Attribute::Subdirectory;
|
||||
m_fileSet.emplace(AZStd::move(archiveFile));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (AZ::IO::FileIOBase::GetDirectInstance()->IsReadOnly(filePath))
|
||||
{
|
||||
fileIterator.m_fileDesc.nAttrib = fileIterator.m_fileDesc.nAttrib | AZ::IO::FileDesc::Attribute::ReadOnly;
|
||||
archiveFile.m_fileDesc.nAttrib = archiveFile.m_fileDesc.nAttrib | AZ::IO::FileDesc::Attribute::ReadOnly;
|
||||
}
|
||||
AZ::u64 fileSize = 0;
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Size(filePath, fileSize);
|
||||
fileIterator.m_fileDesc.nSize = fileSize;
|
||||
fileIterator.m_fileDesc.tWrite = AZ::IO::FileIOBase::GetDirectInstance()->ModificationTime(filePath);
|
||||
archiveFile.m_fileDesc.nSize = fileSize;
|
||||
archiveFile.m_fileDesc.tWrite = AZ::IO::FileIOBase::GetDirectInstance()->ModificationTime(filePath);
|
||||
|
||||
// These times are not supported by our file interface
|
||||
fileIterator.m_fileDesc.tAccess = fileIterator.m_fileDesc.tWrite;
|
||||
fileIterator.m_fileDesc.tCreate = fileIterator.m_fileDesc.tWrite;
|
||||
m_fileSet.emplace(AZStd::move(fileIterator));
|
||||
archiveFile.m_fileDesc.tAccess = archiveFile.m_fileDesc.tWrite;
|
||||
archiveFile.m_fileDesc.tCreate = archiveFile.m_fileDesc.tWrite;
|
||||
m_fileSet.emplace(AZStd::move(archiveFile));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
};
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->FindFiles(searchDirectory.c_str(), pattern.c_str(), ScanFileSystem);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -180,7 +163,7 @@ namespace AZ::IO
|
||||
fileDesc.nAttrib = AZ::IO::FileDesc::Attribute::ReadOnly | AZ::IO::FileDesc::Attribute::Archive;
|
||||
fileDesc.nSize = fileEntry->desc.lSizeUncompressed;
|
||||
fileDesc.tWrite = fileEntry->GetModificationTime();
|
||||
m_fileSet.emplace(AZ::IO::ArchiveFileIterator{ this, fname, fileDesc });
|
||||
m_fileSet.emplace(fname, fileDesc);
|
||||
}
|
||||
|
||||
ZipDir::FindDir findDirectoryEntry(zipCache);
|
||||
@@ -193,7 +176,7 @@ namespace AZ::IO
|
||||
}
|
||||
AZ::IO::FileDesc fileDesc;
|
||||
fileDesc.nAttrib = AZ::IO::FileDesc::Attribute::ReadOnly | AZ::IO::FileDesc::Attribute::Archive | AZ::IO::FileDesc::Attribute::Subdirectory;
|
||||
m_fileSet.emplace(AZ::IO::ArchiveFileIterator{ this, fname, fileDesc });
|
||||
m_fileSet.emplace(fname, fileDesc);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -208,30 +191,16 @@ namespace AZ::IO
|
||||
// so there's really no way to filter out opening the pack and looking at the files inside.
|
||||
// however, the bind root is not part of the inner zip entry name either
|
||||
// and the ZipDir::FindFile actually expects just the chopped off piece.
|
||||
// we have to find whats in common between them and check that:
|
||||
// we have to find the common path segments between them and check that:
|
||||
|
||||
auto resolvedBindRoot = AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(it->m_pathBindRoot);
|
||||
if (!resolvedBindRoot)
|
||||
AZ::IO::FixedMaxPath bindRoot;
|
||||
if (!AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(bindRoot, it->m_pathBindRoot))
|
||||
{
|
||||
AZ_Assert(false, "Unable to resolve Path for archive %s bind root %s", it->GetFullPath(), it->m_pathBindRoot.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPath bindRoot{ *resolvedBindRoot };
|
||||
auto [bindRootIter, sourcePathIter] = AZStd::mismatch(AZStd::begin(bindRoot), AZStd::end(bindRoot),
|
||||
AZStd::begin(sourcePath), AZStd::end(sourcePath));
|
||||
|
||||
if (sourcePathIter == AZStd::begin(sourcePath))
|
||||
{
|
||||
// The path has no characters in common , early out the search as filepath is not part of the iterated zip
|
||||
continue;
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPath sourcePathRemainder;
|
||||
for (; sourcePathIter != AZStd::end(sourcePath); ++sourcePathIter)
|
||||
{
|
||||
sourcePathRemainder /= *sourcePathIter;
|
||||
}
|
||||
// Example:
|
||||
// "@assets@\\levels\\*" <--- szDir
|
||||
// "@assets@\\" <--- mount point
|
||||
@@ -256,18 +225,26 @@ namespace AZ::IO
|
||||
// then it means that the pack's mount point itself might be a return value, not the files inside the pack
|
||||
// in that case, we compare the mount point remainder itself with the search filter
|
||||
|
||||
auto [bindRootIter, sourcePathIter] = AZStd::mismatch(bindRoot.begin(), bindRoot.end(),
|
||||
sourcePath.begin(), sourcePath.end());
|
||||
if (bindRootIter != bindRoot.end())
|
||||
{
|
||||
AZ::IO::FixedMaxPath sourcePathRemainder;
|
||||
for (; sourcePathIter != sourcePath.end(); ++sourcePathIter)
|
||||
{
|
||||
sourcePathRemainder /= *sourcePathIter;
|
||||
}
|
||||
|
||||
// Retrieve next path component of the mount point remainder
|
||||
if (!bindRootIter->empty() && AZStd::wildcard_match(sourcePathRemainder.Native(), bindRootIter->Native()))
|
||||
if (!bindRootIter->empty() && bindRootIter->Match(sourcePathRemainder.Native()))
|
||||
{
|
||||
AZ::IO::FileDesc fileDesc{ AZ::IO::FileDesc::Attribute::ReadOnly | AZ::IO::FileDesc::Attribute::Archive | AZ::IO::FileDesc::Attribute::Subdirectory };
|
||||
m_fileSet.emplace(AZ::IO::ArchiveFileIterator{ this, bindRootIter->Native(), fileDesc });
|
||||
m_fileSet.emplace(AZStd::move(bindRootIter->Native()), fileDesc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
AZ::IO::FixedMaxPath sourcePathRemainder = sourcePath.LexicallyRelative(bindRoot);
|
||||
// if we get here, it means that the search pattern's root and the mount point for this pack are identical
|
||||
// which means we may search inside the pack.
|
||||
ScanInZip(it->pZip.get(), sourcePathRemainder.Native());
|
||||
@@ -280,17 +257,17 @@ namespace AZ::IO
|
||||
{
|
||||
if (m_fileSet.empty())
|
||||
{
|
||||
AZ::IO::ArchiveFileIterator emptyFileIterator;
|
||||
emptyFileIterator.m_lastFetchValid = false;
|
||||
emptyFileIterator.m_findData = this;
|
||||
return emptyFileIterator;
|
||||
return {};
|
||||
}
|
||||
|
||||
// Remove Fetched item from the FindData map so that the iteration continues
|
||||
AZ::IO::ArchiveFileIterator fileIterator{ *m_fileSet.begin() };
|
||||
AZ::IO::ArchiveFileIterator fileIterator;
|
||||
auto archiveFileIt = m_fileSet.begin();
|
||||
fileIterator.m_filename = archiveFileIt->m_filename;
|
||||
fileIterator.m_fileDesc = archiveFileIt->m_fileDesc;
|
||||
fileIterator.m_lastFetchValid = true;
|
||||
fileIterator.m_findData = this;
|
||||
m_fileSet.erase(m_fileSet.begin());
|
||||
m_fileSet.erase(archiveFileIt);
|
||||
return fileIterator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,56 +36,72 @@ namespace AZ::IO
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::IO::FileDesc::Attribute);
|
||||
|
||||
inline constexpr size_t ArchiveFilenameMaxLength = 256;
|
||||
using ArchiveFileString = AZStd::fixed_string<ArchiveFilenameMaxLength>;
|
||||
|
||||
class FindData;
|
||||
//! This is not really an iterator, but a handle
|
||||
//! that extends ownership of any found filenames from an archive file or the file system
|
||||
struct ArchiveFileIterator
|
||||
{
|
||||
ArchiveFileIterator() = default;
|
||||
ArchiveFileIterator(FindData* findData, AZStd::string_view filename, const FileDesc& fileDesc);
|
||||
explicit ArchiveFileIterator(FindData* findData);
|
||||
|
||||
ArchiveFileIterator operator++();
|
||||
ArchiveFileIterator operator++(int);
|
||||
|
||||
bool operator==(const AZ::IO::ArchiveFileIterator& rhs) const;
|
||||
|
||||
explicit operator bool() const;
|
||||
|
||||
size_t GetHash() const;
|
||||
|
||||
inline static constexpr size_t FilenameMaxLength = 256;
|
||||
AZStd::fixed_string<FilenameMaxLength> m_filename;
|
||||
ArchiveFileString m_filename;
|
||||
FileDesc m_fileDesc;
|
||||
AZStd::intrusive_ptr<FindData> m_findData{};
|
||||
|
||||
private:
|
||||
friend class FindData;
|
||||
friend class Archive;
|
||||
AZStd::intrusive_ptr<FindData> m_findData;
|
||||
bool m_lastFetchValid{};
|
||||
};
|
||||
|
||||
struct ArchiveFileIteratorHash
|
||||
{
|
||||
size_t operator()(const AZ::IO::ArchiveFileIterator& iter) const;
|
||||
};
|
||||
|
||||
struct AZStdStringLessCaseInsensitive
|
||||
{
|
||||
bool operator()(AZStd::string_view left, AZStd::string_view right) const;
|
||||
|
||||
using is_transparent = void;
|
||||
};
|
||||
class FindData
|
||||
: public AZStd::intrusive_base
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(FindData, AZ::SystemAllocator, 0);
|
||||
FindData() = default;
|
||||
AZ::IO::ArchiveFileIterator Fetch();
|
||||
ArchiveFileIterator Fetch();
|
||||
void Scan(IArchive* archive, AZStd::string_view path, bool bAllowUseFS = false, bool bScanZips = true);
|
||||
|
||||
protected:
|
||||
void ScanFS(IArchive* archive, AZStd::string_view path);
|
||||
// Populates the FileSet with files within the that match the path pattern that is
|
||||
// if it refers to a file within a bound archive root or returns the archive root
|
||||
// path if the path pattern matches it.
|
||||
void ScanZips(IArchive* archive, AZStd::string_view path);
|
||||
|
||||
using FileSet = AZStd::unordered_set<ArchiveFileIterator, ArchiveFileIteratorHash>;
|
||||
class ArchiveFile
|
||||
{
|
||||
public:
|
||||
friend class FindData;
|
||||
|
||||
ArchiveFile();
|
||||
ArchiveFile(AZStd::string_view filename, const FileDesc& fileDesc);
|
||||
|
||||
size_t GetHash() const;
|
||||
bool operator==(const ArchiveFile& rhs) const;
|
||||
|
||||
private:
|
||||
ArchiveFileString m_filename;
|
||||
FileDesc m_fileDesc;
|
||||
};
|
||||
|
||||
struct ArchiveFileHash
|
||||
{
|
||||
size_t operator()(const ArchiveFile& archiveFile) const;
|
||||
};
|
||||
|
||||
using FileSet = AZStd::unordered_set<ArchiveFile, ArchiveFileHash>;
|
||||
FileSet m_fileSet;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -12,12 +12,10 @@
|
||||
#include <AzCore/EBus/Event.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzCore/std/smart_ptr/intrusive_base.h>
|
||||
#include <AzCore/std/smart_ptr/intrusive_ptr.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
#include <AzFramework/Archive/ArchiveFindData.h>
|
||||
|
||||
@@ -106,66 +104,6 @@ namespace AZ::IO
|
||||
{
|
||||
AZ_RTTI(IArchive, "{764A2260-FF8A-4C86-B958-EBB0B69D9DFA}");
|
||||
using FileTime = uint64_t;
|
||||
// Flags used in file path resolution rules
|
||||
enum EPathResolutionRules
|
||||
{
|
||||
// If used, the source path will be treated as the destination path
|
||||
// and no transformations will be done. Pass this flag when the path is to be the actual
|
||||
// path on the disk/in the packs and doesn't need adjustment (or after it has come through adjustments already)
|
||||
// if this is set, AdjustFileName will not map the input path into the folder (Ex: Shaders will not be converted to Game\Shaders)
|
||||
FLAGS_PATH_REAL = 1 << 16,
|
||||
|
||||
// AdjustFileName will always copy the file path to the destination path:
|
||||
// regardless of the returned value, szDestpath can be used
|
||||
FLAGS_COPY_DEST_ALWAYS = 1 << 17,
|
||||
|
||||
// Adds trailing slash to the path
|
||||
FLAGS_ADD_TRAILING_SLASH = 1L << 18,
|
||||
|
||||
// if this is set, AdjustFileName will not make relative paths into full paths
|
||||
FLAGS_NO_FULL_PATH = 1 << 21,
|
||||
|
||||
// if this is set, AdjustFileName will redirect path to disc
|
||||
FLAGS_REDIRECT_TO_DISC = 1 << 22,
|
||||
|
||||
// if this is set, AdjustFileName will not adjust path for writing files
|
||||
FLAGS_FOR_WRITING = 1 << 23,
|
||||
|
||||
// if this is set, the archive would be stored in memory (gpu)
|
||||
FLAGS_PAK_IN_MEMORY = 1 << 25,
|
||||
|
||||
// Store all file names as crc32 in a flat directory structure.
|
||||
FLAGS_FILENAMES_AS_CRC32 = 1 << 26,
|
||||
|
||||
// if this is set, AdjustFileName will try to find the file under any mod paths we know about
|
||||
FLAGS_CHECK_MOD_PATHS = 1 << 27,
|
||||
|
||||
// if this is set, AdjustFileName will always check the filesystem/disk and not check inside open archives
|
||||
FLAGS_NEVER_IN_PAK = 1 << 28,
|
||||
|
||||
// returns existing file name from the local data or existing cache file name
|
||||
// used by the resource compiler to pass the real file name
|
||||
FLAGS_RESOLVE_TO_CACHE = 1 << 29,
|
||||
|
||||
// if this is set, the archive would be stored in memory (cpu)
|
||||
FLAGS_PAK_IN_MEMORY_CPU = 1 << 30,
|
||||
|
||||
// if this is set, the level pak is inside another archive
|
||||
FLAGS_LEVEL_PAK_INSIDE_PAK = 1 << 31,
|
||||
};
|
||||
|
||||
// Used for widening FOpen functionality. They're ignored for the regular File System files.
|
||||
enum EFOpenFlags
|
||||
{
|
||||
// If possible, will prevent the file from being read from memory.
|
||||
FOPEN_HINT_DIRECT_OPERATION = 1,
|
||||
// Will prevent a "missing file" warnings to be created.
|
||||
FOPEN_HINT_QUIET = 1 << 1,
|
||||
// File should be on disk
|
||||
FOPEN_ONDISK = 1 << 2,
|
||||
// Open is done by the streaming thread.
|
||||
FOPEN_FORSTREAMING = 1 << 3,
|
||||
};
|
||||
|
||||
//
|
||||
enum ERecordFileOpenList
|
||||
@@ -175,8 +113,6 @@ namespace AZ::IO
|
||||
RFOM_Level, // during level loading till export2game -> resourcelist.txt, used to generate the list for level2level loading
|
||||
RFOM_NextLevel // used for level2level loading
|
||||
};
|
||||
// the size of the buffer that receives the full path to the file
|
||||
inline static constexpr size_t MaxPath = 1024;
|
||||
|
||||
//file location enum used in isFileExist to control where the archive system looks for the file.
|
||||
enum EFileSearchLocation
|
||||
@@ -205,63 +141,31 @@ namespace AZ::IO
|
||||
|
||||
virtual ~IArchive() = default;
|
||||
|
||||
/**
|
||||
* Deprecated: Use the AZ::IO::FileIOBase::ResolvePath function below that doesn't accept the nFlags or skipMods parameters
|
||||
* given the source relative path, constructs the full path to the file according to the flags
|
||||
* returns the pointer to the constructed path (can be either szSourcePath, or szDestPath, or NULL in case of error
|
||||
*/
|
||||
//
|
||||
virtual const char* AdjustFileName(AZStd::string_view src, char* dst, size_t dstSize, uint32_t nFlags, bool skipMods = false) = 0;
|
||||
|
||||
virtual bool Init(AZStd::string_view szBasePath) = 0;
|
||||
virtual void Release() = 0;
|
||||
|
||||
// Summary:
|
||||
// Returns true if given archivepath is installed to HDD
|
||||
// If no file path is given it will return true if whole application is installed to HDD
|
||||
virtual bool IsInstalledToHDD(AZStd::string_view acFilePath = 0) const = 0;
|
||||
|
||||
// after this call, the archive file will be searched for files when they aren't on the OS file system
|
||||
// Arguments:
|
||||
// pName - must not be 0
|
||||
virtual bool OpenPack(AZStd::string_view pName, uint32_t nFlags = FLAGS_PATH_REAL, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = {},
|
||||
virtual bool OpenPack(AZStd::string_view pName, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = {},
|
||||
AZ::IO::FixedMaxPathString* pFullPath = nullptr, bool addLevels = true) = 0;
|
||||
// after this call, the archive file will be searched for files when they aren't on the OS file system
|
||||
virtual bool OpenPack(AZStd::string_view pBindingRoot, AZStd::string_view pName, uint32_t nFlags = FLAGS_PATH_REAL,
|
||||
virtual bool OpenPack(AZStd::string_view pBindingRoot, AZStd::string_view pName,
|
||||
AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = {}, AZ::IO::FixedMaxPathString* pFullPath = nullptr, bool addLevels = true) = 0;
|
||||
// after this call, the file will be unlocked and closed, and its contents won't be used to search for files
|
||||
virtual bool ClosePack(AZStd::string_view pName, uint32_t nFlags = FLAGS_PATH_REAL) = 0;
|
||||
virtual bool ClosePack(AZStd::string_view pName) = 0;
|
||||
// opens pack files by the path and wildcard
|
||||
virtual bool OpenPacks(AZStd::string_view pWildcard, uint32_t nFlags = FLAGS_PATH_REAL, AZStd::vector<AZ::IO::FixedMaxPathString>* pFullPaths = nullptr) = 0;
|
||||
virtual bool OpenPacks(AZStd::string_view pWildcard, AZStd::vector<AZ::IO::FixedMaxPathString>* pFullPaths = nullptr) = 0;
|
||||
// opens pack files by the path and wildcard
|
||||
virtual bool OpenPacks(AZStd::string_view pBindingRoot, AZStd::string_view pWildcard, uint32_t nFlags = FLAGS_PATH_REAL,
|
||||
virtual bool OpenPacks(AZStd::string_view pBindingRoot, AZStd::string_view pWildcard,
|
||||
AZStd::vector<AZ::IO::FixedMaxPathString>* pFullPaths = nullptr) = 0;
|
||||
// closes pack files by the path and wildcard
|
||||
virtual bool ClosePacks(AZStd::string_view pWildcard, uint32_t nFlags = FLAGS_PATH_REAL) = 0;
|
||||
virtual bool ClosePacks(AZStd::string_view pWildcard) = 0;
|
||||
//returns if a archive exists matching the wildcard
|
||||
virtual bool FindPacks(AZStd::string_view pWildcardIn) = 0;
|
||||
|
||||
// Set access status of a archive files with a wildcard
|
||||
virtual bool SetPacksAccessible(bool bAccessible, AZStd::string_view pWildcard, uint32_t nFlags = FLAGS_PATH_REAL) = 0;
|
||||
virtual bool SetPacksAccessible(bool bAccessible, AZStd::string_view pWildcard) = 0;
|
||||
|
||||
// Set access status of a pack file
|
||||
virtual bool SetPackAccessible(bool bAccessible, AZStd::string_view pName, uint32_t nFlags = FLAGS_PATH_REAL) = 0;
|
||||
|
||||
// Load or unload archive file completely to memory.
|
||||
virtual bool LoadPakToMemory(AZStd::string_view pName, EInMemoryArchiveLocation eLoadToMemory, AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pMemoryBlock = nullptr) = 0;
|
||||
virtual void LoadPaksToMemory(int nMaxArchiveSize, bool bLoadToMemory) = 0;
|
||||
|
||||
// Processes an alias command line containing multiple aliases.
|
||||
virtual void ParseAliases(AZStd::string_view szCommandLine) = 0;
|
||||
// adds or removes an alias from the list
|
||||
virtual void SetAlias(AZStd::string_view szName, AZStd::string_view szAlias, bool bAdd) = 0;
|
||||
// gets an alias from the list, if any exist.
|
||||
// if bReturnSame==true, it will return the input name if an alias doesn't exist. Otherwise returns NULL
|
||||
virtual const char* GetAlias(AZStd::string_view szName, bool bReturnSame = true) = 0;
|
||||
|
||||
// lock all the operations
|
||||
virtual void Lock() = 0;
|
||||
virtual void Unlock() = 0;
|
||||
virtual bool SetPackAccessible(bool bAccessible, AZStd::string_view pName) = 0;
|
||||
|
||||
// Set and Get the localization folder name (Languages, Localization, ...)
|
||||
virtual void SetLocalizationFolder(AZStd::string_view sLocalizationFolder) = 0;
|
||||
@@ -273,28 +177,19 @@ namespace AZ::IO
|
||||
// ex: AZ::IO::HandleType fileHandle = FOpen( "test.txt","rbx" );
|
||||
// mode x is a direct access mode, when used file reads will go directly into the low level file system without any internal data caching.
|
||||
// Text mode is not supported for files in Archives.
|
||||
// for nFlags @see IArchive::EFOpenFlags
|
||||
virtual AZ::IO::HandleType FOpen(AZStd::string_view pName, const char* mode, uint32_t nFlags = 0) = 0;
|
||||
|
||||
// Read raw data from file, no endian conversion.
|
||||
virtual size_t FReadRaw(void* data, size_t length, size_t elems, AZ::IO::HandleType fileHandle) = 0;
|
||||
|
||||
// Read all file contents into the provided memory, nSizeOfFile must be the same as returned by GetFileSize(handle)
|
||||
// Current seek pointer is ignored and reseted to 0.
|
||||
// no endian conversion.
|
||||
virtual size_t FReadRawAll(void* data, size_t nFileSize, AZ::IO::HandleType fileHandle) = 0;
|
||||
virtual AZ::IO::HandleType FOpen(AZStd::string_view pName, const char* mode) = 0;
|
||||
|
||||
// Get pointer to the internally cached, loaded data of the file.
|
||||
// WARNING! The returned pointer is only valid while the fileHandle has not been closed.
|
||||
virtual void* FGetCachedFileData(AZ::IO::HandleType fileHandle, size_t& nFileSize) = 0;
|
||||
|
||||
// Write file data, cannot be used for writing into the Archive.
|
||||
// Use INestedArchive interface for writing into the archivefiles.
|
||||
virtual size_t FWrite(const void* data, size_t length, size_t elems, AZ::IO::HandleType fileHandle) = 0;
|
||||
// Read raw data from file, no endian conversion.
|
||||
virtual size_t FRead(void* data, size_t bytesToRead, AZ::IO::HandleType fileHandle) = 0;
|
||||
|
||||
// Write file data, cannot be used for writing into the Archive.
|
||||
// Use INestedArchive interface for writing into the archive files.
|
||||
virtual size_t FWrite(const void* data, size_t bytesToWrite, AZ::IO::HandleType fileHandle) = 0;
|
||||
|
||||
virtual int FPrintf(AZ::IO::HandleType fileHandle, const char* format, ...) = 0;
|
||||
virtual char* FGets(char*, int, AZ::IO::HandleType) = 0;
|
||||
virtual int Getc(AZ::IO::HandleType) = 0;
|
||||
virtual size_t FGetSize(AZ::IO::HandleType fileHandle) = 0;
|
||||
virtual size_t FGetSize(AZStd::string_view pName, bool bAllowUseFileSystem = false) = 0;
|
||||
virtual bool IsInPak(AZ::IO::HandleType fileHandle) = 0;
|
||||
@@ -318,7 +213,6 @@ namespace AZ::IO
|
||||
virtual AZStd::intrusive_ptr<AZ::IO::MemoryBlock> PoolAllocMemoryBlock(size_t nSize, const char* sUsage, size_t nAlign = 1) = 0;
|
||||
|
||||
// Arguments:
|
||||
// nFlags is a combination of EPathResolutionRules flags.
|
||||
virtual ArchiveFileIterator FindFirst(AZStd::string_view pDir, EFileSearchType searchType = eFileSearchType_AllowInZipsOnly) = 0;
|
||||
virtual ArchiveFileIterator FindNext(AZ::IO::ArchiveFileIterator handle) = 0;
|
||||
virtual bool FindClose(AZ::IO::ArchiveFileIterator handle) = 0;
|
||||
@@ -334,9 +228,6 @@ namespace AZ::IO
|
||||
|
||||
virtual IArchive::SignedFileSize GetFileSizeOnDisk(AZStd::string_view filename) = 0;
|
||||
|
||||
// creates a directory
|
||||
virtual bool MakeDir(AZStd::string_view szPath) = 0;
|
||||
|
||||
// open the physical archive file - creates if it doesn't exist
|
||||
// returns NULL if it's invalid or can't open the file
|
||||
// nFlags is a combination of flags from EArchiveFlags enum.
|
||||
@@ -344,8 +235,8 @@ namespace AZ::IO
|
||||
AZStd::intrusive_ptr<AZ::IO::MemoryBlock> pData = nullptr) = 0;
|
||||
|
||||
// returns the path to the archive in which the file was opened
|
||||
// returns NULL if the file is a physical file, and "" if the path to archive is unknown (shouldn't ever happen)
|
||||
virtual const char* GetFileArchivePath(AZ::IO::HandleType fileHandle) = 0;
|
||||
// returns empty path view if the file is a physical file
|
||||
virtual AZ::IO::PathView GetFileArchivePath(AZ::IO::HandleType fileHandle) = 0;
|
||||
|
||||
// compresses the raw data into raw data. The buffer for compressed data itself with the heap passed. Uses method 8 (deflate)
|
||||
// returns one of the Z_* errors (Z_OK upon success)
|
||||
@@ -378,25 +269,7 @@ namespace AZ::IO
|
||||
// get the current mode, can be set by RecordFileOpen()
|
||||
virtual IArchive::ERecordFileOpenList GetRecordFileOpenList() = 0;
|
||||
|
||||
// computes CRC (zip compatible) for a file
|
||||
// useful if a huge uncompressed file is generation in non continuous way
|
||||
// good for big files - low memory overhead (1MB)
|
||||
// Arguments:
|
||||
// szPath - must not be 0
|
||||
// Returns:
|
||||
// error code
|
||||
virtual uint32_t ComputeCRC(AZStd::string_view szPath, uint32_t nFileOpenFlags = 0) = 0;
|
||||
|
||||
// computes MD5 checksum for a file
|
||||
// good for big files - low memory overhead (1MB)
|
||||
// Arguments:
|
||||
// szPath - must not be 0
|
||||
// md5 - destination array of uint8_t [16]
|
||||
// Returns:
|
||||
// true if success, false on failure
|
||||
virtual bool ComputeMD5(AZStd::string_view szPath, uint8_t* md5, uint32_t nFileOpenFlags = 0, bool useDirectFileAccess = false) = 0;
|
||||
|
||||
// useful for gathering file access statistics, assert if it was inserted already but then it does not become insersted
|
||||
// useful for gathering file access statistics, assert if it was inserted already but then it does not become inserted
|
||||
// Arguments:
|
||||
// pSink - must not be 0
|
||||
virtual void RegisterFileAccessSink(IArchiveFileAccessSink* pSink) = 0;
|
||||
@@ -408,8 +281,6 @@ namespace AZ::IO
|
||||
// When enabled, files accessed at runtime will be tracked
|
||||
virtual void DisableRuntimeFileAccess(bool status) = 0;
|
||||
virtual bool DisableRuntimeFileAccess(bool status, AZStd::thread_id threadId) = 0;
|
||||
virtual bool CheckFileAccessDisabled(AZStd::string_view name, const char* mode) = 0;
|
||||
virtual void SetRenderThreadId(AZStd::thread_id renderThreadId) = 0;
|
||||
|
||||
// gets the current pak priority
|
||||
virtual ArchiveLocationPriority GetPakPriority() const = 0;
|
||||
@@ -431,21 +302,6 @@ namespace AZ::IO
|
||||
using LevelPackCloseEvent = AZ::Event<AZStd::string_view>;
|
||||
virtual auto GetLevelPackCloseEvent()->LevelPackCloseEvent* = 0;
|
||||
|
||||
// Type-safe endian conversion read.
|
||||
template<class T>
|
||||
size_t FRead(T* data, size_t elems, AZ::IO::HandleType fileHandle, bool bSwapEndian = false)
|
||||
{
|
||||
size_t count = FReadRaw(data, sizeof(T), elems, fileHandle);
|
||||
SwapEndian(data, count, bSwapEndian);
|
||||
return count;
|
||||
}
|
||||
// Type-independent Write.
|
||||
template<class T>
|
||||
void FWrite(T* data, size_t elems, AZ::IO::HandleType fileHandle)
|
||||
{
|
||||
FWrite((void*)data, sizeof(T), elems, fileHandle);
|
||||
}
|
||||
|
||||
inline static constexpr IArchive::SignedFileSize FILE_NOT_PRESENT = -1;
|
||||
};
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/IO/Path/Path_fwd.h>
|
||||
#include <AzCore/Math/Crc.h>
|
||||
#include <AzCore/std/smart_ptr/intrusive_base.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
#include <AzFramework/Archive/Codec.h>
|
||||
|
||||
namespace AZ::IO
|
||||
@@ -71,28 +71,10 @@ namespace AZ::IO
|
||||
// multiple times
|
||||
FLAGS_DONT_COMPACT = 1 << 5,
|
||||
|
||||
// flag is set when complete pak has been loaded into memory
|
||||
FLAGS_IN_MEMORY = 1 << 6,
|
||||
FLAGS_IN_MEMORY_CPU = 1 << 7,
|
||||
FLAGS_IN_MEMORY_MASK = FLAGS_IN_MEMORY | FLAGS_IN_MEMORY_CPU,
|
||||
|
||||
// Store all file names as crc32 in a flat directory structure.
|
||||
FLAGS_FILENAMES_AS_CRC32 = 1 << 8,
|
||||
|
||||
// flag is set when pak is stored on HDD
|
||||
FLAGS_ON_HDD = 1 << 9,
|
||||
|
||||
//Override pak - paks opened with this flag go at the end of the list and contents will be found before other paks
|
||||
//Used for patching
|
||||
FLAGS_OVERRIDE_PAK = 1 << 10,
|
||||
|
||||
// Disable a pak file without unloading it, this flag is used in combination with patches and multiplayer
|
||||
// to ensure that specific paks stay in the position(to keep the same priority) but beeing disabled
|
||||
// to ensure that specific paks stay in the position(to keep the same priority) but being disabled
|
||||
// when running multiplayer
|
||||
FLAGS_DISABLE_PAK = 1 << 11,
|
||||
|
||||
// flag is set when pak is inside another pak
|
||||
FLAGS_INSIDE_PAK = 1 << 12,
|
||||
};
|
||||
|
||||
using Handle = void*;
|
||||
@@ -122,7 +104,7 @@ namespace AZ::IO
|
||||
virtual int StartContinuousFileUpdate(AZStd::string_view szRelativePath, uint64_t nSize) = 0;
|
||||
|
||||
// Summary:
|
||||
// Adds a new file to the zip or update an existing's segment if it is not compressed - just stored
|
||||
// Adds a new file to the zip or update an existing segment if it is not compressed - just stored
|
||||
// adds a directory (creates several nested directories if needed)
|
||||
// ( name might be misleading as if nOverwriteSeekPos is used the update is not continuous )
|
||||
// Arguments:
|
||||
@@ -164,7 +146,7 @@ namespace AZ::IO
|
||||
|
||||
// Summary:
|
||||
// Get the full path to the archive file.
|
||||
virtual const char* GetFullPath() const = 0;
|
||||
virtual AZ::IO::PathView GetFullPath() const = 0;
|
||||
|
||||
// Summary:
|
||||
// Get the flags of this object.
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace AZ::IO
|
||||
return m_pCache->ReadFile(reinterpret_cast<ZipDir::FileEntry*>(fileHandle), nullptr, pBuffer);
|
||||
}
|
||||
|
||||
const char* NestedArchive::GetFullPath() const
|
||||
AZ::IO::PathView NestedArchive::GetFullPath() const
|
||||
{
|
||||
return m_pCache->GetFilePath();
|
||||
}
|
||||
@@ -193,19 +193,9 @@ namespace AZ::IO
|
||||
if (nFlagsToSet & FLAGS_RELATIVE_PATHS_ONLY)
|
||||
{
|
||||
m_nFlags |= FLAGS_RELATIVE_PATHS_ONLY;
|
||||
}
|
||||
|
||||
if (nFlagsToSet & FLAGS_ON_HDD)
|
||||
{
|
||||
m_nFlags |= FLAGS_ON_HDD;
|
||||
}
|
||||
|
||||
if (nFlagsToSet & FLAGS_RELATIVE_PATHS_ONLY ||
|
||||
nFlagsToSet & FLAGS_ON_HDD)
|
||||
{
|
||||
// we don't support changing of any other flags
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -252,20 +242,12 @@ namespace AZ::IO
|
||||
return AZ::IO::FixedMaxPathString{ szRelativePath };
|
||||
}
|
||||
|
||||
if ((szRelativePath.size() > 1 && szRelativePath[1] == ':') || (m_nFlags & FLAGS_ABSOLUTE_PATHS))
|
||||
if ((m_nFlags & FLAGS_ABSOLUTE_PATHS) == FLAGS_ABSOLUTE_PATHS)
|
||||
{
|
||||
// make the normalized full path and try to match it against the binding root of this object
|
||||
auto resolvedPath = AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(szRelativePath);
|
||||
|
||||
// Make sure the resolve path is longer than the bind root and that it starts with the bind root
|
||||
if (!resolvedPath || resolvedPath->Native().size() <= m_strBindRoot.size() || azstrnicmp(resolvedPath->c_str(), m_strBindRoot.c_str(), m_strBindRoot.size()) != 0)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// Remove the bind root prefix from the resolved path
|
||||
resolvedPath->Native().erase(0, m_strBindRoot.size() + 1);
|
||||
return resolvedPath->Native();
|
||||
AZ::IO::FixedMaxPath resolvedPath;
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(resolvedPath, szRelativePath);
|
||||
return resolvedPath.LexicallyProximate(m_strBindRoot).Native();
|
||||
}
|
||||
|
||||
return AZ::IO::FixedMaxPathString{ szRelativePath };
|
||||
|
||||
@@ -19,15 +19,15 @@ namespace AZ::IO
|
||||
{
|
||||
bool operator()(const INestedArchive* left, const INestedArchive* right) const
|
||||
{
|
||||
return azstricmp(left->GetFullPath(), right->GetFullPath()) < 0;
|
||||
return left->GetFullPath() < right->GetFullPath();
|
||||
}
|
||||
bool operator()(AZStd::string_view left, const INestedArchive* right) const
|
||||
{
|
||||
return azstrnicmp(left.data(), right->GetFullPath(), left.size()) < 0;
|
||||
return AZ::IO::PathView(left) < right->GetFullPath();
|
||||
}
|
||||
bool operator()(const INestedArchive* left, AZStd::string_view right) const
|
||||
{
|
||||
return azstrnicmp(left->GetFullPath(), right.data(), right.size()) < 0;
|
||||
return left->GetFullPath() < AZ::IO::PathView(right);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace AZ::IO
|
||||
NestedArchive(IArchive* pArchive, AZStd::string_view strBindRoot, ZipDir::CachePtr pCache, uint32_t nFlags = 0);
|
||||
~NestedArchive() override;
|
||||
|
||||
auto GetRootFolderHandle() -> Handle;
|
||||
auto GetRootFolderHandle() -> Handle override;
|
||||
|
||||
// Adds a new file to the zip or update an existing one
|
||||
// adds a directory (creates several nested directories if needed)
|
||||
@@ -66,26 +66,26 @@ namespace AZ::IO
|
||||
int RemoveDir(AZStd::string_view szRelativePath) override;
|
||||
|
||||
// deletes all files from the archive
|
||||
int RemoveAll();
|
||||
int RemoveAll() override;
|
||||
|
||||
// finds the file; you don't have to close the returned handle
|
||||
Handle FindFile(AZStd::string_view szRelativePath);
|
||||
Handle FindFile(AZStd::string_view szRelativePath) override;
|
||||
|
||||
// returns the size of the file (unpacked) by the handle
|
||||
uint64_t GetFileSize(Handle fileHandle);
|
||||
uint64_t GetFileSize(Handle fileHandle) override;
|
||||
|
||||
// reads the file into the preallocated buffer (must be at least the size of GetFileSize())
|
||||
int ReadFile(Handle fileHandle, void* pBuffer);
|
||||
int ReadFile(Handle fileHandle, void* pBuffer) override;
|
||||
|
||||
// returns the full path to the archive file
|
||||
const char* GetFullPath() const;
|
||||
AZ::IO::PathView GetFullPath() const override;
|
||||
ZipDir::Cache* GetCache();
|
||||
|
||||
uint32_t GetFlags() const;
|
||||
bool SetFlags(uint32_t nFlagsToSet);
|
||||
bool ResetFlags(uint32_t nFlagsToReset);
|
||||
uint32_t GetFlags() const override;
|
||||
bool SetFlags(uint32_t nFlagsToSet) override;
|
||||
bool ResetFlags(uint32_t nFlagsToReset) override;
|
||||
|
||||
bool SetPackAccessible(bool bAccessible);
|
||||
bool SetPackAccessible(bool bAccessible) override;
|
||||
|
||||
protected:
|
||||
// returns the pointer to the relative file path to be passed
|
||||
@@ -95,7 +95,7 @@ namespace AZ::IO
|
||||
|
||||
ZipDir::CachePtr m_pCache;
|
||||
// the binding root may be empty string - in this case, the absolute path binding won't work
|
||||
AZStd::string m_strBindRoot;
|
||||
AZ::IO::Path m_strBindRoot;
|
||||
IArchive* m_archive{};
|
||||
uint32_t m_nFlags{};
|
||||
};
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#include <AzCore/Console/Console.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
|
||||
#include <AzFramework/Archive/ZipFileFormat.h>
|
||||
@@ -104,24 +103,21 @@ namespace AZ::IO::ZipDir
|
||||
: m_pCache(pCache)
|
||||
, m_bCommitted(false)
|
||||
{
|
||||
AZ::IO::PathString normalizedPath{ szRelativePath };
|
||||
AZ::StringFunc::Path::Normalize(normalizedPath);
|
||||
AZStd::to_lower(AZStd::begin(normalizedPath), AZStd::end(normalizedPath));
|
||||
// Update the cache string pool with the relative path to the file
|
||||
auto pathIt = m_pCache->m_relativePathPool.emplace(normalizedPath);
|
||||
auto pathIt = m_pCache->m_relativePathPool.emplace(AZ::IO::PathView(szRelativePath).LexicallyNormal());
|
||||
m_szRelativePath = *pathIt.first;
|
||||
// this is the name of the directory - create it or find it
|
||||
m_pFileEntry = m_pCache->GetRoot()->Add(m_szRelativePath);
|
||||
m_pFileEntry = m_pCache->GetRoot()->Add(m_szRelativePath.Native());
|
||||
if (m_pFileEntry && az_archive_zip_directory_cache_verbosity)
|
||||
{
|
||||
AZ_TracePrintf("Archive", R"(File "%s" has been added to archive at root "%s")", normalizedPath.c_str(), pCache->GetFilePath());
|
||||
AZ_TracePrintf("Archive", R"(File "%s" has been added to archive at root "%s")", pathIt.first->c_str(), pCache->GetFilePath());
|
||||
}
|
||||
}
|
||||
~FileEntryTransactionAdd()
|
||||
{
|
||||
if (m_pFileEntry && !m_bCommitted)
|
||||
{
|
||||
m_pCache->RemoveFile(m_szRelativePath);
|
||||
m_pCache->RemoveFile(m_szRelativePath.Native());
|
||||
m_pCache->m_relativePathPool.erase(m_szRelativePath);
|
||||
}
|
||||
}
|
||||
@@ -131,11 +127,11 @@ namespace AZ::IO::ZipDir
|
||||
}
|
||||
AZStd::string_view GetRelativePath() const
|
||||
{
|
||||
return m_szRelativePath;
|
||||
return m_szRelativePath.Native();
|
||||
}
|
||||
private:
|
||||
Cache* m_pCache;
|
||||
AZStd::string_view m_szRelativePath;
|
||||
AZ::IO::PathView m_szRelativePath;
|
||||
FileEntry* m_pFileEntry;
|
||||
bool m_bCommitted;
|
||||
};
|
||||
@@ -587,34 +583,27 @@ namespace AZ::IO::ZipDir
|
||||
// deletes the file from the archive
|
||||
ErrorEnum Cache::RemoveFile(AZStd::string_view szRelativePathSrc)
|
||||
{
|
||||
// Normalize and lower case the relative path
|
||||
AZ::IO::PathString szRelativePath{ szRelativePathSrc };
|
||||
AZ::StringFunc::Path::Normalize(szRelativePath);
|
||||
AZStd::to_lower(AZStd::begin(szRelativePath), AZStd::end(szRelativePath));
|
||||
AZStd::string_view normalizedRelativePath = szRelativePath;
|
||||
|
||||
// find the last slash in the path
|
||||
size_t slashOffset = normalizedRelativePath.find_last_of(AZ_CORRECT_AND_WRONG_FILESYSTEM_SEPARATOR);
|
||||
AZ::IO::PathView szRelativePath{ szRelativePathSrc };
|
||||
|
||||
AZStd::string_view fileName; // the name of the file to delete
|
||||
|
||||
FileEntryTree* pDir; // the dir from which the subdir will be deleted
|
||||
|
||||
if (slashOffset != AZStd::string_view::npos)
|
||||
if (szRelativePath.HasParentPath())
|
||||
{
|
||||
FindDir fd(GetRoot());
|
||||
// the directory to remove
|
||||
pDir = fd.FindExact(normalizedRelativePath.substr(0, slashOffset));
|
||||
pDir = fd.FindExact(szRelativePath.ParentPath());
|
||||
if (!pDir)
|
||||
{
|
||||
return ZD_ERROR_DIR_NOT_FOUND;// there is no such directory
|
||||
}
|
||||
fileName = normalizedRelativePath.substr(slashOffset + 1);
|
||||
fileName = szRelativePath.Filename().Native();
|
||||
}
|
||||
else
|
||||
{
|
||||
pDir = GetRoot();
|
||||
fileName = normalizedRelativePath;
|
||||
fileName = szRelativePath.Native();
|
||||
}
|
||||
|
||||
ErrorEnum e = pDir->RemoveFile(fileName);
|
||||
@@ -625,7 +614,7 @@ namespace AZ::IO::ZipDir
|
||||
if (az_archive_zip_directory_cache_verbosity)
|
||||
{
|
||||
AZ_TracePrintf("Archive", R"(File "%.*s" has been remove from archive at root "%s")",
|
||||
aznumeric_cast<int>(fileName.size()), fileName.data(), GetFilePath());
|
||||
AZ_STRING_ARG(szRelativePath.Native()), GetFilePath());
|
||||
}
|
||||
}
|
||||
return e;
|
||||
@@ -635,45 +624,38 @@ namespace AZ::IO::ZipDir
|
||||
// deletes the directory, with all its descendants (files and subdirs)
|
||||
ErrorEnum Cache::RemoveDir(AZStd::string_view szRelativePathSrc)
|
||||
{
|
||||
// Normalize and lower case the relative path
|
||||
AZ::IO::PathString szRelativePath{ szRelativePathSrc };
|
||||
AZ::StringFunc::Path::Normalize(szRelativePath);
|
||||
AZStd::to_lower(AZStd::begin(szRelativePath), AZStd::end(szRelativePath));
|
||||
AZStd::string_view normalizedRelativePath = szRelativePath;
|
||||
|
||||
// find the last slash in the path
|
||||
size_t slashOffset = normalizedRelativePath.find_last_of(AZ_CORRECT_AND_WRONG_FILESYSTEM_SEPARATOR);
|
||||
AZ::IO::PathView szRelativePath{ szRelativePathSrc };
|
||||
|
||||
AZStd::string_view dirName; // the name of the dir to delete
|
||||
|
||||
FileEntryTree* pDir; // the dir from which the subdir will be deleted
|
||||
|
||||
if (slashOffset != AZStd::string_view::npos)
|
||||
if (szRelativePath.HasParentPath())
|
||||
{
|
||||
FindDir fd(GetRoot());
|
||||
// the directory to remove
|
||||
pDir = fd.FindExact(normalizedRelativePath.substr(0, slashOffset));
|
||||
pDir = fd.FindExact(szRelativePath.ParentPath());
|
||||
if (!pDir)
|
||||
{
|
||||
return ZD_ERROR_DIR_NOT_FOUND;// there is no such directory
|
||||
}
|
||||
dirName = normalizedRelativePath.substr(slashOffset + 1);
|
||||
dirName = szRelativePath.Filename().Native();
|
||||
}
|
||||
else
|
||||
{
|
||||
pDir = GetRoot();
|
||||
dirName = normalizedRelativePath;
|
||||
dirName = szRelativePath.Native();
|
||||
}
|
||||
|
||||
ErrorEnum e = pDir->RemoveDir(normalizedRelativePath);
|
||||
ErrorEnum e = pDir->RemoveDir(dirName);
|
||||
if (e == ZD_ERROR_SUCCESS)
|
||||
{
|
||||
m_nFlags |= FLAGS_UNCOMPACTED | FLAGS_CDR_DIRTY;
|
||||
|
||||
if (az_archive_zip_directory_cache_verbosity)
|
||||
{
|
||||
AZ_TracePrintf("Archive", R"(File "%.*s" has been remove from archive at root "%s")",
|
||||
aznumeric_cast<int>(normalizedRelativePath.size()), normalizedRelativePath.data(), GetFilePath());
|
||||
AZ_TracePrintf("Archive", R"(Directory "%.*s" has been remove from archive at root "%s")",
|
||||
AZ_STRING_ARG(szRelativePath.Native()), GetFilePath());
|
||||
}
|
||||
}
|
||||
return e;
|
||||
@@ -769,9 +751,7 @@ namespace AZ::IO::ZipDir
|
||||
// finds the file by exact path
|
||||
FileEntry* Cache::FindFile(AZStd::string_view szPathSrc, [[maybe_unused]] bool bFullInfo)
|
||||
{
|
||||
AZ::IO::PathString szPath{ szPathSrc };
|
||||
AZ::StringFunc::Path::Normalize(szPath);
|
||||
AZStd::to_lower(AZStd::begin(szPath), AZStd::end(szPath));
|
||||
AZ::IO::PathView szPath{ szPathSrc };
|
||||
|
||||
ZipDir::FindFile fd(GetRoot());
|
||||
FileEntry* fileEntry = fd.FindExact(szPath);
|
||||
@@ -779,19 +759,13 @@ namespace AZ::IO::ZipDir
|
||||
{
|
||||
if (az_archive_zip_directory_cache_verbosity)
|
||||
{
|
||||
AZ_TracePrintf("Archive", "FindExact failed to find file %s at root %s", szPath.c_str(), GetFilePath());
|
||||
AZ_TracePrintf("Archive", "FindExact failed to find file %.*s at root %s", AZ_STRING_ARG(szPath.Native()), GetFilePath());
|
||||
}
|
||||
return {};
|
||||
}
|
||||
return fileEntry;
|
||||
}
|
||||
|
||||
// returns the size of memory occupied by the instance referred to by this cache
|
||||
size_t Cache::GetSize() const
|
||||
{
|
||||
return sizeof(*this) + m_strFilePath.capacity() + m_treeDir.GetSize() - sizeof(m_treeDir);
|
||||
}
|
||||
|
||||
// refreshes information about the given file entry into this file entry
|
||||
ErrorEnum Cache::Refresh(FileEntryBase* pFileEntry)
|
||||
{
|
||||
@@ -800,7 +774,7 @@ namespace AZ::IO::ZipDir
|
||||
return ZD_ERROR_INVALID_CALL;
|
||||
}
|
||||
|
||||
if (pFileEntry->nFileDataOffset != pFileEntry->INVALID_DATA_OFFSET)
|
||||
if (pFileEntry->nFileDataOffset != FileEntryBase::INVALID_DATA_OFFSET)
|
||||
{
|
||||
return ZD_ERROR_SUCCESS; // the data offset has been successfully read..
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user