Merge branch 'development' into Prefab/SaveAllPrefabs
Signed-off-by: srikappa-amzn <srikappa@amazon.com>
This commit is contained in:
@@ -13,8 +13,6 @@ set(FILES
|
||||
Instance/InstanceData.h
|
||||
Instance/InstanceData.cpp
|
||||
Instance/InstanceDatabase.h
|
||||
Serialization/Json/JsonUtils.h
|
||||
Serialization/Json/JsonUtils.cpp
|
||||
std/containers/array_view.h
|
||||
std/containers/fixed_vector_set.h
|
||||
std/containers/lru_cache.h
|
||||
|
||||
@@ -324,7 +324,7 @@ namespace UnitTest
|
||||
|
||||
// Tests whether the deleter actually calls delete properly without
|
||||
// a parent database.
|
||||
instance->m_onDeleteCallback = [this, &m_deleted]()
|
||||
instance->m_onDeleteCallback = [&m_deleted]()
|
||||
{
|
||||
m_deleted = true;
|
||||
};
|
||||
|
||||
@@ -10,7 +10,6 @@ set(FILES
|
||||
ArrayView.cpp
|
||||
ConcurrencyCheckerTests.cpp
|
||||
InstanceDatabase.cpp
|
||||
JsonSerializationUtilsTests.cpp
|
||||
lru_cache.cpp
|
||||
Main.cpp
|
||||
vector_set.cpp
|
||||
|
||||
@@ -456,7 +456,7 @@ namespace AZ
|
||||
{
|
||||
if (loadBehavior & (1 << thisFlag))
|
||||
{
|
||||
returnFlags[thisFlag] = 1;
|
||||
returnFlags[thisFlag] = true;
|
||||
}
|
||||
}
|
||||
return returnFlags;
|
||||
|
||||
@@ -153,6 +153,7 @@ namespace AZ
|
||||
// behavior, we would need to rework the way filters work as well as the code in AssetSerializer.cpp to pass down
|
||||
// the loadParams.m_assetLoadFilterCB that was passed into the AddDependentAssets() methods to use as the dependent
|
||||
// asset filter instead of this lambda function.
|
||||
AZ_UNUSED(handledAssetDependencyList); // Prevent unused warning in release builds
|
||||
AZ_Assert(AZStd::find(handledAssetDependencyList.begin(), handledAssetDependencyList.end(), filterInfo.m_assetId) !=
|
||||
handledAssetDependencyList.end(),
|
||||
"Dependent Asset ID (%s) is expected to load, but the Asset Catalog has no dependency recorded. "
|
||||
|
||||
@@ -71,8 +71,8 @@ namespace AZ
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
typedef AssetId BusIdType;
|
||||
typedef AZStd::recursive_mutex MutexType;
|
||||
using BusIdType = AssetId;
|
||||
using MutexType = AZStd::recursive_mutex;
|
||||
|
||||
template <class Bus>
|
||||
struct AssetJobConnectionPolicy
|
||||
@@ -107,7 +107,7 @@ namespace AZ
|
||||
virtual void OnLoadCanceled(AssetId assetId) = 0;
|
||||
};
|
||||
|
||||
typedef EBus<BlockingAssetLoadEvents> BlockingAssetLoadBus;
|
||||
using BlockingAssetLoadBus = EBus<BlockingAssetLoadEvents>;
|
||||
|
||||
/*
|
||||
* This class processes async AssetDatabase load jobs
|
||||
@@ -1478,7 +1478,7 @@ namespace AZ
|
||||
|
||||
// Resolve the asset handler and account for the new asset instance.
|
||||
{
|
||||
AssetHandlerMap::iterator handlerIt = m_handlers.find(newData->GetType());
|
||||
[[maybe_unused]] AssetHandlerMap::iterator handlerIt = m_handlers.find(newData->GetType());
|
||||
AZ_Assert(
|
||||
handlerIt != m_handlers.end(), "No handler was registered for this asset [type:%s id:%s]!",
|
||||
newData->GetType().ToString<AZ::OSString>().c_str(), newData->GetId().ToString<AZ::OSString>().c_str());
|
||||
@@ -1869,7 +1869,7 @@ namespace AZ
|
||||
{
|
||||
AZStd::scoped_lock<AZStd::recursive_mutex> requestLock(m_activeBlockingRequestMutex);
|
||||
|
||||
auto inserted = m_activeBlockingRequests.insert(AZStd::make_pair(assetId, blockingRequest));
|
||||
[[maybe_unused]] auto inserted = m_activeBlockingRequests.insert(AZStd::make_pair(assetId, blockingRequest));
|
||||
AZ_Assert(inserted.second, "Failed to track blocking request for asset %s", assetId.ToString<AZStd::string>().c_str());
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
// Component includes
|
||||
#include <AzCore/Asset/AssetManagerComponent.h>
|
||||
#include <AzCore/Debug/FrameProfilerComponent.h>
|
||||
#include <AzCore/IO/Streamer/StreamerComponent.h>
|
||||
#include <AzCore/Jobs/JobManagerComponent.h>
|
||||
#include <AzCore/Serialization/Json/JsonSystemComponent.h>
|
||||
@@ -36,7 +35,6 @@ namespace AZ
|
||||
JsonSystemComponent::CreateDescriptor(),
|
||||
AssetManagerComponent::CreateDescriptor(),
|
||||
UserSettingsComponent::CreateDescriptor(),
|
||||
Debug::FrameProfilerComponent::CreateDescriptor(),
|
||||
SliceComponent::CreateDescriptor(),
|
||||
SliceSystemComponent::CreateDescriptor(),
|
||||
SliceMetadataInfoComponent::CreateDescriptor(),
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
#include <AzCore/Driller/Driller.h>
|
||||
#include <AzCore/Memory/MemoryDriller.h>
|
||||
#include <AzCore/Debug/TraceMessagesDriller.h>
|
||||
#include <AzCore/Debug/ProfilerDriller.h>
|
||||
#include <AzCore/Debug/EventTraceDriller.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Script/ScriptSystemBus.h>
|
||||
@@ -546,6 +545,10 @@ namespace AZ
|
||||
m_entityActivatedEvent.DisconnectAllHandlers();
|
||||
m_entityDeactivatedEvent.DisconnectAllHandlers();
|
||||
|
||||
#if !defined(_RELEASE)
|
||||
m_budgetTracker.Reset();
|
||||
#endif
|
||||
|
||||
DestroyAllocator();
|
||||
}
|
||||
|
||||
@@ -594,6 +597,10 @@ namespace AZ
|
||||
CreateOSAllocator();
|
||||
CreateSystemAllocator();
|
||||
|
||||
#if !defined(_RELEASE)
|
||||
m_budgetTracker.Init();
|
||||
#endif
|
||||
|
||||
// This can be moved to the ComponentApplication constructor if need be
|
||||
// This is reading the *.setreg files using SystemFile and merging the settings
|
||||
// to the settings registry.
|
||||
@@ -625,8 +632,6 @@ namespace AZ
|
||||
m_eventLogger->Start(outputPath.Native(), baseFileName);
|
||||
}
|
||||
|
||||
CreateDrillers();
|
||||
|
||||
Sfmt::Create();
|
||||
|
||||
CreateReflectionManager();
|
||||
@@ -639,7 +644,7 @@ namespace AZ
|
||||
NameDictionary::Create();
|
||||
|
||||
// Call this and child class's reflects
|
||||
ReflectionEnvironment::GetReflectionManager()->Reflect(azrtti_typeid(this), AZStd::bind(&ComponentApplication::Reflect, this, AZStd::placeholders::_1));
|
||||
ReflectionEnvironment::GetReflectionManager()->Reflect(azrtti_typeid(this), [this](ReflectContext* context) {Reflect(context); });
|
||||
|
||||
RegisterCoreComponents();
|
||||
TickBus::AllowFunctionQueuing(true);
|
||||
@@ -746,12 +751,6 @@ namespace AZ
|
||||
ComponentApplicationBus::Handler::BusDisconnect();
|
||||
TickRequestBus::Handler::BusDisconnect();
|
||||
|
||||
if (m_drillerManager)
|
||||
{
|
||||
Debug::DrillerManager::Destroy(m_drillerManager);
|
||||
m_drillerManager = nullptr;
|
||||
}
|
||||
|
||||
m_eventLogger->Stop();
|
||||
|
||||
// Clear the descriptor to deallocate all strings (owned by ModuleDescriptor)
|
||||
@@ -899,33 +898,6 @@ namespace AZ
|
||||
allocatorManager.FinalizeConfiguration();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// CreateDrillers
|
||||
// [2/20/2013]
|
||||
//=========================================================================
|
||||
void ComponentApplication::CreateDrillers()
|
||||
{
|
||||
// Create driller manager and register drillers if requested
|
||||
if (m_descriptor.m_enableDrilling)
|
||||
{
|
||||
m_drillerManager = Debug::DrillerManager::Create();
|
||||
// Memory driller is responsible for tracking allocations.
|
||||
// Tracking type and overhead is determined by app configuration.
|
||||
|
||||
// Only one MemoryDriller is supported at a time
|
||||
// Only create the memory driller if there is no handlers connected to the MemoryDrillerBus
|
||||
if (!Debug::MemoryDrillerBus::HasHandlers())
|
||||
{
|
||||
m_drillerManager->Register(aznew Debug::MemoryDriller);
|
||||
}
|
||||
// Profiler driller will consume resources only when started.
|
||||
m_drillerManager->Register(aznew Debug::ProfilerDriller);
|
||||
// Trace messages driller will consume resources only when started.
|
||||
m_drillerManager->Register(aznew Debug::TraceMessagesDriller);
|
||||
m_drillerManager->Register(aznew Debug::EventTraceDriller);
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentApplication::MergeSettingsToRegistry(SettingsRegistryInterface& registry)
|
||||
{
|
||||
SettingsRegistryInterface::Specializations specializations;
|
||||
@@ -998,7 +970,12 @@ namespace AZ
|
||||
{
|
||||
if (ReflectionEnvironment::GetReflectionManager())
|
||||
{
|
||||
ReflectionEnvironment::GetReflectionManager()->Reflect(descriptor->GetUuid(), AZStd::bind(&ComponentDescriptor::Reflect, descriptor, AZStd::placeholders::_1));
|
||||
ReflectionEnvironment::GetReflectionManager()->Reflect(
|
||||
descriptor->GetUuid(),
|
||||
[descriptor](ReflectContext* context)
|
||||
{
|
||||
descriptor->Reflect(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1294,7 +1271,7 @@ namespace AZ
|
||||
void Visit(AZStd::string_view path, AZStd::string_view, AZ::SettingsRegistryInterface::Type, AZStd::string_view value) override
|
||||
{
|
||||
// Remove last path segment and check if the key corresponds to the Modules array
|
||||
AZStd::optional<AZStd::string_view> moduleIndex = AZ::StringFunc::TokenizeLast(path, "/");
|
||||
AZ::StringFunc::TokenizeLast(path, "/");
|
||||
if (path.ends_with("/Modules"))
|
||||
{
|
||||
// Remove the "Modules" path segment to be at the GemName key
|
||||
@@ -1416,10 +1393,6 @@ namespace AZ
|
||||
EBUS_EVENT(TickBus, OnTick, m_deltaTime, ScriptTimePoint(now));
|
||||
}
|
||||
}
|
||||
if (m_drillerManager)
|
||||
{
|
||||
m_drillerManager->FrameUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/Memory/AllocationRecords.h>
|
||||
#include <AzCore/Debug/BudgetTracker.h>
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
#include <AzCore/Module/DynamicModuleHandle.h>
|
||||
#include <AzCore/Module/ModuleManager.h>
|
||||
@@ -225,11 +226,6 @@ namespace AZ
|
||||
/// Returns the path to the folder the executable is in.
|
||||
const char* GetExecutableFolder() const override { return m_exeDirectory.c_str(); }
|
||||
|
||||
|
||||
/// Returns pointer to the driller manager if it's enabled, otherwise NULL.
|
||||
Debug::DrillerManager* GetDrillerManager() override { return m_drillerManager; }
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/// TickRequestBus
|
||||
float GetTickDeltaTime() override;
|
||||
@@ -324,9 +320,6 @@ namespace AZ
|
||||
/// Create the system allocator using the data in the m_descriptor
|
||||
void CreateSystemAllocator();
|
||||
|
||||
/// Create the drillers
|
||||
void CreateDrillers();
|
||||
|
||||
virtual void MergeSettingsToRegistry(SettingsRegistryInterface& registry);
|
||||
|
||||
//! Sets the specializations that will be used when loading the Settings Registry. Extend this in derived
|
||||
@@ -402,6 +395,10 @@ namespace AZ
|
||||
// from the m_console member when it goes out of scope
|
||||
AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle m_settingsRegistryConsoleFunctors;
|
||||
|
||||
#if !defined(_RELEASE)
|
||||
Debug::BudgetTracker m_budgetTracker;
|
||||
#endif
|
||||
|
||||
// this is used when no argV/ArgC is supplied.
|
||||
// in order to have the same memory semantics (writable, non-const)
|
||||
// we create a buffer that can be written to (up to AZ_MAX_PATH_LEN) and then
|
||||
@@ -409,8 +406,6 @@ namespace AZ
|
||||
char m_commandLineBuffer[AZ_MAX_PATH_LEN];
|
||||
char* m_commandLineBufferAddress{ m_commandLineBuffer };
|
||||
|
||||
Debug::DrillerManager* m_drillerManager{ nullptr };
|
||||
|
||||
StartupParameters m_startupParameters;
|
||||
|
||||
char** m_argV{ nullptr };
|
||||
|
||||
@@ -187,11 +187,6 @@ namespace AZ
|
||||
//! @return a pointer to the name of the path that contains the application's executable.
|
||||
virtual const char* GetExecutableFolder() const = 0;
|
||||
|
||||
//! Returns a pointer to the driller manager, if driller is enabled.
|
||||
//! The driller manager manages all active driller sessions and driller factories.
|
||||
//! @return A pointer to the driller manager. If driller is not enabled, this function returns null.
|
||||
virtual Debug::DrillerManager* GetDrillerManager() = 0;
|
||||
|
||||
//! ResolveModulePath is called whenever LoadDynamicModule wants to resolve a module in order to actually load it.
|
||||
//! You can override this if you need to load modules from a different path or hijack module loading in some other way.
|
||||
//! If you do, ensure that you use platform-specific conventions to do so, as this is called by multiple platforms.
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Debug/Budget.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/EBus/Event.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
@@ -438,3 +439,4 @@ namespace AZ
|
||||
return component;
|
||||
}
|
||||
} // namespace AZ
|
||||
|
||||
|
||||
@@ -81,20 +81,22 @@ namespace AZ
|
||||
azrtti_typeid<decltype(componentMap)>(),
|
||||
inputValue, "Components", context);
|
||||
|
||||
static TypeId genericComponentWrapperTypeId("{68D358CA-89B9-4730-8BA6-E181DEA28FDE}");
|
||||
for (auto& [componentKey, component] : componentMap)
|
||||
{
|
||||
entityInstance->m_components.emplace_back(component);
|
||||
// if underlying type is genericComponentWrapperTypeId, the template is null and the component should not be addded
|
||||
if (component->GetUnderlyingComponentType() != genericComponentWrapperTypeId)
|
||||
{
|
||||
entityInstance->m_components.emplace_back(component);
|
||||
}
|
||||
}
|
||||
|
||||
result.Combine(componentLoadResult);
|
||||
}
|
||||
|
||||
{
|
||||
JSR::ResultCode runtimeActiveLoadResult =
|
||||
ContinueLoadingFromJsonObjectField(&entityInstance->m_isRuntimeActiveByDefault,
|
||||
azrtti_typeid<decltype(entityInstance->m_isRuntimeActiveByDefault)>(),
|
||||
inputValue, "IsRuntimeActive", context);
|
||||
}
|
||||
ContinueLoadingFromJsonObjectField(&entityInstance->m_isRuntimeActiveByDefault,
|
||||
azrtti_typeid<decltype(entityInstance->m_isRuntimeActiveByDefault)>(),
|
||||
inputValue, "IsRuntimeActive", context);
|
||||
|
||||
return context.Report(
|
||||
result,
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace AZ
|
||||
|
||||
AZStd::fixed_vector<TypeId, 64> knownBaseClasses = { typeToExamine }; // avoid allocating heap here if possible. 64 types are 64*sizeof(Uuid) which is only 1k.
|
||||
bool foundBaseClass = false;
|
||||
auto enumerateBaseVisitor = [&foundBaseClass, &baseClassVisitor, &knownBaseClasses](const AZ::SerializeContext::ClassData* classData, const TypeId& examineTypeId)
|
||||
auto enumerateBaseVisitor = [&baseClassVisitor, &knownBaseClasses](const AZ::SerializeContext::ClassData* classData, const TypeId& examineTypeId)
|
||||
{
|
||||
if (!classData)
|
||||
{
|
||||
|
||||
@@ -23,8 +23,8 @@ using namespace AZ;
|
||||
// [3/21/2011]
|
||||
//=========================================================================
|
||||
ZLib::ZLib(IAllocator* workMemAllocator)
|
||||
: m_strDeflate(NULL)
|
||||
, m_strInflate(NULL)
|
||||
: m_strDeflate(nullptr)
|
||||
, m_strInflate(nullptr)
|
||||
{
|
||||
m_workMemoryAllocator = workMemAllocator ? workMemAllocator->GetAllocationSource() : nullptr;
|
||||
if (!m_workMemoryAllocator)
|
||||
@@ -75,7 +75,7 @@ void ZLib::FreeMem(void* userData, void* address)
|
||||
//=========================================================================
|
||||
void ZLib::StartCompressor(unsigned int compressionLevel)
|
||||
{
|
||||
AZ_Assert(m_strDeflate == NULL, "Compressor already started!");
|
||||
AZ_Assert(m_strDeflate == nullptr, "Compressor already started!");
|
||||
m_strDeflate = reinterpret_cast< z_stream* >(AllocateMem(m_workMemoryAllocator, 1, sizeof(z_stream)));
|
||||
m_strDeflate->zalloc = &ZLib::AllocateMem;
|
||||
m_strDeflate->zfree = &ZLib::FreeMem;
|
||||
@@ -91,10 +91,10 @@ void ZLib::StartCompressor(unsigned int compressionLevel)
|
||||
//=========================================================================
|
||||
void ZLib::StopCompressor()
|
||||
{
|
||||
AZ_Assert(m_strDeflate != NULL, "Compressor not started!");
|
||||
AZ_Assert(m_strDeflate != nullptr, "Compressor not started!");
|
||||
deflateEnd(m_strDeflate);
|
||||
FreeMem(m_workMemoryAllocator, m_strDeflate);
|
||||
m_strDeflate = NULL;
|
||||
m_strDeflate = nullptr;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -103,7 +103,7 @@ void ZLib::StopCompressor()
|
||||
//=========================================================================
|
||||
void ZLib::ResetCompressor()
|
||||
{
|
||||
AZ_Assert(m_strDeflate != NULL, "Compressor not started!");
|
||||
AZ_Assert(m_strDeflate != nullptr, "Compressor not started!");
|
||||
int r = deflateReset(m_strDeflate);
|
||||
(void)r;
|
||||
AZ_Assert(r == Z_OK, "ZLib inconsistent state - deflateReset() failed !!!\n");
|
||||
@@ -115,7 +115,7 @@ void ZLib::ResetCompressor()
|
||||
//=========================================================================
|
||||
unsigned int ZLib::Compress(const void* data, unsigned int& dataSize, void* compressedData, unsigned int compressedDataSize, FlushType flushType)
|
||||
{
|
||||
AZ_Assert(m_strDeflate != NULL, "Compressor not started!");
|
||||
AZ_Assert(m_strDeflate != nullptr, "Compressor not started!");
|
||||
m_strDeflate->avail_in = dataSize;
|
||||
m_strDeflate->next_in = (unsigned char*)data;
|
||||
m_strDeflate->avail_out = compressedDataSize;
|
||||
@@ -158,7 +158,7 @@ unsigned int ZLib::Compress(const void* data, unsigned int& dataSize, void* comp
|
||||
//=========================================================================
|
||||
unsigned int ZLib::GetMinCompressedBufferSize(unsigned int sourceDataSize)
|
||||
{
|
||||
AZ_Assert(m_strDeflate != NULL, "Compressor not started!");
|
||||
AZ_Assert(m_strDeflate != nullptr, "Compressor not started!");
|
||||
return static_cast<unsigned int>(deflateBound(m_strDeflate, sourceDataSize));
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ unsigned int ZLib::GetMinCompressedBufferSize(unsigned int sourceDataSize)
|
||||
//=========================================================================
|
||||
void ZLib::StartDecompressor(Header* header)
|
||||
{
|
||||
AZ_Assert(m_strInflate == NULL, "Decompressor already started!");
|
||||
AZ_Assert(m_strInflate == nullptr, "Decompressor already started!");
|
||||
m_strInflate = reinterpret_cast< z_stream* >(AllocateMem(m_workMemoryAllocator, 1, sizeof(z_stream)));
|
||||
m_strInflate->zalloc = &ZLib::AllocateMem;
|
||||
m_strInflate->zfree = &ZLib::FreeMem;
|
||||
@@ -188,10 +188,10 @@ void ZLib::StartDecompressor(Header* header)
|
||||
//=========================================================================
|
||||
void ZLib::StopDecompressor()
|
||||
{
|
||||
AZ_Assert(m_strInflate != NULL, "Decompressor not started!");
|
||||
AZ_Assert(m_strInflate != nullptr, "Decompressor not started!");
|
||||
inflateEnd(m_strInflate);
|
||||
FreeMem(m_workMemoryAllocator, m_strInflate);
|
||||
m_strInflate = NULL;
|
||||
m_strInflate = nullptr;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -200,7 +200,7 @@ void ZLib::StopDecompressor()
|
||||
//=========================================================================
|
||||
void ZLib::ResetDecompressor(Header* header)
|
||||
{
|
||||
AZ_Assert(m_strInflate != NULL, "Decompressor not started!");
|
||||
AZ_Assert(m_strInflate != nullptr, "Decompressor not started!");
|
||||
int r = inflateReset(m_strInflate);
|
||||
(void)r;
|
||||
AZ_Assert(r == Z_OK, "ZLib inconsistent state - inflateReset() failed !!!\n");
|
||||
@@ -229,7 +229,7 @@ void ZLib::SetupDecompressHeader(Header header)
|
||||
//=========================================================================
|
||||
unsigned int ZLib::Decompress(const void* compressedData, unsigned int compressedDataSize, void* data, unsigned int& dataSize, FlushType flushType)
|
||||
{
|
||||
AZ_Assert(m_strInflate != NULL, "Decompressor not started!");
|
||||
AZ_Assert(m_strInflate != nullptr, "Decompressor not started!");
|
||||
m_strInflate->avail_in = compressedDataSize;
|
||||
m_strInflate->next_in = (unsigned char*)compressedData;
|
||||
m_strInflate->avail_out = dataSize;
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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 "Budget.h"
|
||||
|
||||
#include <AzCore/Module/Environment.h>
|
||||
#include <AzCore/Math/Crc.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
|
||||
AZ_DEFINE_BUDGET(Animation);
|
||||
AZ_DEFINE_BUDGET(Audio);
|
||||
AZ_DEFINE_BUDGET(AzCore);
|
||||
AZ_DEFINE_BUDGET(Editor);
|
||||
AZ_DEFINE_BUDGET(Entity);
|
||||
AZ_DEFINE_BUDGET(Game);
|
||||
AZ_DEFINE_BUDGET(System);
|
||||
AZ_DEFINE_BUDGET(Physics);
|
||||
|
||||
namespace AZ::Debug
|
||||
{
|
||||
struct BudgetImpl
|
||||
{
|
||||
AZ_CLASS_ALLOCATOR(BudgetImpl, AZ::SystemAllocator, 0);
|
||||
// TODO: Budget implementation for tracking budget wall time per-core, memory, etc.
|
||||
};
|
||||
|
||||
Budget::Budget(const char* name)
|
||||
: m_name{ name }
|
||||
, m_crc{ Crc32(name) }
|
||||
{
|
||||
}
|
||||
|
||||
Budget::Budget(const char* name, uint32_t crc)
|
||||
: m_name{ name }
|
||||
, m_crc{ crc }
|
||||
{
|
||||
m_impl = aznew BudgetImpl;
|
||||
}
|
||||
|
||||
Budget::~Budget()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
delete m_impl;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO:Budgets Methods below are stubbed pending future work to both update budget data and visualize it
|
||||
|
||||
void Budget::PerFrameReset()
|
||||
{
|
||||
}
|
||||
|
||||
void Budget::BeginProfileRegion()
|
||||
{
|
||||
}
|
||||
|
||||
void Budget::EndProfileRegion()
|
||||
{
|
||||
}
|
||||
|
||||
void Budget::TrackAllocation(uint64_t)
|
||||
{
|
||||
}
|
||||
|
||||
void Budget::UntrackAllocation(uint64_t)
|
||||
{
|
||||
}
|
||||
} // namespace AZ::Debug
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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/Debug/BudgetTracker.h>
|
||||
#include <AzCore/Math/Crc.h>
|
||||
|
||||
namespace AZ::Debug
|
||||
{
|
||||
// A budget collates per-frame resource utilization and memory for a particular category
|
||||
class Budget final
|
||||
{
|
||||
public:
|
||||
explicit Budget(const char* name);
|
||||
Budget(const char* name, uint32_t crc);
|
||||
~Budget();
|
||||
|
||||
void PerFrameReset();
|
||||
void BeginProfileRegion();
|
||||
void EndProfileRegion();
|
||||
void TrackAllocation(uint64_t bytes);
|
||||
void UntrackAllocation(uint64_t bytes);
|
||||
|
||||
const char* Name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
uint32_t Crc() const
|
||||
{
|
||||
return m_crc;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* m_name;
|
||||
const uint32_t m_crc;
|
||||
struct BudgetImpl* m_impl = nullptr;
|
||||
};
|
||||
} // namespace AZ::Debug
|
||||
|
||||
// The budget is usable in the same file it was defined without needing an additional declaration.
|
||||
// If you encounter a linker error complaining that this function is not defined, you have likely forgotten to either
|
||||
// define or declare the budget used in a profile or memory marker. See AZ_DEFINE_BUDGET and AZ_DECLARE_BUDGET below
|
||||
// for usage.
|
||||
#define AZ_BUDGET_GETTER(name) GetAzBudget##name
|
||||
|
||||
#if defined(_RELEASE)
|
||||
#define AZ_DEFINE_BUDGET(name) \
|
||||
::AZ::Debug::Budget* AZ_BUDGET_GETTER(name)() \
|
||||
{ \
|
||||
return nullptr; \
|
||||
}
|
||||
#else
|
||||
// Usage example:
|
||||
// In a single C++ source file:
|
||||
// AZ_DEFINE_BUDGET(AzCore);
|
||||
//
|
||||
// Anywhere the budget is used, the budget must be declared (either in a header or in the source file itself)
|
||||
// AZ_DECLARE_BUDGET(AzCore);
|
||||
#define AZ_DEFINE_BUDGET(name) \
|
||||
::AZ::Debug::Budget* AZ_BUDGET_GETTER(name)() \
|
||||
{ \
|
||||
constexpr static uint32_t crc = AZ_CRC_CE(#name); \
|
||||
static ::AZ::Debug::Budget* budget = ::AZ::Debug::BudgetTracker::GetBudgetFromEnvironment(#name, crc); \
|
||||
return budget; \
|
||||
}
|
||||
#endif
|
||||
|
||||
// If using a budget defined in a different C++ source file, add AZ_DECLARE_BUDGET(yourBudget); somewhere in your source file at namespace
|
||||
// scope Alternatively, AZ_DECLARE_BUDGET can be used in a header to declare the budget for use across any users of the header
|
||||
#define AZ_DECLARE_BUDGET(name) ::AZ::Debug::Budget* AZ_BUDGET_GETTER(name)()
|
||||
|
||||
// Declare budgets that are core engine budgets, or may be shared/needed across multiple external gems
|
||||
// You should NOT need to declare user-space or budgets with isolated usage here. Prefer declaring them local to the module(s) that use
|
||||
// the budget and defining them within a single module to avoid needing to recompile the entire engine.
|
||||
AZ_DECLARE_BUDGET(Animation);
|
||||
AZ_DECLARE_BUDGET(Audio);
|
||||
AZ_DECLARE_BUDGET(AzCore);
|
||||
AZ_DECLARE_BUDGET(Editor);
|
||||
AZ_DECLARE_BUDGET(Entity);
|
||||
AZ_DECLARE_BUDGET(Game);
|
||||
AZ_DECLARE_BUDGET(System);
|
||||
AZ_DECLARE_BUDGET(Physics);
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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/Debug/BudgetTracker.h>
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/Debug/Budget.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/parallel/scoped_lock.h>
|
||||
|
||||
namespace AZ::Debug
|
||||
{
|
||||
struct BudgetTracker::BudgetTrackerImpl
|
||||
{
|
||||
AZStd::unordered_map<const char*, Budget> m_budgets;
|
||||
};
|
||||
|
||||
Budget* BudgetTracker::GetBudgetFromEnvironment(const char* budgetName, uint32_t crc)
|
||||
{
|
||||
BudgetTracker* tracker = Interface<BudgetTracker>::Get();
|
||||
if (tracker)
|
||||
{
|
||||
return &tracker->GetBudget(budgetName, crc);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BudgetTracker::~BudgetTracker()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
bool BudgetTracker::Init()
|
||||
{
|
||||
if (Interface<BudgetTracker>::Get())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Interface<BudgetTracker>::Register(this);
|
||||
m_impl = new BudgetTrackerImpl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void BudgetTracker::Reset()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
Interface<BudgetTracker>::Unregister(this);
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Budget& BudgetTracker::GetBudget(const char* budgetName, uint32_t crc)
|
||||
{
|
||||
AZStd::scoped_lock lock{ m_mutex };
|
||||
|
||||
auto it = m_impl->m_budgets.try_emplace(budgetName, budgetName, crc).first;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
} // namespace AZ::Debug
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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/Module/Environment.h>
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
|
||||
namespace AZ::Debug
|
||||
{
|
||||
class Budget;
|
||||
|
||||
class BudgetTracker
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(BudgetTracker, "{E14A746D-BFFE-4C02-90FB-4699B79864A5}");
|
||||
static Budget* GetBudgetFromEnvironment(const char* budgetName, uint32_t crc);
|
||||
|
||||
~BudgetTracker();
|
||||
|
||||
// Returns false if the budget tracker was already present in the environment (initialized already elsewhere)
|
||||
bool Init();
|
||||
void Reset();
|
||||
|
||||
Budget& GetBudget(const char* budgetName, uint32_t crc);
|
||||
|
||||
private:
|
||||
struct BudgetTrackerImpl;
|
||||
|
||||
AZStd::mutex m_mutex;
|
||||
|
||||
// The BudgetTracker is likely included in proportionally high number of files throughout the
|
||||
// engine, so indirection is used here to avoid imposing excessive recompilation in periods
|
||||
// while the budget system is iterated on.
|
||||
BudgetTrackerImpl* m_impl = nullptr;
|
||||
};
|
||||
} // namespace AZ::Debug
|
||||
@@ -26,7 +26,6 @@ namespace AZ
|
||||
const u32 Timestamp = AZ_CRC("Timestamp", 0xa5d6e63e);
|
||||
const u32 Duration = AZ_CRC("Duration", 0x865f80c0);
|
||||
const u32 Instant = AZ_CRC("Instant", 0x0e9047ad);
|
||||
const u32 InstantScope = AZ_CRC("InstantScope", 0xed4bfb0e);
|
||||
}
|
||||
|
||||
EventTraceDriller::EventTraceDriller()
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#ifndef AZCORE_FRAME_PROFILER_H
|
||||
#define AZCORE_FRAME_PROFILER_H
|
||||
|
||||
#include <AzCore/Driller/DrillerBus.h>
|
||||
#include <AzCore/std/containers/ring_buffer.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/std/parallel/config.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Debug
|
||||
{
|
||||
namespace FrameProfiler
|
||||
{
|
||||
/**
|
||||
* This structure is used for frame data history, make sure it's memory efficient.
|
||||
*/
|
||||
struct FrameData
|
||||
{
|
||||
unsigned int m_frameId; ///< Id of the frame this data belongs to.
|
||||
union
|
||||
{
|
||||
ProfilerRegister::TimeData m_timeData;
|
||||
ProfilerRegister::ValuesData m_userValues;
|
||||
};
|
||||
};
|
||||
|
||||
struct RegisterData
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Profile register snapshot
|
||||
/// data that doesn't change
|
||||
const char* m_name; ///< Name of the profiler register.
|
||||
const char* m_function; ///< Function name in the code.
|
||||
int m_line; ///< Line number if the code.
|
||||
AZ::u32 m_systemId; ///< Register system id.
|
||||
ProfilerRegister::Type m_type;
|
||||
RegisterData* m_lastParent; ///< Pointer to the last parent register data.
|
||||
AZStd::ring_buffer<FrameData> m_frames; ///< History of all frame deltas (basically the data you want to display)
|
||||
};
|
||||
|
||||
struct ThreadData
|
||||
{
|
||||
typedef AZStd::unordered_map<const ProfilerRegister*, RegisterData> RegistersMap;
|
||||
AZStd::thread_id m_id; ///< Thread id (same as AZStd::thread::id)
|
||||
RegistersMap m_registers; ///< Map with all the registers (with history)
|
||||
};
|
||||
|
||||
typedef AZStd::fixed_vector<ThreadData, Profiler::m_maxNumberOfThreads> ThreadDataArray; ///< Array with samplers for all threads
|
||||
} // namespace FrameProfiler
|
||||
} // namespace Debug
|
||||
} // namespace AZ
|
||||
|
||||
#endif // AZCORE_FRAME_PROFILER_H
|
||||
#pragma once
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#ifndef AZCORE_FRAME_PROFILER_BUS_H
|
||||
#define AZCORE_FRAME_PROFILER_BUS_H
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Debug/FrameProfiler.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Debug
|
||||
{
|
||||
class FrameProfilerComponent;
|
||||
|
||||
/**
|
||||
* Interface class for frame profiler events.
|
||||
*/
|
||||
class FrameProfilerEvents
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
virtual ~FrameProfilerEvents() {}
|
||||
|
||||
/// Called when the frame profiler has computed a new frame (even is there is no new data).
|
||||
virtual void OnFrameProfilerData(const FrameProfiler::ThreadDataArray& data) = 0;
|
||||
};
|
||||
|
||||
typedef AZ::EBus<FrameProfilerEvents> FrameProfilerBus;
|
||||
} // namespace Debug
|
||||
} // namespace AZ
|
||||
|
||||
#endif // AZCORE_FRAME_PROFILER_BUS_H
|
||||
#pragma once
|
||||
@@ -1,250 +0,0 @@
|
||||
/*
|
||||
* 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/Debug/FrameProfilerComponent.h>
|
||||
#include <AzCore/Debug/FrameProfilerBus.h>
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Debug
|
||||
{
|
||||
//=========================================================================
|
||||
// FrameProfilerComponent
|
||||
// [12/5/2012]
|
||||
//=========================================================================
|
||||
FrameProfilerComponent::FrameProfilerComponent()
|
||||
: m_numFramesStored(2)
|
||||
, m_frameId(0)
|
||||
, m_pauseOnFrame(0)
|
||||
, m_currentThreadData(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ~FrameProfilerComponent
|
||||
// [12/5/2012]
|
||||
//=========================================================================
|
||||
FrameProfilerComponent::~FrameProfilerComponent()
|
||||
{
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Activate
|
||||
// [12/5/2012]
|
||||
//=========================================================================
|
||||
void FrameProfilerComponent::Activate()
|
||||
{
|
||||
if (!Profiler::IsReady())
|
||||
{
|
||||
Profiler::Create();
|
||||
}
|
||||
|
||||
Profiler::AddReference();
|
||||
|
||||
TickBus::Handler::BusConnect();
|
||||
AZ_Assert(m_numFramesStored >= 1, "We must have at least one frame to store, otherwise this component is useless!");
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Deactivate
|
||||
// [12/5/2012]
|
||||
//=========================================================================
|
||||
void FrameProfilerComponent::Deactivate()
|
||||
{
|
||||
TickBus::Handler::BusDisconnect();
|
||||
|
||||
Profiler::ReleaseReference();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// OnTick
|
||||
// [12/5/2012]
|
||||
//=========================================================================
|
||||
void FrameProfilerComponent::OnTick(float deltaTime, ScriptTimePoint time)
|
||||
{
|
||||
(void)deltaTime;
|
||||
(void)time;
|
||||
++m_frameId;
|
||||
AZ_Error("Profiler", m_frameId != m_pauseOnFrame, "Triggered user pause/error on this frame! Check FrameProfilerComponent pauseOnFrame value!");
|
||||
|
||||
if (!Profiler::IsReady())
|
||||
{
|
||||
return; // we can't sample registers without profiler
|
||||
}
|
||||
// collect data from the profiler
|
||||
m_currentThreadData = NULL;
|
||||
Profiler::Instance().ReadRegisterValues(AZStd::bind(&FrameProfilerComponent::ReadProfilerRegisters, this, AZStd::placeholders::_1, AZStd::placeholders::_2));
|
||||
|
||||
// process all the resulting data here, not while reading the registers
|
||||
for (size_t iThread = 0; iThread < m_threads.size(); ++iThread)
|
||||
{
|
||||
FrameProfiler::ThreadData& td = m_threads[iThread];
|
||||
FrameProfiler::ThreadData::RegistersMap::iterator it = td.m_registers.begin();
|
||||
FrameProfiler::ThreadData::RegistersMap::iterator last = td.m_registers.end();
|
||||
for (; it != last; ++it)
|
||||
{
|
||||
// fix up parents
|
||||
FrameProfiler::RegisterData& rd = it->second;
|
||||
if (rd.m_type == ProfilerRegister::PRT_TIME)
|
||||
{
|
||||
const FrameProfiler::FrameData& fd = rd.m_frames.back();
|
||||
if (fd.m_timeData.m_lastParent != nullptr)
|
||||
{
|
||||
FrameProfiler::ThreadData::RegistersMap::iterator parentIt = td.m_registers.find(fd.m_timeData.m_lastParent);
|
||||
AZ_Assert(parentIt != td.m_registers.end(), "We have a parent register that is not in our register map. This should not happen!");
|
||||
rd.m_lastParent = &parentIt->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
rd.m_lastParent = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// send an even to whomever cares
|
||||
EBUS_EVENT(FrameProfilerBus, OnFrameProfilerData, m_threads);
|
||||
}
|
||||
|
||||
int FrameProfilerComponent::GetTickOrder()
|
||||
{
|
||||
// Even it's not critical we should tick last to capture the current frame
|
||||
// so TICK_LAST (since it's not the last int +1 is a valid assumption)
|
||||
return TICK_LAST + 1;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ReadRegisterCallback
|
||||
// [12/5/2012]
|
||||
//=========================================================================
|
||||
bool FrameProfilerComponent::ReadProfilerRegisters(const ProfilerRegister& reg, const AZStd::thread_id& id)
|
||||
{
|
||||
if (m_currentThreadData == NULL || m_currentThreadData->m_id != id)
|
||||
{
|
||||
m_currentThreadData = NULL;
|
||||
|
||||
// find the thread and cache it, as we will received registers thread by thread... so we don't search.
|
||||
for (size_t i = 0; i < m_threads.size(); ++i)
|
||||
{
|
||||
FrameProfiler::ThreadData* td = &m_threads[i];
|
||||
if (td->m_id == id)
|
||||
{
|
||||
m_currentThreadData = td;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_currentThreadData == NULL)
|
||||
{
|
||||
m_threads.push_back();
|
||||
m_currentThreadData = &m_threads.back();
|
||||
m_currentThreadData->m_id = id;
|
||||
}
|
||||
}
|
||||
|
||||
const ProfilerRegister* profReg = ®
|
||||
FrameProfiler::ThreadData::RegistersMap::pair_iter_bool pairIterBool = m_currentThreadData->m_registers.insert_key(profReg);
|
||||
FrameProfiler::RegisterData& regData = pairIterBool.first->second;
|
||||
|
||||
// now update dynamic data with as little as possible computation (we must be fast)
|
||||
FrameProfiler::FrameData fd; // we can actually move this computation (FrameData and push) for later but we will need to use more memory
|
||||
fd.m_frameId = m_frameId;
|
||||
|
||||
if (pairIterBool.second)
|
||||
{
|
||||
// when insert copy the static data only once
|
||||
regData.m_name = profReg->m_name;
|
||||
regData.m_function = profReg->m_function;
|
||||
regData.m_line = profReg->m_line;
|
||||
regData.m_systemId = profReg->m_systemId;
|
||||
regData.m_frames.set_capacity(m_numFramesStored);
|
||||
regData.m_type = static_cast<ProfilerRegister::Type>(profReg->m_type);
|
||||
}
|
||||
|
||||
switch (regData.m_type)
|
||||
{
|
||||
case ProfilerRegister::PRT_TIME:
|
||||
{
|
||||
fd.m_timeData.m_time = profReg->m_timeData.m_time;
|
||||
fd.m_timeData.m_childrenTime = profReg->m_timeData.m_childrenTime;
|
||||
fd.m_timeData.m_calls = profReg->m_timeData.m_calls;
|
||||
fd.m_timeData.m_childrenCalls = profReg->m_timeData.m_childrenCalls;
|
||||
fd.m_timeData.m_lastParent = profReg->m_timeData.m_lastParent;
|
||||
} break;
|
||||
case ProfilerRegister::PRT_VALUE:
|
||||
{
|
||||
fd.m_userValues.m_value1 = profReg->m_userValues.m_value1;
|
||||
fd.m_userValues.m_value2 = profReg->m_userValues.m_value2;
|
||||
fd.m_userValues.m_value3 = profReg->m_userValues.m_value3;
|
||||
fd.m_userValues.m_value4 = profReg->m_userValues.m_value4;
|
||||
fd.m_userValues.m_value5 = profReg->m_userValues.m_value5;
|
||||
} break;
|
||||
}
|
||||
|
||||
regData.m_frames.push_back(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GetProvidedServices
|
||||
//=========================================================================
|
||||
void FrameProfilerComponent::GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC("FrameProfilerService", 0x05d1bb90));
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GetIncompatibleServices
|
||||
//=========================================================================
|
||||
void FrameProfilerComponent::GetIncompatibleServices(ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC("FrameProfilerService", 0x05d1bb90));
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GetDependentServices
|
||||
//=========================================================================
|
||||
void FrameProfilerComponent::GetDependentServices(ComponentDescriptor::DependencyArrayType& dependent)
|
||||
{
|
||||
dependent.push_back(AZ_CRC("MemoryService", 0x5c4d473c));
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Reflect
|
||||
//=========================================================================
|
||||
void FrameProfilerComponent::Reflect(ReflectContext* context)
|
||||
{
|
||||
if (SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<FrameProfilerComponent, AZ::Component>()
|
||||
->Version(1)
|
||||
->Field("numFramesStored", &FrameProfilerComponent::m_numFramesStored)
|
||||
->Field("pauseOnFrame", &FrameProfilerComponent::m_pauseOnFrame)
|
||||
;
|
||||
|
||||
if (EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<FrameProfilerComponent>(
|
||||
"Frame Profiler", "Performs per frame profiling (FPS counter, registers, etc.)")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Category, "Profiling")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
|
||||
->DataElement(AZ::Edit::UIHandlers::SpinBox, &FrameProfilerComponent::m_numFramesStored, "Number of Frames", "How many frames we will keep with the RUNTIME buffers.")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 1)
|
||||
->DataElement(AZ::Edit::UIHandlers::SpinBox, &FrameProfilerComponent::m_pauseOnFrame, "Pause on frame", "Paused the engine (debug break) on a specific frame. 0 means no pause!")
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Debug
|
||||
} // namespace AZ
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#ifndef AZCORE_FRAME_PROFILER_COMPONENT_H
|
||||
#define AZCORE_FRAME_PROFILER_COMPONENT_H
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/Debug/FrameProfiler.h>
|
||||
#include <AzCore/std/parallel/threadbus.h>
|
||||
#include <AzCore/Math/Crc.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Debug
|
||||
{
|
||||
/**
|
||||
* Frame profiler component provides a frame profiling information
|
||||
* (from FPS counter to profiler registers manipulation and so on).
|
||||
* It's a debug system so it should not be active in release
|
||||
*/
|
||||
class FrameProfilerComponent
|
||||
: public Component
|
||||
, public AZ::TickBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(AZ::Debug::FrameProfilerComponent, "{B81739EF-ED77-4F67-9D05-6ADF94F0431A}")
|
||||
|
||||
FrameProfilerComponent();
|
||||
virtual ~FrameProfilerComponent();
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Component base
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Tick bus
|
||||
void OnTick(float deltaTime, ScriptTimePoint time) override;
|
||||
int GetTickOrder() override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// \ref ComponentDescriptor::GetProvidedServices
|
||||
static void GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided);
|
||||
/// \ref ComponentDescriptor::GetIncompatibleServices
|
||||
static void GetIncompatibleServices(ComponentDescriptor::DependencyArrayType& incompatible);
|
||||
/// \ref ComponentDescriptor::GetDependentServices
|
||||
static void GetDependentServices(ComponentDescriptor::DependencyArrayType& dependent);
|
||||
/// \red ComponentDescriptor::Reflect
|
||||
static void Reflect(ReflectContext* reflection);
|
||||
|
||||
/// callback for reading profiler registers
|
||||
bool ReadProfilerRegisters(const ProfilerRegister& reg, const AZStd::thread_id& id);
|
||||
|
||||
// Keep in mind memory usage, increases quickly. Prefer remote tools (where the history is kept on the PC) instead of keeping long history
|
||||
unsigned int m_numFramesStored; ///< Number of frames that we will store in history buffers. >= 1
|
||||
unsigned int m_frameId; ///< Frame id (it's just counted from the start).
|
||||
|
||||
unsigned int m_pauseOnFrame; ///< Allows you to specify a frame the code will pause onto.
|
||||
|
||||
|
||||
FrameProfiler::ThreadDataArray m_threads; ///< Array with samplers for all threads
|
||||
FrameProfiler::ThreadData* m_currentThreadData; ///< Cached pointer to the last accessed thread data.
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // AZCORE_FRAME_PROFILER_COMPONENT_H
|
||||
#pragma once
|
||||
@@ -242,7 +242,9 @@ namespace AZ::Debug
|
||||
ThreadData* threadData = threadStorage.m_data;
|
||||
|
||||
// Set to nullptr so other threads doing a flush can't pick this up.
|
||||
while (!threadStorage.m_data.compare_exchange_strong(threadData, nullptr));
|
||||
while (!threadStorage.m_data.compare_exchange_strong(threadData, nullptr))
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t writeSize = AZ_SIZE_ALIGN_UP(sizeof(EventHeader) + size, EventBoundary);
|
||||
if (threadData->m_usedBytes + writeSize >= ThreadData::BufferSize)
|
||||
@@ -270,7 +272,9 @@ namespace AZ::Debug
|
||||
// swap the pending data to commit the event
|
||||
ThreadStorage& threadStorage = GetThreadStorage();
|
||||
ThreadData* expectedData = nullptr;
|
||||
while (!threadStorage.m_data.compare_exchange_strong(expectedData, threadStorage.m_pendingData));
|
||||
while (!threadStorage.m_data.compare_exchange_strong(expectedData, threadStorage.m_pendingData))
|
||||
{
|
||||
}
|
||||
threadStorage.m_pendingData = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,664 +7,4 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Debug/ProfilerDrillerBus.h>
|
||||
|
||||
#include <AzCore/std/containers/list.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
#include <AzCore/std/parallel/thread.h>
|
||||
#include <AzCore/std/parallel/shared_spin_mutex.h>
|
||||
#include <AzCore/std/parallel/lock.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
#include <AzCore/Math/Crc.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
uint32_t ProfileScope::GetSystemID(const char* system)
|
||||
{
|
||||
// TODO: stable ids for registered budgets
|
||||
return AZ::Crc32(system);
|
||||
}
|
||||
|
||||
namespace Debug
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Globals
|
||||
AZStd::chrono::microseconds ProfilerRegister::TimeData::s_startStopOverheadPer1000Calls(0);
|
||||
Profiler* Profiler::s_instance = nullptr;
|
||||
u64 Profiler::s_id = 0;
|
||||
int Profiler::s_useCount = 0;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Profile data stored per thread.
|
||||
*/
|
||||
struct ProfilerThreadData
|
||||
{
|
||||
static const int m_maxStackSize = 32;
|
||||
typedef AZStd::list<ProfilerRegister, OSStdAllocator> ProfilerRegisterList;
|
||||
typedef AZStd::fixed_vector<ProfilerSection*, m_maxStackSize> ProfilerSectionStack;
|
||||
|
||||
AZStd::thread::id m_id; ///< Thread id.
|
||||
ProfilerRegisterList m_registers; ///< Thread profiler registers (for this thread).
|
||||
mutable AZStd::shared_spin_mutex m_registersLock; ///< Lock for accessing thread profiler entries. Sadly the only reason for this to exists is so we can read safe the register counters.
|
||||
ProfilerSectionStack m_stack; ///< Current active sections stack.
|
||||
};
|
||||
|
||||
struct ProfilerSystemData
|
||||
{
|
||||
AZ::u32 m_id;
|
||||
const char* m_name;
|
||||
bool m_isActive;
|
||||
};
|
||||
|
||||
/**
|
||||
* Profiler class data (hidden in from the header file)
|
||||
*/
|
||||
struct ProfilerData
|
||||
{
|
||||
AZ_CLASS_ALLOCATOR(ProfilerData, OSAllocator, 0);
|
||||
|
||||
AZStd::fixed_vector<ProfilerThreadData, Profiler::m_maxNumberOfThreads> m_threads; ///< Array with thread with all belonging information.
|
||||
AZStd::shared_spin_mutex m_threadDataMutex; ///< Spin read/write lock (shared_mutex) for access to the m_threads.
|
||||
AZStd::fixed_vector<ProfilerSystemData, Profiler::m_maxNumberOfSystems> m_systems; ///< Array with systems (profiler/timer groups) that you can enable/disable.
|
||||
};
|
||||
|
||||
//=========================================================================
|
||||
// Profiler
|
||||
// [12/3/2012]
|
||||
//=========================================================================
|
||||
Profiler::Profiler(const Descriptor& desc)
|
||||
{
|
||||
(void)desc;
|
||||
m_data = aznew ProfilerData;
|
||||
|
||||
// we can periodically call this function (like the end of every frame to refresh the current estimation).
|
||||
ProfilerRegister::TimerComputeStartStopOverhead();
|
||||
|
||||
// use a timestamp as and id.
|
||||
s_id = AZStd::GetTimeUTCMilliSecond();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ~Profiler
|
||||
// [12/3/2012]
|
||||
//=========================================================================
|
||||
Profiler::~Profiler()
|
||||
{
|
||||
AZ_Assert(s_useCount == 0, "You deleted the profiler while it's still in use.");
|
||||
s_id = 0;
|
||||
delete m_data;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Create
|
||||
// [12/3/2012]
|
||||
//=========================================================================
|
||||
bool Profiler::Create(const Descriptor& desc)
|
||||
{
|
||||
AZ_Assert(s_instance == nullptr, "Profiler is already created!");
|
||||
if (s_instance != nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
s_instance = azcreate(Profiler, (desc), AZ::OSAllocator, "Profiler", 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Destroy
|
||||
// [12/3/2012]
|
||||
//=========================================================================
|
||||
void Profiler::Destroy()
|
||||
{
|
||||
AZ_Assert(s_instance != nullptr, "Profiler not created");
|
||||
if (s_instance)
|
||||
{
|
||||
azdestroy(s_instance, AZ::OSAllocator);
|
||||
s_instance = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// AddReference
|
||||
// [5/24/2013]
|
||||
//=========================================================================
|
||||
void Profiler::AddReference()
|
||||
{
|
||||
++s_useCount;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
//
|
||||
// [5/24/2013]
|
||||
//=========================================================================
|
||||
void Profiler::ReleaseReference()
|
||||
{
|
||||
AZ_Assert(s_useCount > 0, "Use count is already 0, you can't release it!");
|
||||
--s_useCount;
|
||||
if (s_useCount == 0)
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// RegisterSystem
|
||||
// [12/3/2012]
|
||||
//=========================================================================
|
||||
bool Profiler::RegisterSystem(AZ::u32 systemId, const char* name, bool isActive)
|
||||
{
|
||||
for (size_t i = 0; i < m_data->m_systems.size(); ++i)
|
||||
{
|
||||
if (m_data->m_systems[i].m_id == systemId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ProfilerSystemData sd;
|
||||
sd.m_id = systemId;
|
||||
sd.m_isActive = isActive;
|
||||
sd.m_name = name;
|
||||
m_data->m_systems.push_back(sd);
|
||||
return true;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// UnregisterSystem
|
||||
// [12/3/2012]
|
||||
//=========================================================================
|
||||
bool Profiler::UnregisterSystem(AZ::u32 systemId)
|
||||
{
|
||||
size_t i = 0;
|
||||
for (; i < m_data->m_systems.size(); ++i)
|
||||
{
|
||||
ProfilerSystemData& sd = m_data->m_systems[i];
|
||||
if (sd.m_id == systemId)
|
||||
{
|
||||
if (sd.m_isActive)
|
||||
{
|
||||
DeactivateSystem(sd.m_name);
|
||||
}
|
||||
// Make sure we triggest driller message when the m_threadDataMutex is NOT locked
|
||||
// as we lock them in reverse order when we update the profile driller.
|
||||
AZ_Assert(false, "Currently this code is unused. If we do use it, we should make call EBUS even outside of this function. Where m_threadDataMutex is NOT locked!");
|
||||
//EBUS_DBG_EVENT(ProfilerDrillerBus,OnUnregisterSystem,systemId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < m_data->m_systems.size())
|
||||
{
|
||||
m_data->m_systems.erase(m_data->m_systems.begin() + i);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ActivateSystem
|
||||
// [12/3/2012]
|
||||
//=========================================================================
|
||||
bool Profiler::SetSystemState(AZ::u32 systemId, bool isActive)
|
||||
{
|
||||
for (size_t i = 0; i < m_data->m_systems.size(); ++i)
|
||||
{
|
||||
ProfilerSystemData& sd = m_data->m_systems[i];
|
||||
if (sd.m_id == systemId)
|
||||
{
|
||||
if (sd.m_isActive != isActive)
|
||||
{
|
||||
sd.m_isActive = isActive;
|
||||
size_t numThreads = m_data->m_threads.size();
|
||||
for (size_t j = 0; j < numThreads; ++j)
|
||||
{
|
||||
ProfilerThreadData& data = m_data->m_threads[j];
|
||||
ProfilerThreadData::ProfilerRegisterList::iterator it = data.m_registers.begin();
|
||||
ProfilerThreadData::ProfilerRegisterList::iterator end = data.m_registers.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
ProfilerRegister& reg = *it;
|
||||
// This is a big question since this is the only writer
|
||||
// and the timers are readers and value should be read atomically (1 byte)
|
||||
// we should be safe without a synchronization here (as data should be written as we exit)
|
||||
// at worst we can put a volatile in front of the bool. Either way this should not cause
|
||||
// crashes or anything
|
||||
if (reg.m_systemId == systemId)
|
||||
{
|
||||
reg.m_isActive = isActive ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ActivateSystem
|
||||
// [5/24/2013]
|
||||
//=========================================================================
|
||||
void Profiler::ActivateSystem(const char* systemName)
|
||||
{
|
||||
AZ::u32 systemId = AZ::Crc32(systemName);
|
||||
bool isNewSystem = false;
|
||||
{
|
||||
AZStd::unique_lock<AZStd::shared_spin_mutex> writeLock(m_data->m_threadDataMutex);
|
||||
if (!SetSystemState(systemId, true))
|
||||
{
|
||||
// if the system is new add it
|
||||
RegisterSystem(systemId, systemName, true);
|
||||
isNewSystem = true;
|
||||
}
|
||||
}
|
||||
if (isNewSystem)
|
||||
{
|
||||
// Make sure we triggest driller message when the m_threadDataMutex is NOT locked
|
||||
// as we lock them in reverse order when we update the profile driller.
|
||||
EBUS_DBG_EVENT(ProfilerDrillerBus, OnRegisterSystem, systemId, systemName);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// DeactivateSystem
|
||||
// [5/24/2013]
|
||||
//=========================================================================
|
||||
void Profiler::DeactivateSystem(const char* systemName)
|
||||
{
|
||||
AZ::u32 systemId = AZ::Crc32(systemName);
|
||||
bool isNewSystem = false;
|
||||
{
|
||||
AZStd::unique_lock<AZStd::shared_spin_mutex> writeLock(m_data->m_threadDataMutex);
|
||||
if (!SetSystemState(systemId, false))
|
||||
{
|
||||
// if the system is new add it
|
||||
RegisterSystem(systemId, systemName, false);
|
||||
isNewSystem = true;
|
||||
}
|
||||
}
|
||||
if (isNewSystem)
|
||||
{
|
||||
// Make sure we triggest driller message when the m_threadDataMutex is NOT locked
|
||||
// as we lock them in reverse order when we update the profile driller.
|
||||
EBUS_DBG_EVENT(ProfilerDrillerBus, OnRegisterSystem, systemId, systemName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// IsSystemActive
|
||||
// [5/24/2013]
|
||||
//=========================================================================
|
||||
bool Profiler::IsSystemActive(const char* systemName) const
|
||||
{
|
||||
return IsSystemActive(AZ::Crc32(systemName));
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// IsSystemActive
|
||||
// [12/3/2012]
|
||||
//=========================================================================
|
||||
bool Profiler::IsSystemActive(AZ::u32 systemId) const
|
||||
{
|
||||
for (size_t i = 0; i < m_data->m_systems.size(); ++i)
|
||||
{
|
||||
if (m_data->m_systems[i].m_id == systemId)
|
||||
{
|
||||
return m_data->m_systems[i].m_isActive != 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GetNumberOfSystems
|
||||
// [12/3/2012]
|
||||
//=========================================================================
|
||||
int Profiler::GetNumberOfSystems() const
|
||||
{
|
||||
return static_cast<int>(m_data->m_systems.size());
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GetSystemName
|
||||
// [12/3/2012]
|
||||
//=========================================================================
|
||||
const char* Profiler::GetSystemName(int index) const
|
||||
{
|
||||
return m_data->m_systems[index].m_name;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// GetSystemName
|
||||
// [12/3/2012]
|
||||
//=========================================================================
|
||||
const char* Profiler::GetSystemName(AZ::u32 systemId) const
|
||||
{
|
||||
for (size_t i = 0; i < m_data->m_systems.size(); ++i)
|
||||
{
|
||||
if (m_data->m_systems[i].m_id == systemId)
|
||||
{
|
||||
return m_data->m_systems[i].m_name;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// RemoveThreadData
|
||||
// [12/3/2012]
|
||||
//=========================================================================
|
||||
void Profiler::RemoveThreadData(AZStd::thread_id id)
|
||||
{
|
||||
// this is very tricky we must be sure that thread is no longer operational
|
||||
// otherwise we will crash badly. We can do only because nobody should
|
||||
// reference this registers but the thread local data.
|
||||
AZStd::unique_lock<AZStd::shared_spin_mutex> writeLock(m_data->m_threadDataMutex);
|
||||
size_t numThreads = m_data->m_threads.size();
|
||||
ProfilerThreadData* threadData = NULL;
|
||||
for (size_t i = 0; i < numThreads; ++i)
|
||||
{
|
||||
ProfilerThreadData& data = m_data->m_threads[i];
|
||||
if (data.m_id == id)
|
||||
{
|
||||
threadData = &data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (threadData)
|
||||
{
|
||||
// delete all registers, we can remove the thread data too, but we will need to switch the structure to list
|
||||
// so far this is super minimal overhead, registers are more.
|
||||
threadData->m_registers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ReadRegisterValues
|
||||
// [12/3/2012]
|
||||
//=========================================================================
|
||||
void Profiler::ReadRegisterValues(const ReadProfileRegisterCB& callback, AZ::u32 systemFilter, const AZStd::thread_id* threadFilter) const
|
||||
{
|
||||
AZStd::shared_lock<AZStd::shared_spin_mutex> readLock(s_instance->m_data->m_threadDataMutex);
|
||||
size_t numThreads = Profiler::s_instance->m_data->m_threads.size();
|
||||
for (size_t i = 0; i < numThreads; ++i)
|
||||
{
|
||||
const ProfilerThreadData& data = s_instance->m_data->m_threads[i];
|
||||
if (threadFilter && *threadFilter != data.m_id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
{
|
||||
AZStd::shared_lock<AZStd::shared_spin_mutex> registersLock(data.m_registersLock);
|
||||
ProfilerThreadData::ProfilerRegisterList::const_iterator it = data.m_registers.begin();
|
||||
ProfilerThreadData::ProfilerRegisterList::const_iterator end = data.m_registers.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
const ProfilerRegister& reg = *it;
|
||||
if (!reg.m_isActive || (systemFilter != 0 && systemFilter != reg.m_systemId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!callback(reg, data.m_id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ResetRegisters
|
||||
// [12/4/2012]
|
||||
//=========================================================================
|
||||
void Profiler::ResetRegisters()
|
||||
{
|
||||
AZStd::unique_lock<AZStd::shared_spin_mutex> writeLock(s_instance->m_data->m_threadDataMutex);
|
||||
size_t numThreads = Profiler::s_instance->m_data->m_threads.size();
|
||||
for (size_t i = 0; i < numThreads; ++i)
|
||||
{
|
||||
ProfilerThreadData& data = s_instance->m_data->m_threads[i];
|
||||
{
|
||||
AZStd::unique_lock<AZStd::shared_spin_mutex> registersLock(data.m_registersLock);
|
||||
ProfilerThreadData::ProfilerRegisterList::iterator it = data.m_registers.begin();
|
||||
ProfilerThreadData::ProfilerRegisterList::iterator end = data.m_registers.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
ProfilerRegister& reg = *it;
|
||||
reg.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reset registers event
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// CreateRegister
|
||||
// [6/28/2013]
|
||||
//=========================================================================
|
||||
ProfilerRegister*
|
||||
ProfilerRegister::CreateRegister(const char* systemName, const char* name, const char* function, int line, ProfilerRegister::Type type)
|
||||
{
|
||||
static AZ_THREAD_LOCAL ProfilerThreadData* threadData = nullptr;
|
||||
static AZ_THREAD_LOCAL u64 profilerId = 0;
|
||||
if (profilerId != Profiler::s_id)
|
||||
{
|
||||
threadData = nullptr; // profiler has changed
|
||||
profilerId = Profiler::s_id;
|
||||
}
|
||||
AZ::u32 systemId = AZ::Crc32(systemName);
|
||||
ProfilerRegister* reg;
|
||||
{
|
||||
AZStd::unique_lock<AZStd::shared_spin_mutex> writeLock(Profiler::s_instance->m_data->m_threadDataMutex);
|
||||
|
||||
// make sure we have the system registered. This function will just return false if the system exists.
|
||||
if (systemName)
|
||||
{
|
||||
Profiler::s_instance->RegisterSystem(systemId, systemName, true);
|
||||
}
|
||||
|
||||
if (threadData == nullptr) // if this is a new thread add the data
|
||||
{
|
||||
AZStd::thread::id threadId = AZStd::this_thread::get_id();
|
||||
Profiler::s_instance->m_data->m_threads.push_back();
|
||||
threadData = &Profiler::s_instance->m_data->m_threads.back();
|
||||
threadData->m_id = threadId;
|
||||
}
|
||||
threadData->m_registers.push_back();
|
||||
reg = &threadData->m_registers.back();
|
||||
reg->m_name = name;
|
||||
reg->m_function = function;
|
||||
reg->m_line = line;
|
||||
reg->m_systemId = systemId;
|
||||
reg->m_isActive = Profiler::s_instance->IsSystemActive(systemId) ? 1 : 0;
|
||||
reg->m_type = type;
|
||||
reg->m_threadData = threadData;
|
||||
|
||||
reg->Reset();
|
||||
}
|
||||
// Make sure we triggest driller message when the m_threadDataMutex is NOT locked
|
||||
// as we lock them in reverse order when we update the profile driller.
|
||||
EBUS_DBG_EVENT(ProfilerDrillerBus, OnNewRegister, *reg, threadData->m_id);
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// TimerCreateAndStart
|
||||
// [11/30/2012]
|
||||
//=========================================================================
|
||||
ProfilerRegister*
|
||||
ProfilerRegister::TimerCreateAndStart(const char* systemName, const char* name, ProfilerSection * section, const char* function, int line)
|
||||
{
|
||||
AZStd::chrono::system_clock::time_point start = AZStd::chrono::system_clock::now();
|
||||
ProfilerRegister* reg = CreateRegister(systemName, name, function, line, ProfilerRegister::PRT_TIME);
|
||||
AZStd::chrono::system_clock::time_point end = AZStd::chrono::system_clock::now();
|
||||
|
||||
// adjust the parent timer with the overhead we incur during timer operations. (TODO with TLS this is so fast that we might not need to do it)
|
||||
if (!reg->m_threadData->m_stack.empty()) // if we are not he last element
|
||||
{
|
||||
AZStd::chrono::microseconds elapsed = end - start;
|
||||
reg->m_threadData->m_stack.back()->m_childTime += elapsed; // no need to check if we go in the future as this will happen on Stop
|
||||
}
|
||||
|
||||
if (reg->m_isActive)
|
||||
{
|
||||
section->m_register = reg;
|
||||
section->m_start = end;
|
||||
reg->m_threadData->m_stack.push_back(section);
|
||||
}
|
||||
else
|
||||
{
|
||||
section->m_register = nullptr;
|
||||
}
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ValueCreate
|
||||
// [6/28/2013]
|
||||
//=========================================================================
|
||||
ProfilerRegister*
|
||||
ProfilerRegister::ValueCreate(const char* systemName, const char* name, const char* function, int line)
|
||||
{
|
||||
return CreateRegister(systemName, name, function, line, ProfilerRegister::PRT_VALUE);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// TimerStart
|
||||
// [11/29/2012]
|
||||
//=========================================================================
|
||||
void ProfilerRegister::TimerStart(ProfilerSection* section)
|
||||
{
|
||||
ProfilerRegister* reg = this;
|
||||
|
||||
if (reg->m_isActive)
|
||||
{
|
||||
section->m_register = reg;
|
||||
reg->m_threadData->m_stack.push_back(section);
|
||||
section->m_start = AZStd::chrono::system_clock::now();
|
||||
}
|
||||
else
|
||||
{
|
||||
section->m_register = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// TimerStop
|
||||
// [11/29/2012]
|
||||
//=========================================================================
|
||||
void ProfilerRegister::TimerStop()
|
||||
{
|
||||
AZStd::chrono::system_clock::time_point end = AZStd::chrono::system_clock::now();
|
||||
ProfilerSection* section = m_threadData->m_stack.back();
|
||||
AZStd::chrono::microseconds elapsedTime = end - section->m_start;
|
||||
{
|
||||
m_threadData->m_registersLock.lock(); // lock for write
|
||||
++m_timeData.m_calls;
|
||||
m_timeData.m_time += elapsedTime.count();
|
||||
m_timeData.m_childrenTime += section->m_childTime.count();
|
||||
m_timeData.m_childrenCalls += section->m_childCalls;
|
||||
m_threadData->m_registersLock.unlock(); // unlock
|
||||
}
|
||||
m_threadData->m_stack.pop_back();
|
||||
|
||||
// adjust the parent timer with the overhead we incur during timer operations.
|
||||
if (!m_threadData->m_stack.empty())
|
||||
{
|
||||
ProfilerSection* parent = m_threadData->m_stack.back();
|
||||
m_timeData.m_lastParent = parent->m_register;
|
||||
parent->m_childTime += elapsedTime /*+ s_startStopOverhead*/; // add the overhead since most of it is in Stop()
|
||||
++parent->m_childCalls;
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Reset
|
||||
// [12/4/2012]
|
||||
//=========================================================================
|
||||
void ProfilerRegister::Reset()
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case PRT_TIME:
|
||||
{
|
||||
m_timeData.m_time = 0;
|
||||
m_timeData.m_childrenTime = 0;
|
||||
m_timeData.m_calls = 0;
|
||||
m_timeData.m_childrenCalls = 0;
|
||||
m_timeData.m_lastParent = nullptr;
|
||||
} break;
|
||||
case PRT_VALUE:
|
||||
{
|
||||
m_userValues.m_value1 = 0;
|
||||
m_userValues.m_value2 = 0;
|
||||
m_userValues.m_value3 = 0;
|
||||
m_userValues.m_value4 = 0;
|
||||
m_userValues.m_value5 = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ComputeStartStopOverhead
|
||||
// [12/3/2012]
|
||||
//=========================================================================
|
||||
void ProfilerRegister::TimerComputeStartStopOverhead()
|
||||
{
|
||||
// compute default thread start stop overhead
|
||||
ProfilerThreadData sampleThreadData;
|
||||
sampleThreadData.m_id = AZStd::this_thread::get_id();
|
||||
sampleThreadData.m_registers.push_back();
|
||||
ProfilerRegister& sampleRegister = sampleThreadData.m_registers.back();
|
||||
sampleRegister.m_isActive = true;
|
||||
sampleRegister.m_name = nullptr;
|
||||
sampleRegister.m_systemId = 0;
|
||||
sampleRegister.m_threadData = &sampleThreadData;
|
||||
|
||||
const int numSamples = 1000;
|
||||
for (int iRepetition = 0; iRepetition < 1000; ++iRepetition) // just for test
|
||||
{
|
||||
ProfilerSection section;
|
||||
sampleRegister.TimerStart(§ion);
|
||||
AZStd::chrono::system_clock::time_point start = AZStd::chrono::system_clock::now();
|
||||
for (int i = 0; i < numSamples; ++i)
|
||||
{
|
||||
static AZ::Debug::ProfilerRegister* sampleRegisterPtr = &sampleRegister; // the creation is timed differently
|
||||
ProfilerSection subSection;
|
||||
if (sampleRegisterPtr != NULL)
|
||||
{
|
||||
sampleRegister.TimerStart(&subSection);
|
||||
}
|
||||
}
|
||||
AZStd::chrono::microseconds elapsed = (AZStd::chrono::system_clock::now() - start);
|
||||
if (TimeData::s_startStopOverheadPer1000Calls.count() == 0) // if first time set otherwise smooth average
|
||||
{
|
||||
TimeData::s_startStopOverheadPer1000Calls = elapsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
float fNew = static_cast<float>(elapsed.count());
|
||||
float fCurrent = static_cast<float>(TimeData::s_startStopOverheadPer1000Calls.count());
|
||||
int deltaValue = static_cast<int>((fNew - fCurrent) * 0.1f);
|
||||
if (deltaValue < 0)
|
||||
{
|
||||
TimeData::s_startStopOverheadPer1000Calls -= AZStd::chrono::microseconds(-deltaValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
TimeData::s_startStopOverheadPer1000Calls += AZStd::chrono::microseconds(deltaValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
//AZ_TracePrintf("Profiler","Overhead %d microseconds per 1000 profile calls!\n",TimeData::s_startStopOverheadPer1000Calls.count());
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace AZ
|
||||
|
||||
@@ -7,42 +7,49 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/chrono/chrono.h>
|
||||
#include <AzCore/std/function/function_fwd.h>
|
||||
#include <AzCore/Debug/Budget.h>
|
||||
|
||||
#ifdef USE_PIX
|
||||
#include <AzCore/PlatformIncl.h>
|
||||
#include <WinPixEventRuntime/pix3.h>
|
||||
#endif
|
||||
|
||||
#if defined(AZ_PROFILER_MACRO_DISABLE) // by default we never disable the profiler registers as their overhead should be minimal, you can still do that for your code though.
|
||||
# define AZ_PROFILE_SCOPE(...)
|
||||
# define AZ_PROFILE_FUNCTION(...)
|
||||
# define AZ_PROFILE_BEGIN(...)
|
||||
# define AZ_PROFILE_END(...)
|
||||
#if defined(AZ_PROFILER_MACRO_DISABLE) // by default we never disable the profiler registers as their overhead should be minimal, you can
|
||||
// still do that for your code though.
|
||||
#define AZ_PROFILE_SCOPE(...)
|
||||
#define AZ_PROFILE_FUNCTION(...)
|
||||
#define AZ_PROFILE_BEGIN(...)
|
||||
#define AZ_PROFILE_END(...)
|
||||
#else
|
||||
|
||||
/**
|
||||
* Macro to declare a profile section for the current scope { }.
|
||||
* format is: AZ_PROFILE_SCOPE(categoryName, const char* formatStr, ...)
|
||||
*/
|
||||
# define AZ_PROFILE_SCOPE(category, ...) ::AZ::ProfileScope AZ_JOIN(azProfileScope, __LINE__){ #category, __VA_ARGS__ }
|
||||
# define AZ_PROFILE_FUNCTION(category) AZ_PROFILE_SCOPE(category, AZ_FUNCTION_SIGNATURE)
|
||||
#define AZ_PROFILE_SCOPE(budget, ...) \
|
||||
::AZ::Debug::ProfileScope AZ_JOIN(azProfileScope, __LINE__) \
|
||||
{ \
|
||||
AZ_BUDGET_GETTER(budget)(), __VA_ARGS__ \
|
||||
}
|
||||
|
||||
#define AZ_PROFILE_FUNCTION(category) AZ_PROFILE_SCOPE(category, AZ_FUNCTION_SIGNATURE)
|
||||
|
||||
// Prefer using the scoped macros which automatically end the event (AZ_PROFILE_SCOPE/AZ_PROFILE_FUNCTION)
|
||||
# define AZ_PROFILE_BEGIN(category, ...) ::AZ::ProfileScope::BeginRegion(#category, __VA_ARGS__)
|
||||
# define AZ_PROFILE_END() ::AZ::ProfileScope::EndRegion()
|
||||
#define AZ_PROFILE_BEGIN(budget, ...) ::AZ::Debug::ProfileScope::BeginRegion(AZ_BUDGET_GETTER(budget)(), __VA_ARGS__)
|
||||
#define AZ_PROFILE_END(budget) ::AZ::Debug::ProfileScope::EndRegion(AZ_BUDGET_GETTER(budget)())
|
||||
|
||||
#endif // AZ_PROFILER_MACRO_DISABLE
|
||||
|
||||
#ifndef AZ_PROFILE_INTERVAL_START
|
||||
# define AZ_PROFILE_INTERVAL_START(...)
|
||||
# define AZ_PROFILE_INTERVAL_START_COLORED(...)
|
||||
# define AZ_PROFILE_INTERVAL_END(...)
|
||||
# define AZ_PROFILE_INTERVAL_SCOPED(...)
|
||||
#define AZ_PROFILE_INTERVAL_START(...)
|
||||
#define AZ_PROFILE_INTERVAL_START_COLORED(...)
|
||||
#define AZ_PROFILE_INTERVAL_END(...)
|
||||
#define AZ_PROFILE_INTERVAL_SCOPED(...)
|
||||
#endif
|
||||
|
||||
#ifndef AZ_PROFILE_DATAPOINT
|
||||
# define AZ_PROFILE_DATAPOINT(...)
|
||||
# define AZ_PROFILE_DATAPOINT_PERCENT(...)
|
||||
#define AZ_PROFILE_DATAPOINT(...)
|
||||
#define AZ_PROFILE_DATAPOINT_PERCENT(...)
|
||||
#endif
|
||||
|
||||
namespace AZStd
|
||||
@@ -50,344 +57,24 @@ namespace AZStd
|
||||
struct thread_id; // forward declare. This is the same type as AZStd::thread::id
|
||||
}
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::Debug
|
||||
{
|
||||
class ProfileScope
|
||||
{
|
||||
public:
|
||||
static uint32_t GetSystemID(const char* system);
|
||||
template<typename... T>
|
||||
static void BeginRegion([[maybe_unused]] Budget* budget, [[maybe_unused]] const char* eventName, [[maybe_unused]] T const&... args);
|
||||
|
||||
static void EndRegion([[maybe_unused]] Budget* budget);
|
||||
|
||||
template<typename... T>
|
||||
static void BeginRegion([[maybe_unused]] const char* system, [[maybe_unused]] const char* eventName, [[maybe_unused]] T const&... args)
|
||||
{
|
||||
// TODO: Verification that the supplied system name corresponds to a known budget
|
||||
#if defined(USE_PIX)
|
||||
PIXBeginEvent(PIX_COLOR_INDEX(GetSystemID(system) & 0xff), eventName, args...);
|
||||
#endif
|
||||
// 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
|
||||
}
|
||||
ProfileScope(Budget* budget, char const* eventName, T const&... args);
|
||||
|
||||
static void EndRegion()
|
||||
{
|
||||
#if defined(USE_PIX)
|
||||
PIXEndEvent();
|
||||
#endif
|
||||
}
|
||||
~ProfileScope();
|
||||
|
||||
template<typename... T>
|
||||
ProfileScope(const char* system, char const* eventName, T const&... args)
|
||||
{
|
||||
BeginRegion(system, eventName, args...);
|
||||
}
|
||||
|
||||
~ProfileScope()
|
||||
{
|
||||
EndRegion();
|
||||
}
|
||||
private:
|
||||
Budget* m_budget;
|
||||
};
|
||||
} // namespace AZ::Debug
|
||||
|
||||
namespace Debug
|
||||
{
|
||||
class ProfilerSection;
|
||||
class ProfilerRegister;
|
||||
struct ProfilerThreadData;
|
||||
struct ProfilerData;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Profiler
|
||||
{
|
||||
friend class ProfilerRegister;
|
||||
friend struct ProfilerData;
|
||||
public:
|
||||
/// Max number of threads supported by the profiler.
|
||||
static const int m_maxNumberOfThreads = 32;
|
||||
/// Max number of systems supported by the profiler. (We can switch this container if needed)
|
||||
static const int m_maxNumberOfSystems = 64;
|
||||
|
||||
~Profiler();
|
||||
|
||||
struct Descriptor
|
||||
{
|
||||
};
|
||||
|
||||
static bool Create(const Descriptor& desc = Descriptor());
|
||||
static void Destroy();
|
||||
static bool IsReady() { return s_instance != NULL; }
|
||||
static Profiler& Instance() { return *s_instance; }
|
||||
static u64 GetId() { return s_id; }
|
||||
|
||||
/// Increment the use count.
|
||||
static void AddReference();
|
||||
/// Release the use count if 0 a Destroy will be called automatically.
|
||||
static void ReleaseReference();
|
||||
|
||||
void ActivateSystem(const char* systemName);
|
||||
void DeactivateSystem(const char* systemName);
|
||||
bool IsSystemActive(const char* systemName) const;
|
||||
bool IsSystemActive(AZ::u32 systemId) const;
|
||||
int GetNumberOfSystems() const;
|
||||
const char* GetSystemName(int index) const;
|
||||
const char* GetSystemName(AZ::u32 systemId) const;
|
||||
|
||||
/** Callback to read a single register. Make sure you read the data as fast as possible. Don't compute inside the callback
|
||||
* it will lock and hold all the registers that we process. The best is just to read the value and push it into a
|
||||
* history buffer.
|
||||
*/
|
||||
typedef AZStd::function<bool (const ProfilerRegister&, const AZStd::thread_id&)> ReadProfileRegisterCB;
|
||||
/**
|
||||
* Read register values, make sure the code here is fast and efficient as we are holding a lock.
|
||||
* provide a callback that will be called for each register.
|
||||
* You can choose to filter your values by thread or a system. Use this filter only to narrow you samples. Don't
|
||||
* use it for multiple calls to sort your counters, use the history data.
|
||||
* It addition keep in mind that you can run this function is parallel, as we only read the values.
|
||||
*/
|
||||
void ReadRegisterValues(const ReadProfileRegisterCB& callback, AZ::u32 systemFilter = 0, const AZStd::thread_id* threadFilter = NULL) const;
|
||||
/**
|
||||
* This is slow operation that will cause contention try to avoid using it. A better way will be each frame instead of reset to read and store
|
||||
* register values (this is good for history too) and make the difference that way.
|
||||
*/
|
||||
void ResetRegisters();
|
||||
|
||||
/// You can remove thread data ONLY IF YOU ARE SURE THIS THREAD IS NO LONGER ACTIVE! This will work only is specific cases.
|
||||
void RemoveThreadData(AZStd::thread_id id);
|
||||
|
||||
private:
|
||||
/// Register a new system in the profiler. Make sure the proper locks are LOCKED when calling this function (m_threadDataMutex)
|
||||
bool RegisterSystem(AZ::u32 systemId, const char* name, bool isActive);
|
||||
/// Unregister a system. Make sure the proper locks are LOCKED when calling this function (m_threadDataMutex)
|
||||
bool UnregisterSystem(AZ::u32 systemId);
|
||||
/// Sets the system active/inactive state. Make sure the proper locks are LOCKED when calling this function (m_threadDataMutex)
|
||||
bool SetSystemState(AZ::u32 systemId, bool isActive);
|
||||
|
||||
Profiler(const Descriptor& desc);
|
||||
Profiler& operator=(const Profiler&);
|
||||
|
||||
ProfilerData* m_data; ///< Hidden data to reduce the number of header files included;
|
||||
static Profiler* s_instance; ///< The only instance of the profiler.
|
||||
static u64 s_id; ///< Profiler unique (over time) id (don't use the pointer as it might be reused).
|
||||
static int s_useCount;
|
||||
};
|
||||
|
||||
/**
|
||||
* A profiler "virtual" register that contains data about a certain place in the code.
|
||||
*/
|
||||
class ProfilerRegister
|
||||
{
|
||||
friend class Profiler;
|
||||
public:
|
||||
ProfilerRegister()
|
||||
{}
|
||||
|
||||
enum Type
|
||||
{
|
||||
PRT_TIME = 0, ///< Time (members m_time,m_childrenTime,m_calls, m_childrenCalls and m_lastParant are used) register.
|
||||
PRT_VALUE, ///< Value register
|
||||
};
|
||||
|
||||
/// Time register data.
|
||||
struct TimeData
|
||||
{
|
||||
AZ::u64 m_time; ///< Total inclusive time current and children in microseconds.
|
||||
AZ::u64 m_childrenTime; ///< Time taken by child profilers in microseconds.
|
||||
AZ::s64 m_calls; ///< Number of calls for this register.
|
||||
AZ::s64 m_childrenCalls;///< Number of children calls.
|
||||
ProfilerRegister* m_lastParent; ///< Pointer to the last parent register.
|
||||
|
||||
static AZStd::chrono::microseconds s_startStopOverheadPer1000Calls; ///< Static constant representing a standard start stop overhead per 1000 calls. You can use this to adjust timings.
|
||||
};
|
||||
|
||||
/// Value register data.
|
||||
struct ValuesData
|
||||
{
|
||||
AZ::s64 m_value1;
|
||||
AZ::s64 m_value2;
|
||||
AZ::s64 m_value3;
|
||||
AZ::s64 m_value4;
|
||||
AZ::s64 m_value5;
|
||||
};
|
||||
|
||||
static ProfilerRegister* TimerCreateAndStart(const char* systemName, const char* name, ProfilerSection* section, const char* function, int line);
|
||||
static ProfilerRegister* ValueCreate(const char* systemName, const char* name, const char* function, int line);
|
||||
void TimerStart(ProfilerSection* section);
|
||||
|
||||
void ValueSet(const AZ::s64& v1);
|
||||
void ValueSet(const AZ::s64& v1, const AZ::s64& v2);
|
||||
void ValueSet(const AZ::s64& v1, const AZ::s64& v2, const AZ::s64& v3);
|
||||
void ValueSet(const AZ::s64& v1, const AZ::s64& v2, const AZ::s64& v3, const AZ::s64& v4);
|
||||
void ValueSet(const AZ::s64& v1, const AZ::s64& v2, const AZ::s64& v3, const AZ::s64& v4, const AZ::s64& v5);
|
||||
|
||||
void ValueAdd(const AZ::s64& v1);
|
||||
void ValueAdd(const AZ::s64& v1, const AZ::s64& v2);
|
||||
void ValueAdd(const AZ::s64& v1, const AZ::s64& v2, const AZ::s64& v3);
|
||||
void ValueAdd(const AZ::s64& v1, const AZ::s64& v2, const AZ::s64& v3, const AZ::s64& v4);
|
||||
void ValueAdd(const AZ::s64& v1, const AZ::s64& v2, const AZ::s64& v3, const AZ::s64& v4, const AZ::s64& v5);
|
||||
|
||||
// Dynamic register data
|
||||
union
|
||||
{
|
||||
TimeData m_timeData;
|
||||
ValuesData m_userValues;
|
||||
};
|
||||
|
||||
// Static value data.
|
||||
const char* m_name; ///< Name of the profiler register.
|
||||
const char* m_function; ///< Function name in the code.
|
||||
int m_line; ///< Line number if the code.
|
||||
AZ::u32 m_systemId; ///< ID of the system this profiler belongs to.
|
||||
unsigned char m_type : 7; ///< Register type
|
||||
unsigned char m_isActive : 1; ///< Flag if the profiler is active.
|
||||
|
||||
private:
|
||||
friend class ProfilerSection;
|
||||
|
||||
static ProfilerRegister* CreateRegister(const char* systemName, const char* name, const char* function, int line, ProfilerRegister::Type type);
|
||||
|
||||
/// Compute static start/stop overhead approximation. You can call this periodically (or not) to update the overhead.
|
||||
static void TimerComputeStartStopOverhead();
|
||||
|
||||
void TimerStop();
|
||||
|
||||
void Reset();
|
||||
|
||||
ProfilerRegister* GetValueRegisterForThisThread();
|
||||
|
||||
ProfilerThreadData* m_threadData; ///< Pointer to this entry thread data.
|
||||
};
|
||||
|
||||
/**
|
||||
* Scoped stop register count on destruction.
|
||||
*/
|
||||
class ProfilerSection
|
||||
{
|
||||
friend class ProfilerRegister;
|
||||
public:
|
||||
ProfilerSection()
|
||||
: m_register(nullptr)
|
||||
, m_profilerId(AZ::Debug::Profiler::GetId())
|
||||
, m_childTime(0)
|
||||
, m_childCalls(0)
|
||||
{}
|
||||
|
||||
~ProfilerSection()
|
||||
{
|
||||
// If we have a valid register and the profiler did not change while we were active stop the register.
|
||||
if (m_register && m_profilerId == AZ::Debug::Profiler::GetId())
|
||||
{
|
||||
m_register->TimerStop();
|
||||
}
|
||||
}
|
||||
|
||||
void Stop()
|
||||
{
|
||||
// If we have a valid register and the profiler did not change while we were active stop the register.
|
||||
if (m_register && m_profilerId == AZ::Debug::Profiler::GetId())
|
||||
{
|
||||
m_register->TimerStop();
|
||||
}
|
||||
m_register = nullptr;
|
||||
}
|
||||
private:
|
||||
ProfilerRegister* m_register; ///< Pointer to the owning profiler register.
|
||||
u64 m_profilerId; ///< Id of the profiler when we started this section.
|
||||
AZStd::chrono::system_clock::time_point m_start; ///< Start mark.
|
||||
AZStd::chrono::microseconds m_childTime; ///< Time spent in child profilers.
|
||||
int m_childCalls; ///< Number of children calls.
|
||||
};
|
||||
|
||||
AZ_FORCE_INLINE ProfilerRegister* ProfilerRegister::GetValueRegisterForThisThread()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE void ProfilerRegister::ValueSet(const AZ::s64& v1)
|
||||
{
|
||||
ProfilerRegister* reg = GetValueRegisterForThisThread();
|
||||
reg->m_userValues.m_value1 = v1;
|
||||
}
|
||||
AZ_FORCE_INLINE void ProfilerRegister::ValueSet(const AZ::s64& v1, const AZ::s64& v2)
|
||||
{
|
||||
ProfilerRegister* reg = GetValueRegisterForThisThread();
|
||||
reg->m_userValues.m_value1 = v1;
|
||||
reg->m_userValues.m_value2 = v2;
|
||||
}
|
||||
AZ_FORCE_INLINE void ProfilerRegister::ValueSet(const AZ::s64& v1, const AZ::s64& v2, const AZ::s64& v3)
|
||||
{
|
||||
ProfilerRegister* reg = GetValueRegisterForThisThread();
|
||||
reg->m_userValues.m_value1 = v1;
|
||||
reg->m_userValues.m_value2 = v2;
|
||||
reg->m_userValues.m_value3 = v3;
|
||||
}
|
||||
AZ_FORCE_INLINE void ProfilerRegister::ValueSet(const AZ::s64& v1, const AZ::s64& v2, const AZ::s64& v3, const AZ::s64& v4)
|
||||
{
|
||||
ProfilerRegister* reg = GetValueRegisterForThisThread();
|
||||
reg->m_userValues.m_value1 = v1;
|
||||
reg->m_userValues.m_value2 = v2;
|
||||
reg->m_userValues.m_value3 = v3;
|
||||
reg->m_userValues.m_value4 = v4;
|
||||
}
|
||||
AZ_FORCE_INLINE void ProfilerRegister::ValueSet(const AZ::s64& v1, const AZ::s64& v2, const AZ::s64& v3, const AZ::s64& v4, const AZ::s64& v5)
|
||||
{
|
||||
ProfilerRegister* reg = GetValueRegisterForThisThread();
|
||||
reg->m_userValues.m_value1 = v1;
|
||||
reg->m_userValues.m_value2 = v2;
|
||||
reg->m_userValues.m_value3 = v3;
|
||||
reg->m_userValues.m_value4 = v4;
|
||||
reg->m_userValues.m_value5 = v5;
|
||||
}
|
||||
AZ_FORCE_INLINE void ProfilerRegister::ValueAdd(const AZ::s64& v1)
|
||||
{
|
||||
ProfilerRegister* reg = GetValueRegisterForThisThread();
|
||||
reg->m_userValues.m_value1 += v1;
|
||||
}
|
||||
AZ_FORCE_INLINE void ProfilerRegister::ValueAdd(const AZ::s64& v1, const AZ::s64& v2)
|
||||
{
|
||||
ProfilerRegister* reg = GetValueRegisterForThisThread();
|
||||
reg->m_userValues.m_value1 += v1;
|
||||
reg->m_userValues.m_value2 += v2;
|
||||
}
|
||||
AZ_FORCE_INLINE void ProfilerRegister::ValueAdd(const AZ::s64& v1, const AZ::s64& v2, const AZ::s64& v3)
|
||||
{
|
||||
ProfilerRegister* reg = GetValueRegisterForThisThread();
|
||||
reg->m_userValues.m_value1 += v1;
|
||||
reg->m_userValues.m_value2 += v2;
|
||||
reg->m_userValues.m_value3 += v3;
|
||||
}
|
||||
AZ_FORCE_INLINE void ProfilerRegister::ValueAdd(const AZ::s64& v1, const AZ::s64& v2, const AZ::s64& v3, const AZ::s64& v4)
|
||||
{
|
||||
ProfilerRegister* reg = GetValueRegisterForThisThread();
|
||||
reg->m_userValues.m_value1 += v1;
|
||||
reg->m_userValues.m_value2 += v2;
|
||||
reg->m_userValues.m_value3 += v3;
|
||||
reg->m_userValues.m_value4 += v4;
|
||||
}
|
||||
AZ_FORCE_INLINE void ProfilerRegister::ValueAdd(const AZ::s64& v1, const AZ::s64& v2, const AZ::s64& v3, const AZ::s64& v4, const AZ::s64& v5)
|
||||
{
|
||||
ProfilerRegister* reg = GetValueRegisterForThisThread();
|
||||
reg->m_userValues.m_value1 += v1;
|
||||
reg->m_userValues.m_value2 += v2;
|
||||
reg->m_userValues.m_value3 += v3;
|
||||
reg->m_userValues.m_value4 += v4;
|
||||
reg->m_userValues.m_value5 += v5;
|
||||
}
|
||||
} // namespace Debug
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
struct RegisterData
|
||||
{
|
||||
AZ::Debug::ProfilerRegister* m_register; ///< Pointer to the register data.
|
||||
AZ::u64 m_profilerId; ///< Profiler ID which create the \ref register data.
|
||||
};
|
||||
}
|
||||
} // namespace AZ
|
||||
|
||||
#ifdef USE_PIX
|
||||
// The pix3 header unfortunately brings in other Windows macros we need to undef
|
||||
#undef DeleteFile
|
||||
#undef LoadImage
|
||||
#undef GetCurrentTime
|
||||
#endif
|
||||
#include <AzCore/Debug/Profiler.inl>
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
namespace AZ::Debug
|
||||
{
|
||||
template<typename... T>
|
||||
void ProfileScope::BeginRegion(
|
||||
[[maybe_unused]] Budget* budget, [[maybe_unused]] const char* eventName, [[maybe_unused]] T const&... args)
|
||||
{
|
||||
if (!budget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#if !defined(_RELEASE)
|
||||
// TODO: Verification that the supplied system name corresponds to a known budget
|
||||
#if defined(USE_PIX)
|
||||
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
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void ProfileScope::EndRegion([[maybe_unused]] Budget* budget)
|
||||
{
|
||||
if (!budget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#if !defined(_RELEASE)
|
||||
budget->EndProfileRegion();
|
||||
#if defined(USE_PIX)
|
||||
PIXEndEvent();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
ProfileScope::ProfileScope(Budget* budget, char const* eventName, T const&... args)
|
||||
: m_budget{ budget }
|
||||
{
|
||||
BeginRegion(budget, eventName, args...);
|
||||
}
|
||||
|
||||
inline ProfileScope::~ProfileScope()
|
||||
{
|
||||
EndRegion(m_budget);
|
||||
}
|
||||
|
||||
} // namespace AZ::Debug
|
||||
@@ -1,310 +0,0 @@
|
||||
/*
|
||||
* 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/Debug/ProfilerDriller.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Math/Crc.h>
|
||||
|
||||
#include <AzCore/std/parallel/thread.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
#include <AzCore/std/bind/bind.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Debug
|
||||
{
|
||||
//=========================================================================
|
||||
// ProfilerDriller
|
||||
// [7/9/2013]
|
||||
//=========================================================================
|
||||
ProfilerDriller::ProfilerDriller()
|
||||
{
|
||||
AZStd::ThreadDrillerEventBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ~ProfilerDriller
|
||||
// [7/9/2013]
|
||||
//=========================================================================
|
||||
ProfilerDriller::~ProfilerDriller()
|
||||
{
|
||||
AZStd::ThreadDrillerEventBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Start
|
||||
// [5/24/2013]
|
||||
//=========================================================================
|
||||
void ProfilerDriller::Start(const Param* params, int numParams)
|
||||
{
|
||||
for (int i = 0; i < m_numberOfSystemFilters; ++i)
|
||||
{
|
||||
m_systemFilters[i].desc = "SystemID of the system which counters we are interested in";
|
||||
m_systemFilters[i].type = Param::PT_INT;
|
||||
m_systemFilters[i].value = 0;
|
||||
}
|
||||
|
||||
// Copy valid filters.
|
||||
m_numberOfValidFilters = 0;
|
||||
if (params)
|
||||
{
|
||||
for (int i = 0; i < numParams; ++i)
|
||||
{
|
||||
if (params[i].type == Param::PT_INT && params[i].value != 0)
|
||||
{
|
||||
m_systemFilters[m_numberOfValidFilters++].value = params[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// output current threads
|
||||
for (ThreadArrayType::iterator it = m_threads.begin(); it != m_threads.end(); ++it)
|
||||
{
|
||||
OutputThreadEnter(*it);
|
||||
}
|
||||
|
||||
ProfilerDrillerBus::Handler::BusConnect();
|
||||
|
||||
if (!Profiler::IsReady())
|
||||
{
|
||||
Profiler::Create();
|
||||
}
|
||||
|
||||
Profiler::AddReference();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Stop
|
||||
// [5/24/2013]
|
||||
//=========================================================================
|
||||
void ProfilerDriller::Stop()
|
||||
{
|
||||
Profiler::ReleaseReference();
|
||||
ProfilerDrillerBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// OnError
|
||||
// [2/8/2013]
|
||||
//=========================================================================
|
||||
void ProfilerDriller::Update()
|
||||
{
|
||||
// \note We could add thread_id in addition to the System ID, but I can't foresee many cases where we would like to profile only a specific thread.
|
||||
if (m_numberOfValidFilters)
|
||||
{
|
||||
for (int iFilter = 0; iFilter < m_numberOfValidFilters; ++iFilter)
|
||||
{
|
||||
AZ::u32 systemFilter = *reinterpret_cast<AZ::u32*>(&m_systemFilters[iFilter].value);
|
||||
Profiler::Instance().ReadRegisterValues(AZStd::bind(&ProfilerDriller::ReadProfilerRegisters, this, AZStd::placeholders::_1, AZStd::placeholders::_2), systemFilter);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Profiler::Instance().ReadRegisterValues(AZStd::bind(&ProfilerDriller::ReadProfilerRegisters, this, AZStd::placeholders::_1, AZStd::placeholders::_2), 0);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ReadProfilerRegisters
|
||||
// [2/11/2013]
|
||||
//=========================================================================
|
||||
bool ProfilerDriller::ReadProfilerRegisters(const ProfilerRegister& reg, const AZStd::thread_id& id)
|
||||
{
|
||||
(void)id;
|
||||
m_output->BeginTag(AZ_CRC("ProfilerDriller", 0x172c5268));
|
||||
m_output->BeginTag(AZ_CRC("UpdateRegister", 0x6c00b890));
|
||||
m_output->Write(AZ_CRC("Id", 0xbf396750), ®);
|
||||
// Send only the data which is changing
|
||||
switch (reg.m_type)
|
||||
{
|
||||
case ProfilerRegister::PRT_TIME:
|
||||
{
|
||||
m_output->Write(AZ_CRC("Time", 0x6f949845), reg.m_timeData.m_time);
|
||||
m_output->Write(AZ_CRC("ChildrenTime", 0x46162d3f), reg.m_timeData.m_childrenTime);
|
||||
m_output->Write(AZ_CRC("Calls", 0xdaa35c8f), reg.m_timeData.m_calls);
|
||||
m_output->Write(AZ_CRC("ChildrenCalls", 0x6a5a4618), reg.m_timeData.m_childrenCalls);
|
||||
m_output->Write(AZ_CRC("ParentId", 0x856a684c), reg.m_timeData.m_lastParent);
|
||||
} break;
|
||||
case ProfilerRegister::PRT_VALUE:
|
||||
{
|
||||
m_output->Write(AZ_CRC("Value1", 0xa2756c5a), reg.m_userValues.m_value1);
|
||||
m_output->Write(AZ_CRC("Value2", 0x3b7c3de0), reg.m_userValues.m_value2);
|
||||
m_output->Write(AZ_CRC("Value3", 0x4c7b0d76), reg.m_userValues.m_value3);
|
||||
m_output->Write(AZ_CRC("Value4", 0xd21f98d5), reg.m_userValues.m_value4);
|
||||
m_output->Write(AZ_CRC("Value5", 0xa518a843), reg.m_userValues.m_value5);
|
||||
} break;
|
||||
}
|
||||
m_output->EndTag(AZ_CRC("UpdateRegister", 0x6c00b890));
|
||||
m_output->EndTag(AZ_CRC("ProfilerDriller", 0x172c5268));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// OnThreadEnter
|
||||
// [5/31/2013]
|
||||
//=========================================================================
|
||||
void ProfilerDriller::OnThreadEnter(const AZStd::thread_id& id, const AZStd::thread_desc* desc)
|
||||
{
|
||||
m_threads.push_back();
|
||||
ThreadInfo& info = m_threads.back();
|
||||
info.m_id = (size_t)id.m_id;
|
||||
if (desc)
|
||||
{
|
||||
info.m_name = desc->m_name;
|
||||
info.m_cpuId = desc->m_cpuId;
|
||||
info.m_priority = desc->m_priority;
|
||||
info.m_stackSize = desc->m_stackSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.m_name = nullptr;
|
||||
info.m_cpuId = -1;
|
||||
info.m_priority = -100000;
|
||||
info.m_stackSize = 0;
|
||||
}
|
||||
|
||||
if (m_output)
|
||||
{
|
||||
OutputThreadEnter(info);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// OnThreadExit
|
||||
// [5/31/2013]
|
||||
//=========================================================================
|
||||
void ProfilerDriller::OnThreadExit(const AZStd::thread_id& id)
|
||||
{
|
||||
ThreadArrayType::iterator it = m_threads.begin();
|
||||
while (it != m_threads.end())
|
||||
{
|
||||
if (it->m_id == (size_t)id.m_id)
|
||||
{
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
if (it != m_threads.end())
|
||||
{
|
||||
if (m_output)
|
||||
{
|
||||
OutputThreadExit(*it);
|
||||
}
|
||||
|
||||
m_threads.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// OutputThreadEnter
|
||||
// [7/9/2013]
|
||||
//=========================================================================
|
||||
void ProfilerDriller::OutputThreadEnter(const ThreadInfo& threadInfo)
|
||||
{
|
||||
m_output->BeginTag(AZ_CRC("ProfilerDriller", 0x172c5268));
|
||||
m_output->BeginTag(AZ_CRC("ThreadEnter", 0x60e4acfb));
|
||||
m_output->Write(AZ_CRC("Id", 0xbf396750), threadInfo.m_id);
|
||||
if (threadInfo.m_name)
|
||||
{
|
||||
m_output->Write(AZ_CRC("Name", 0x5e237e06), threadInfo.m_name);
|
||||
}
|
||||
m_output->Write(AZ_CRC("CpuId", 0xdf558508), threadInfo.m_cpuId);
|
||||
m_output->Write(AZ_CRC("Priority", 0x62a6dc27), threadInfo.m_priority);
|
||||
m_output->Write(AZ_CRC("StackSize", 0x9cfaf35b), threadInfo.m_stackSize);
|
||||
m_output->EndTag(AZ_CRC("ThreadEnter", 0x60e4acfb));
|
||||
m_output->EndTag(AZ_CRC("ProfilerDriller", 0x172c5268));
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// OutputThreadExit
|
||||
// [7/9/2013]
|
||||
//=========================================================================
|
||||
void ProfilerDriller::OutputThreadExit(const ThreadInfo& threadInfo)
|
||||
{
|
||||
m_output->BeginTag(AZ_CRC("ProfilerDriller", 0x172c5268));
|
||||
m_output->BeginTag(AZ_CRC("OnThreadExit", 0x16042db9));
|
||||
m_output->Write(AZ_CRC("Id", 0xbf396750), threadInfo.m_id);
|
||||
m_output->EndTag(AZ_CRC("OnThreadExit", 0x16042db9));
|
||||
m_output->EndTag(AZ_CRC("ProfilerDriller", 0x172c5268));
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// OnRegisterSystem
|
||||
// [5/31/2013]
|
||||
//=========================================================================
|
||||
void ProfilerDriller::OnRegisterSystem(AZ::u32 id, const char* name)
|
||||
{
|
||||
m_output->BeginTag(AZ_CRC("ProfilerDriller", 0x172c5268));
|
||||
m_output->BeginTag(AZ_CRC("RegisterSystem", 0x957739ef));
|
||||
m_output->Write(AZ_CRC("Id", 0xbf396750), id);
|
||||
m_output->Write(AZ_CRC("Name", 0x5e237e06), name);
|
||||
m_output->EndTag(AZ_CRC("RegisterSystem", 0x957739ef));
|
||||
m_output->EndTag(AZ_CRC("ProfilerDriller", 0x172c5268));
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// OnUnregisterSystem
|
||||
// [5/31/2013]
|
||||
//=========================================================================
|
||||
void ProfilerDriller::OnUnregisterSystem(AZ::u32 id)
|
||||
{
|
||||
m_output->BeginTag(AZ_CRC("ProfilerDriller", 0x172c5268));
|
||||
m_output->BeginTag(AZ_CRC("UnregisterSystem", 0xa20538e4));
|
||||
m_output->Write(AZ_CRC("Id", 0xbf396750), id);
|
||||
m_output->EndTag(AZ_CRC("UnregisterSystem", 0xa20538e4));
|
||||
m_output->EndTag(AZ_CRC("ProfilerDriller", 0x172c5268));
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// OnNewRegister
|
||||
// [5/31/2013]
|
||||
//=========================================================================
|
||||
void ProfilerDriller::OnNewRegister(const ProfilerRegister& reg, const AZStd::thread_id& threadId)
|
||||
{
|
||||
m_output->BeginTag(AZ_CRC("ProfilerDriller", 0x172c5268));
|
||||
m_output->BeginTag(AZ_CRC("NewRegister", 0xf0f2f287));
|
||||
m_output->Write(AZ_CRC("Id", 0xbf396750), ®);
|
||||
m_output->Write(AZ_CRC("ThreadId", 0xd0fd9043), threadId.m_id);
|
||||
if (reg.m_name)
|
||||
{
|
||||
m_output->Write(AZ_CRC("Name", 0x5e237e06), reg.m_name);
|
||||
}
|
||||
if (reg.m_function)
|
||||
{
|
||||
m_output->Write(AZ_CRC("Function", 0xcaae163d), reg.m_function);
|
||||
}
|
||||
m_output->Write(AZ_CRC("Line", 0xd114b4f6), reg.m_line);
|
||||
m_output->Write(AZ_CRC("SystemId", 0x0dfecf6f), reg.m_systemId);
|
||||
m_output->Write(AZ_CRC("Type", 0x8cde5729), reg.m_type);
|
||||
|
||||
switch (reg.m_type)
|
||||
{
|
||||
case ProfilerRegister::PRT_TIME:
|
||||
{
|
||||
m_output->Write(AZ_CRC("Time", 0x6f949845), reg.m_timeData.m_time);
|
||||
m_output->Write(AZ_CRC("ChildrenTime", 0x46162d3f), reg.m_timeData.m_childrenTime);
|
||||
m_output->Write(AZ_CRC("Calls", 0xdaa35c8f), reg.m_timeData.m_calls);
|
||||
m_output->Write(AZ_CRC("ChildrenCalls", 0x6a5a4618), reg.m_timeData.m_childrenCalls);
|
||||
m_output->Write(AZ_CRC("ParentId", 0x856a684c), reg.m_timeData.m_lastParent);
|
||||
} break;
|
||||
case ProfilerRegister::PRT_VALUE:
|
||||
{
|
||||
m_output->Write(AZ_CRC("Value1", 0xa2756c5a), reg.m_userValues.m_value1);
|
||||
m_output->Write(AZ_CRC("Value2", 0x3b7c3de0), reg.m_userValues.m_value2);
|
||||
m_output->Write(AZ_CRC("Value3", 0x4c7b0d76), reg.m_userValues.m_value3);
|
||||
m_output->Write(AZ_CRC("Value4", 0xd21f98d5), reg.m_userValues.m_value4);
|
||||
m_output->Write(AZ_CRC("Value5", 0xa518a843), reg.m_userValues.m_value5);
|
||||
} break;
|
||||
}
|
||||
m_output->EndTag(AZ_CRC("NewRegister", 0xf0f2f287));
|
||||
m_output->EndTag(AZ_CRC("ProfilerDriller", 0x172c5268));
|
||||
}
|
||||
} // namespace Debug
|
||||
} // namespace AZ
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#ifndef AZCORE_PROFILER_DRILLER_H
|
||||
#define AZCORE_PROFILER_DRILLER_H 1
|
||||
|
||||
#include <AzCore/Driller/Driller.h>
|
||||
#include <AzCore/Debug/ProfilerDrillerBus.h>
|
||||
#include <AzCore/std/parallel/threadbus.h>
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
struct thread_id;
|
||||
struct thread_desc;
|
||||
}
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Debug
|
||||
{
|
||||
struct ProfilerSystemData;
|
||||
class ProfilerRegister;
|
||||
|
||||
/**
|
||||
* ProfilerDriller or we can just make a Profiler driller and read the registers ourself.
|
||||
*/
|
||||
class ProfilerDriller
|
||||
: public Driller
|
||||
, public ProfilerDrillerBus::Handler
|
||||
, public AZStd::ThreadDrillerEventBus::Handler
|
||||
{
|
||||
struct ThreadInfo
|
||||
{
|
||||
AZ::u64 m_id;
|
||||
AZ::u32 m_stackSize;
|
||||
AZ::s32 m_priority;
|
||||
AZ::s32 m_cpuId;
|
||||
const char* m_name;
|
||||
};
|
||||
typedef vector<ThreadInfo>::type ThreadArrayType;
|
||||
|
||||
public:
|
||||
|
||||
AZ_CLASS_ALLOCATOR(ProfilerDriller, OSAllocator, 0)
|
||||
|
||||
ProfilerDriller();
|
||||
virtual ~ProfilerDriller();
|
||||
|
||||
protected:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Driller
|
||||
virtual const char* GroupName() const { return "SystemDrillers"; }
|
||||
virtual const char* GetName() const { return "ProfilerDriller"; }
|
||||
virtual const char* GetDescription() const { return "Collects data from all available profile registers."; }
|
||||
virtual int GetNumParams() const { return m_numberOfSystemFilters; }
|
||||
virtual const Param* GetParam(int index) const { AZ_Assert(index >= 0 && index < m_numberOfSystemFilters, "Invalid index"); return &m_systemFilters[index]; }
|
||||
virtual void Start(const Param* params = NULL, int numParams = 0);
|
||||
virtual void Stop();
|
||||
virtual void Update();
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Thread driller event bus
|
||||
/// Called when we enter a thread, optional thread_desc is provided when the use provides one.
|
||||
virtual void OnThreadEnter(const AZStd::thread_id& id, const AZStd::thread_desc* desc);
|
||||
/// Called when we exit a thread.
|
||||
virtual void OnThreadExit(const AZStd::thread_id& id);
|
||||
|
||||
/// Output thread enter to stream.
|
||||
void OutputThreadEnter(const ThreadInfo& threadInfo);
|
||||
/// Output thread exit to stream.
|
||||
void OutputThreadExit(const ThreadInfo& threadInfo);
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Profiler Driller bus
|
||||
virtual void OnRegisterSystem(AZ::u32 id, const char* name);
|
||||
|
||||
virtual void OnUnregisterSystem(AZ::u32 id);
|
||||
|
||||
virtual void OnNewRegister(const ProfilerRegister& reg, const AZStd::thread_id& threadId);
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Read profile registers callback.
|
||||
bool ReadProfilerRegisters(const ProfilerRegister& reg, const AZStd::thread_id& id);
|
||||
|
||||
|
||||
|
||||
static const int m_numberOfSystemFilters = 16;
|
||||
int m_numberOfValidFilters = 0 ; ///< Number of valid filter set when the driller was created.
|
||||
Param m_systemFilters[m_numberOfSystemFilters]; ///< If != 0, it's a ID of specific System we would like to drill.
|
||||
ThreadArrayType m_threads;
|
||||
};
|
||||
}
|
||||
} // namespace AZ
|
||||
|
||||
#endif // AZCORE_PROFILER_DRILLER_H
|
||||
#pragma once
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
#ifndef AZCORE_PROFILER_DRILLER_BUS_H
|
||||
#define AZCORE_PROFILER_DRILLER_BUS_H
|
||||
|
||||
#include <AzCore/Driller/DrillerBus.h>
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
struct thread_id;
|
||||
}
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Debug
|
||||
{
|
||||
class ProfilerRegister;
|
||||
|
||||
/**
|
||||
* ProfilerDrillerInterface driller profiler event interface, that records events from the profiler system.
|
||||
*/
|
||||
class ProfilerDrillerInterface
|
||||
: public DrillerEBusTraits
|
||||
{
|
||||
public:
|
||||
virtual ~ProfilerDrillerInterface() {}
|
||||
|
||||
virtual void OnRegisterSystem(AZ::u32 id, const char* name) = 0;
|
||||
|
||||
virtual void OnUnregisterSystem(AZ::u32 id) = 0;
|
||||
|
||||
virtual void OnNewRegister(const ProfilerRegister& reg, const AZStd::thread_id& threadId) = 0;
|
||||
};
|
||||
|
||||
typedef AZ::EBus<ProfilerDrillerInterface> ProfilerDrillerBus;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // AZCORE_PROFILER_DRILLER_BUS_H
|
||||
#pragma once
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/Module/Environment.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/std/chrono/chrono.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -33,6 +34,7 @@ namespace AZ
|
||||
namespace Platform
|
||||
{
|
||||
#if defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
bool AttachDebugger();
|
||||
bool IsDebuggerPresent();
|
||||
void HandleExceptions(bool isEnabled);
|
||||
void DebugBreak();
|
||||
@@ -66,7 +68,6 @@ namespace AZ
|
||||
static const int assertLevel_log = 1;
|
||||
static const int assertLevel_nativeUI = 2;
|
||||
static const int assertLevel_crash = 3;
|
||||
static const int logLevel_errorWarning = 1;
|
||||
static const int logLevel_full = 2;
|
||||
static AZ::EnvironmentVariable<AZStd::unordered_set<size_t>> g_ignoredAsserts;
|
||||
static AZ::EnvironmentVariable<int> g_assertVerbosityLevel;
|
||||
@@ -142,6 +143,42 @@ namespace AZ
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
Trace::AttachDebugger()
|
||||
{
|
||||
#if defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
return Platform::AttachDebugger();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
Trace::WaitForDebugger([[maybe_unused]] float timeoutSeconds/*=-1.f*/)
|
||||
{
|
||||
#if defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
using AZStd::chrono::system_clock;
|
||||
using AZStd::chrono::time_point;
|
||||
using AZStd::chrono::milliseconds;
|
||||
|
||||
milliseconds timeoutMs = milliseconds(aznumeric_cast<long long>(timeoutSeconds * 1000));
|
||||
system_clock clock;
|
||||
time_point start = clock.now();
|
||||
auto hasTimedOut = [&clock, start, timeoutMs]()
|
||||
{
|
||||
return timeoutMs.count() >= 0 && (clock.now() - start) >= timeoutMs;
|
||||
};
|
||||
|
||||
while (!AZ::Debug::Trace::IsDebuggerPresent() && !hasTimedOut())
|
||||
{
|
||||
AZStd::this_thread::sleep_for(milliseconds(1));
|
||||
}
|
||||
return AZ::Debug::Trace::IsDebuggerPresent();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// HandleExceptions
|
||||
// [8/3/2009]
|
||||
@@ -181,7 +218,7 @@ namespace AZ
|
||||
|
||||
void Debug::Trace::Crash()
|
||||
{
|
||||
int* p = 0;
|
||||
int* p = nullptr;
|
||||
*p = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace AZ
|
||||
{
|
||||
void OutputToDebugger(const char* window, const char* message);
|
||||
}
|
||||
|
||||
|
||||
/// Global instance to the tracer.
|
||||
extern class Trace g_tracer;
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace AZ
|
||||
static void Destroy();
|
||||
static int GetAssertVerbosityLevel();
|
||||
static void SetAssertVerbosityLevel(int level);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the default string used for a system window.
|
||||
* It can be useful for Trace message handlers to easily validate if the window they received is the fallback window used by this class,
|
||||
@@ -49,6 +49,8 @@ namespace AZ
|
||||
*/
|
||||
static const char* GetDefaultSystemWindow();
|
||||
static bool IsDebuggerPresent();
|
||||
static bool AttachDebugger();
|
||||
static bool WaitForDebugger(float timeoutSeconds = -1.f);
|
||||
|
||||
/// True or false if we want to handle system exceptions.
|
||||
static void HandleExceptions(bool isEnabled);
|
||||
@@ -107,7 +109,7 @@ namespace AZ
|
||||
* Correct usage:
|
||||
* AZ_Assert(false, "Fail always");
|
||||
*/
|
||||
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace TraceInternal
|
||||
@@ -119,7 +121,7 @@ namespace AZ
|
||||
static constexpr ExpressionValidResult value = ExpressionValidResult::Valid;
|
||||
};
|
||||
template<>
|
||||
struct ExpressionIsValid<const char*&>
|
||||
struct ExpressionIsValid<const char*&>
|
||||
{
|
||||
static constexpr ExpressionValidResult value = ExpressionValidResult::Valid;
|
||||
};
|
||||
@@ -226,7 +228,7 @@ namespace AZ
|
||||
{ \
|
||||
AZ::Debug::Trace::Instance().Printf(window, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! The AZ_TrancePrintfOnce macro output the result of the format string only once for each use of the macro
|
||||
//! It does not take into account the result of the format string to determine whether to output the string or not
|
||||
|
||||
@@ -208,7 +208,7 @@ namespace AZ
|
||||
{
|
||||
if (drillerList.empty())
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m_sessions.push_back();
|
||||
@@ -246,21 +246,21 @@ namespace AZ
|
||||
AZStd::lock_guard<DrillerEBusMutex::MutexType> lock(DrillerEBusMutex::GetMutex()); ///< Make sure no driller is writing to the stream
|
||||
for (DrillerListType::const_iterator iDriller = drillerList.begin(); iDriller != drillerList.end(); ++iDriller)
|
||||
{
|
||||
Driller* driller = NULL;
|
||||
Driller* driller = nullptr;
|
||||
const DrillerInfo& di = *iDriller;
|
||||
for (size_t iDesc = 0; iDesc < m_drillers.size(); ++iDesc)
|
||||
{
|
||||
if (m_drillers[iDesc]->GetId() == di.id)
|
||||
{
|
||||
driller = m_drillers[iDesc];
|
||||
AZ_Assert(driller->m_output == NULL, "Driller with id %08x is already have an output stream %p (currently we support only 1 at a time)", di.id, driller->m_output);
|
||||
AZ_Assert(driller->m_output == nullptr, "Driller with id %08x is already have an output stream %p (currently we support only 1 at a time)", di.id, driller->m_output);
|
||||
driller->m_output = &output;
|
||||
driller->Start(di.params.data(), static_cast<unsigned int>(di.params.size()));
|
||||
s.drillers.push_back(driller);
|
||||
break;
|
||||
}
|
||||
}
|
||||
AZ_Warning("Driller", driller != NULL, "We can't start a driller with id %d!", di.id);
|
||||
AZ_Warning("Driller", driller != nullptr, "We can't start a driller with id %d!", di.id);
|
||||
}
|
||||
}
|
||||
return &s;
|
||||
@@ -293,7 +293,7 @@ namespace AZ
|
||||
for (size_t i = 0; i < s.drillers.size(); ++i)
|
||||
{
|
||||
s.drillers[i]->Stop();
|
||||
s.drillers[i]->m_output = NULL;
|
||||
s.drillers[i]->m_output = nullptr;
|
||||
}
|
||||
}
|
||||
s.output->EndTag(AZ_CRC("Frame", 0xb5f83ccd));
|
||||
|
||||
@@ -677,7 +677,7 @@ namespace AZ
|
||||
AZStd::endian_swap(crc32);
|
||||
}
|
||||
stringPtr = m_stringPool->Find(crc32);
|
||||
AZ_Assert(stringPtr != NULL, "Failed to find string with id 0x%08x in the string pool, proper stream read is impossible!", crc32);
|
||||
AZ_Assert(stringPtr != nullptr, "Failed to find string with id 0x%08x in the string pool, proper stream read is impossible!", crc32);
|
||||
stringLength = static_cast<unsigned int>(strlen(stringPtr));
|
||||
}
|
||||
else if (m_isPooledString)
|
||||
@@ -710,7 +710,7 @@ namespace AZ
|
||||
//=========================================================================
|
||||
const DrillerDOMParser::Node* DrillerDOMParser::Node::GetTag(u32 tagName) const
|
||||
{
|
||||
const Node* tagNode = NULL;
|
||||
const Node* tagNode = nullptr;
|
||||
for (Node::NodeListType::const_iterator i = m_tags.begin(); i != m_tags.end(); ++i)
|
||||
{
|
||||
if ((*i).m_name == tagName)
|
||||
@@ -728,7 +728,7 @@ namespace AZ
|
||||
//=========================================================================
|
||||
const DrillerDOMParser::Data* DrillerDOMParser::Node::GetData(u32 dataName) const
|
||||
{
|
||||
const Data* dataNode = NULL;
|
||||
const Data* dataNode = nullptr;
|
||||
for (Node::DataListType::const_iterator i = m_data.begin(); i != m_data.end(); ++i)
|
||||
{
|
||||
if (i->m_name == dataName)
|
||||
@@ -749,7 +749,7 @@ namespace AZ
|
||||
, m_isPersistentInputData(isPersistentInputData)
|
||||
{
|
||||
m_root.m_name = 0;
|
||||
m_root.m_parent = NULL;
|
||||
m_root.m_parent = nullptr;
|
||||
m_topNode = &m_root;
|
||||
}
|
||||
static int g_numFree = 0;
|
||||
@@ -850,14 +850,14 @@ namespace AZ
|
||||
return;
|
||||
}
|
||||
|
||||
DrillerHandlerParser* childHandler = NULL;
|
||||
DrillerHandlerParser* childHandler = nullptr;
|
||||
DrillerHandlerParser* currentHandler = m_stack.back();
|
||||
if (isOpen)
|
||||
{
|
||||
if (currentHandler != NULL)
|
||||
if (currentHandler != nullptr)
|
||||
{
|
||||
childHandler = currentHandler->OnEnterTag(name);
|
||||
AZ_Warning("Driller", !currentHandler->IsWarnOnUnsupportedTags() || childHandler != NULL, "Could not find handler for tag 0x%08x", name);
|
||||
AZ_Warning("Driller", !currentHandler->IsWarnOnUnsupportedTags() || childHandler != nullptr, "Could not find handler for tag 0x%08x", name);
|
||||
}
|
||||
m_stack.push_back(childHandler);
|
||||
}
|
||||
|
||||
@@ -655,7 +655,7 @@ namespace AZ
|
||||
static void Validate() {}
|
||||
};
|
||||
|
||||
template <class Function, bool IsBindExpression = AZStd::is_bind_expression_v<Function>>
|
||||
template <class Function>
|
||||
struct ArgumentValidatorHelper
|
||||
{
|
||||
constexpr static void Validate()
|
||||
@@ -674,13 +674,6 @@ namespace AZ
|
||||
}
|
||||
};
|
||||
|
||||
// bind has already copied/bound its arguments, we can't validate them further in any reasonable way
|
||||
template <class Function>
|
||||
struct ArgumentValidatorHelper<Function, true>
|
||||
{
|
||||
constexpr static void Validate() {}
|
||||
};
|
||||
|
||||
template <class Function>
|
||||
struct QueueFunctionArgumentValidator<Function, false>
|
||||
{
|
||||
|
||||
@@ -22,10 +22,10 @@ namespace AZ
|
||||
// [12/13/2012]
|
||||
//=========================================================================
|
||||
CompressorZLib::CompressorZLib(unsigned int decompressionCachePerStream, unsigned int dataBufferSize)
|
||||
: m_lastReadStream(NULL)
|
||||
: m_lastReadStream(nullptr)
|
||||
, m_lastReadStreamOffset(0)
|
||||
, m_lastReadStreamSize(0)
|
||||
, m_compressedDataBuffer(NULL)
|
||||
, m_compressedDataBuffer(nullptr)
|
||||
, m_compressedDataBufferSize(dataBufferSize)
|
||||
, m_compressedDataBufferUseCount(0)
|
||||
, m_decompressionCachePerStream(decompressionCachePerStream)
|
||||
@@ -63,7 +63,7 @@ namespace AZ
|
||||
//=========================================================================
|
||||
bool CompressorZLib::ReadHeaderAndData(CompressorStream* stream, AZ::u8* data, unsigned int dataSize)
|
||||
{
|
||||
if (stream->GetCompressorData() != NULL) // we already have compressor data
|
||||
if (stream->GetCompressorData() != nullptr) // we already have compressor data
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -347,7 +347,7 @@ namespace AZ
|
||||
AZ_Assert(stream && stream->GetCompressorData(), "This stream doesn't have compression enabled! Call Stream::WriteCompressed after you create the file!");
|
||||
AZ_Assert(offset == SizeType(-1) || offset == stream->GetCurPos(), "We can write compressed data only at the end of the stream!");
|
||||
|
||||
m_lastReadStream = NULL; // invalidate last read position, otherwise m_dataBuffer will be corrupted (as we are about to write in it).
|
||||
m_lastReadStream = nullptr; // invalidate last read position, otherwise m_dataBuffer will be corrupted (as we are about to write in it).
|
||||
|
||||
CompressorZLibData* zlibData = static_cast<CompressorZLibData*>(stream->GetCompressorData());
|
||||
AZ_Assert(!zlibData->m_zlib.IsDecompressorStarted(), "You can't write while reading/decompressing a compressed stream!");
|
||||
@@ -398,13 +398,13 @@ namespace AZ
|
||||
AZ_Assert(stream && stream->GetCompressorData(), "This stream doesn't have compression enabled! Call Stream::WriteCompressed after you create the file!");
|
||||
CompressorZLibData* zlibData = static_cast<CompressorZLibData*>(stream->GetCompressorData());
|
||||
|
||||
m_lastReadStream = NULL; // invalidate last read position, otherwise m_dataBuffer will be corrupted (as we are about to write in it).
|
||||
m_lastReadStream = nullptr; // invalidate last read position, otherwise m_dataBuffer will be corrupted (as we are about to write in it).
|
||||
|
||||
unsigned int compressedSize;
|
||||
unsigned int dataToCompress = 0;
|
||||
do
|
||||
{
|
||||
compressedSize = zlibData->m_zlib.Compress(NULL, dataToCompress, m_compressedDataBuffer, m_compressedDataBufferSize, ZLib::FT_FULL_FLUSH);
|
||||
compressedSize = zlibData->m_zlib.Compress(nullptr, dataToCompress, m_compressedDataBuffer, m_compressedDataBufferSize, ZLib::FT_FULL_FLUSH);
|
||||
if (compressedSize)
|
||||
{
|
||||
GenericStream* baseStream = stream->GetWrappedStream();
|
||||
@@ -429,7 +429,7 @@ namespace AZ
|
||||
//=========================================================================
|
||||
bool CompressorZLib::StartCompressor(CompressorStream* stream, int compressionLevel, SizeType autoSeekDataSize)
|
||||
{
|
||||
AZ_Assert(stream && stream->GetCompressorData() == NULL, "Stream has compressor already enabled!");
|
||||
AZ_Assert(stream && stream->GetCompressorData() == nullptr, "Stream has compressor already enabled!");
|
||||
|
||||
AcquireDataBuffer();
|
||||
|
||||
@@ -470,14 +470,14 @@ namespace AZ
|
||||
bool result = true;
|
||||
if (zlibData->m_zlib.IsCompressorStarted())
|
||||
{
|
||||
m_lastReadStream = NULL; // invalidate last read position, otherwise m_dataBuffer will be corrupted (as we are about to write in it).
|
||||
m_lastReadStream = nullptr; // invalidate last read position, otherwise m_dataBuffer will be corrupted (as we are about to write in it).
|
||||
|
||||
// flush all compressed data
|
||||
unsigned int compressedSize;
|
||||
unsigned int dataToCompress = 0;
|
||||
do
|
||||
{
|
||||
compressedSize = zlibData->m_zlib.Compress(NULL, dataToCompress, m_compressedDataBuffer, m_compressedDataBufferSize, ZLib::FT_FINISH);
|
||||
compressedSize = zlibData->m_zlib.Compress(nullptr, dataToCompress, m_compressedDataBuffer, m_compressedDataBufferSize, ZLib::FT_FINISH);
|
||||
if (compressedSize)
|
||||
{
|
||||
baseStream->Write(compressedSize, m_compressedDataBuffer);
|
||||
@@ -502,7 +502,7 @@ namespace AZ
|
||||
{
|
||||
if (m_lastReadStream == stream)
|
||||
{
|
||||
m_lastReadStream = NULL; // invalidate the data in m_dataBuffer if it was from the current stream.
|
||||
m_lastReadStream = nullptr; // invalidate the data in m_dataBuffer if it was from the current stream.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,11 +525,11 @@ namespace AZ
|
||||
//=========================================================================
|
||||
void CompressorZLib::AcquireDataBuffer()
|
||||
{
|
||||
if (m_compressedDataBuffer == NULL)
|
||||
if (m_compressedDataBuffer == nullptr)
|
||||
{
|
||||
AZ_Assert(m_compressedDataBufferUseCount == 0, "Buffer usecount should be 0 if the buffer is NULL");
|
||||
m_compressedDataBuffer = reinterpret_cast<unsigned char*>(azmalloc(m_compressedDataBufferSize, m_CompressedDataBufferAlignment, AZ::SystemAllocator, "CompressorZLib"));
|
||||
m_lastReadStream = NULL; // reset the cache info in the m_dataBuffer
|
||||
m_lastReadStream = nullptr; // reset the cache info in the m_dataBuffer
|
||||
}
|
||||
++m_compressedDataBufferUseCount;
|
||||
}
|
||||
@@ -543,10 +543,10 @@ namespace AZ
|
||||
--m_compressedDataBufferUseCount;
|
||||
if (m_compressedDataBufferUseCount == 0)
|
||||
{
|
||||
AZ_Assert(m_compressedDataBuffer != NULL, "Invalid data buffer! We should have a non null pointer!");
|
||||
AZ_Assert(m_compressedDataBuffer != nullptr, "Invalid data buffer! We should have a non null pointer!");
|
||||
azfree(m_compressedDataBuffer, AZ::SystemAllocator, m_compressedDataBufferSize, m_CompressedDataBufferAlignment);
|
||||
m_compressedDataBuffer = NULL;
|
||||
m_lastReadStream = NULL; // reset the cache info in the m_dataBuffer
|
||||
m_compressedDataBuffer = nullptr;
|
||||
m_lastReadStream = nullptr; // reset the cache info in the m_dataBuffer
|
||||
}
|
||||
}
|
||||
} // namespace IO
|
||||
|
||||
@@ -426,7 +426,6 @@ namespace AZ
|
||||
|
||||
void FileIOStream::Seek(OffsetType bytes, SeekMode mode)
|
||||
{
|
||||
AZ_PROFILE_SCOPE(AzCore, "FileIO Seek: %s", m_filename.c_str());
|
||||
AZ_Assert(FileIOBase::GetInstance(), "FileIO is not initialized.");
|
||||
AZ_Assert(IsOpen(), "Cannot seek on a FileIOStream that is not open.");
|
||||
|
||||
@@ -454,7 +453,6 @@ namespace AZ
|
||||
|
||||
SizeType FileIOStream::Read(SizeType bytes, void* oBuffer)
|
||||
{
|
||||
AZ_PROFILE_SCOPE(AzCore, "FileIO Read: %s", m_filename.c_str());
|
||||
AZ_Assert(FileIOBase::GetInstance(), "FileIO is not initialized.");
|
||||
AZ_Assert(IsOpen(), "Cannot read from a FileIOStream that is not open.");
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/std/containers/array.h>
|
||||
#include <AzCore/std/string/wildcard.h>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/AzCore_Traits_Platform.h>
|
||||
|
||||
// extern instantiations of Path templates to prevent implicit instantiations
|
||||
namespace AZ::IO
|
||||
@@ -92,11 +93,23 @@ namespace AZ::IO::Internal
|
||||
constexpr auto ConsumeRootName(InputIt entryBeginIter, InputIt entryEndIter, const char preferredSeparator)
|
||||
-> AZStd::enable_if_t<AZStd::Internal::is_forward_iterator_v<InputIt>, InputIt>
|
||||
{
|
||||
if (preferredSeparator == '/')
|
||||
if (preferredSeparator == PosixPathSeparator)
|
||||
{
|
||||
// If the preferred separator is forward slash the parser is in posix path
|
||||
// parsing mode, which doesn't have a root name
|
||||
// parsing mode, which doesn't have a root name,
|
||||
// unless we're on a posix platform that uses a custom path root separator
|
||||
#if defined(AZ_TRAIT_CUSTOM_PATH_ROOT_SEPARATOR)
|
||||
const AZStd::string_view path{ entryBeginIter, entryEndIter };
|
||||
const auto positionOfPathSeparator = path.find(AZ_TRAIT_CUSTOM_PATH_ROOT_SEPARATOR);
|
||||
if (positionOfPathSeparator == AZStd::string_view::npos)
|
||||
{
|
||||
return entryBeginIter;
|
||||
}
|
||||
const AZStd::string_view rootName{ path.substr(0, positionOfPathSeparator + 1) };
|
||||
return AZStd::next(entryBeginIter, rootName.size());
|
||||
#else
|
||||
return entryBeginIter;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -185,13 +198,18 @@ namespace AZ::IO::Internal
|
||||
template <typename InputIt, typename EndIt, typename = AZStd::enable_if_t<AZStd::Internal::is_input_iterator_v<InputIt>>>
|
||||
static constexpr bool IsAbsolute(InputIt first, EndIt last, const char preferredSeparator)
|
||||
{
|
||||
size_t pathSize = AZStd::distance(first, last);
|
||||
|
||||
// If the preferred separator is a forward slash
|
||||
// than an absolute path is simply one that starts with a forward slash
|
||||
if (preferredSeparator == '/')
|
||||
// than an absolute path is simply one that starts with a forward slash,
|
||||
// unless we're on a posix platform that uses a custom path root separator
|
||||
if (preferredSeparator == PosixPathSeparator)
|
||||
{
|
||||
#if defined(AZ_TRAIT_CUSTOM_PATH_ROOT_SEPARATOR)
|
||||
const AZStd::string_view path{ first, last };
|
||||
return path.find(AZ_TRAIT_CUSTOM_PATH_ROOT_SEPARATOR) != AZStd::string_view::npos;
|
||||
#else
|
||||
const size_t pathSize = AZStd::distance(first, last);
|
||||
return pathSize > 0 && IsSeparator(*first);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -199,6 +217,7 @@ namespace AZ::IO::Internal
|
||||
{
|
||||
// If a windows path ends starts with C:foo it is a root relative path
|
||||
// A path is absolute root absolute on windows if it starts with <drive_letter><colon><path_separator>
|
||||
const size_t pathSize = AZStd::distance(first, last);
|
||||
return pathSize > 2 && Internal::IsSeparator(*AZStd::next(first, 2));
|
||||
}
|
||||
|
||||
|
||||
@@ -45,8 +45,10 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
#if AZ_STREAMER_ADD_EXTRA_PROFILING_INFO
|
||||
static constexpr char DecompBoundName[] = "Decompression bound";
|
||||
static constexpr char ReadBoundName[] = "Read bound";
|
||||
#endif // AZ_STREAMER_ADD_EXTRA_PROFILING_INFO
|
||||
|
||||
bool FullFileDecompressor::DecompressionInformation::IsProcessing() const
|
||||
{
|
||||
|
||||
@@ -14,8 +14,10 @@
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
#if AZ_STREAMER_ADD_EXTRA_PROFILING_INFO
|
||||
static constexpr char SchedulerName[] = "Scheduler";
|
||||
static constexpr char ImmediateReadsName[] = "Immediate reads";
|
||||
#endif // AZ_STREAMER_ADD_EXTRA_PROFILING_INFO
|
||||
|
||||
Scheduler::Scheduler(AZStd::shared_ptr<StreamStackEntry> streamStack, u64 memoryAlignment, u64 sizeAlignment, u64 granularity)
|
||||
{
|
||||
@@ -337,7 +339,7 @@ namespace AZ::IO
|
||||
AZStd::chrono::system_clock::time_point now = AZStd::chrono::system_clock::now();
|
||||
auto visitor = [this, now](auto&& args) -> void
|
||||
#else
|
||||
auto visitor = [this](auto&& args) -> void
|
||||
auto visitor = [](auto&& args) -> void
|
||||
#endif
|
||||
{
|
||||
using Command = AZStd::decay_t<decltype(args)>;
|
||||
|
||||
@@ -17,10 +17,11 @@ namespace AZ
|
||||
namespace IO
|
||||
{
|
||||
static constexpr char ContextName[] = "Context";
|
||||
#if AZ_STREAMER_ADD_EXTRA_PROFILING_INFO
|
||||
static constexpr char PredictionAccuracyName[] = "Prediction accuracy (ms)";
|
||||
static constexpr char LatePredictionName[] = "Early completions";
|
||||
static constexpr char MissedDeadlinesName[] = "Missed deadlines";
|
||||
|
||||
#endif // AZ_STREAMER_ADD_EXTRA_PROFILING_INFO
|
||||
StreamerContext::~StreamerContext()
|
||||
{
|
||||
for (FileRequest* entry : m_internalRecycleBin)
|
||||
|
||||
@@ -127,7 +127,7 @@ bool SystemFile::Open(const char* fileName, int mode, int platformFlags)
|
||||
bool SystemFile::ReOpen(int mode, int platformFlags)
|
||||
{
|
||||
AZ_Assert(!m_fileName.empty(), "Missing filename. You must call open first!");
|
||||
return Open(0, mode, platformFlags);
|
||||
return Open(nullptr, mode, platformFlags);
|
||||
}
|
||||
|
||||
void SystemFile::Close()
|
||||
|
||||
@@ -125,7 +125,7 @@ SharedMemory::Close()
|
||||
bool
|
||||
SharedMemory::Map(AccessMode mode, unsigned int size)
|
||||
{
|
||||
AZ_Assert(m_mappedBase == NULL, "We already have data mapped");
|
||||
AZ_Assert(m_mappedBase == nullptr, "We already have data mapped");
|
||||
AZ_Assert(Platform::IsMapHandleValid(), "You must call Map() first!");
|
||||
|
||||
bool result = Platform::Map(mode, size);
|
||||
@@ -232,7 +232,7 @@ bool SharedMemory::CheckMappedBaseValid()
|
||||
// [4/29/2011]
|
||||
//=========================================================================
|
||||
SharedMemoryRingBuffer::SharedMemoryRingBuffer()
|
||||
: m_info(NULL)
|
||||
: m_info(nullptr)
|
||||
{}
|
||||
|
||||
//=========================================================================
|
||||
@@ -279,7 +279,7 @@ SharedMemoryRingBuffer::Map(AccessMode mode, unsigned int size)
|
||||
bool
|
||||
SharedMemoryRingBuffer::UnMap()
|
||||
{
|
||||
m_info = NULL;
|
||||
m_info = nullptr;
|
||||
return SharedMemory::UnMap();
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ bool
|
||||
SharedMemoryRingBuffer::Write(const void* data, unsigned int dataSize)
|
||||
{
|
||||
AZ_Warning("AZSystem", !Platform::IsWaitFailed(), "You are writing the ring buffer %s while the Global lock is NOT locked! This can lead to data corruption!", m_name);
|
||||
AZ_Assert(m_info != NULL, "You need to Create and Map the buffer first!");
|
||||
AZ_Assert(m_info != nullptr, "You need to Create and Map the buffer first!");
|
||||
if (m_info->m_writeOffset >= m_info->m_readOffset)
|
||||
{
|
||||
unsigned int freeSpace = m_dataSize - (m_info->m_writeOffset - m_info->m_readOffset);
|
||||
@@ -346,7 +346,7 @@ SharedMemoryRingBuffer::Read(void* data, unsigned int maxDataSize)
|
||||
return 0;
|
||||
}
|
||||
|
||||
AZ_Assert(m_info != NULL, "You need to Create and Map the buffer first!");
|
||||
AZ_Assert(m_info != nullptr, "You need to Create and Map the buffer first!");
|
||||
unsigned int dataRead;
|
||||
if (m_info->m_writeOffset > m_info->m_readOffset)
|
||||
{
|
||||
|
||||
@@ -192,15 +192,15 @@ void JobManagerWorkStealing::SuspendJobUntilReady(Job* job)
|
||||
ThreadInfo* info = GetCurrentOrCreateThreadInfo();
|
||||
AZ_Assert(info->m_currentJob == job, ("Can't suspend a job which isn't currently running"));
|
||||
|
||||
info->m_currentJob = NULL; //clear current job
|
||||
info->m_currentJob = nullptr; //clear current job
|
||||
|
||||
if (IsAsynchronous())
|
||||
{
|
||||
ProcessJobsAssist(info, job, NULL);
|
||||
ProcessJobsAssist(info, job, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessJobsSynchronous(info, job, NULL);
|
||||
ProcessJobsSynchronous(info, job, nullptr);
|
||||
}
|
||||
|
||||
info->m_currentJob = job; //restore current job
|
||||
@@ -223,11 +223,11 @@ void JobManagerWorkStealing::StartJobAndAssistUntilComplete(Job* job)
|
||||
//the processing functions will return when the empty job dependent count has reached 1
|
||||
if (IsAsynchronous())
|
||||
{
|
||||
ProcessJobsAssist(info, NULL, ¬ifyFlag);
|
||||
ProcessJobsAssist(info, nullptr, ¬ifyFlag);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessJobsSynchronous(info, NULL, ¬ifyFlag);
|
||||
ProcessJobsSynchronous(info, nullptr, ¬ifyFlag);
|
||||
}
|
||||
|
||||
AZ_Assert(!m_currentThreadInfo, "");
|
||||
@@ -306,9 +306,9 @@ void JobManagerWorkStealing::ProcessJobsWorker(ThreadInfo* info)
|
||||
//setup thread-local storage
|
||||
m_currentThreadInfo = info;
|
||||
|
||||
ProcessJobsInternal(info, NULL, NULL);
|
||||
ProcessJobsInternal(info, nullptr, nullptr);
|
||||
|
||||
m_currentThreadInfo = NULL;
|
||||
m_currentThreadInfo = nullptr;
|
||||
}
|
||||
|
||||
void JobManagerWorkStealing::ProcessJobsAssist(ThreadInfo* info, Job* suspendedJob, AZStd::atomic<bool>* notifyFlag)
|
||||
@@ -529,7 +529,7 @@ void JobManagerWorkStealing::ProcessJobsSynchronous(ThreadInfo* info, Job* suspe
|
||||
|
||||
info->m_currentJob = job;
|
||||
Process(job);
|
||||
info->m_currentJob = NULL;
|
||||
info->m_currentJob = nullptr;
|
||||
|
||||
//...after calling Process we cannot use the job pointer again, the job has completed and may not exist anymore
|
||||
#ifdef JOBMANAGER_ENABLE_STATS
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace AZ
|
||||
}
|
||||
countAndFlags |= (unsigned int)((priority << FLAG_PRIORITY_START_BIT) & FLAG_PRIORITY_MASK);
|
||||
SetDependentCountAndFlags(countAndFlags);
|
||||
StoreDependent(NULL);
|
||||
StoreDependent(nullptr);
|
||||
|
||||
#ifdef AZ_DEBUG_JOB_STATE
|
||||
SetState(STATE_SETUP);
|
||||
@@ -66,7 +66,7 @@ namespace AZ
|
||||
SetDependentCountAndFlags(countAndFlags);
|
||||
if (isClearDependent)
|
||||
{
|
||||
StoreDependent(NULL);
|
||||
StoreDependent(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -8,25 +8,21 @@
|
||||
#ifndef AZ_CORE_GUID_H
|
||||
#define AZ_CORE_GUID_H 1
|
||||
|
||||
#ifndef GUID_DEFINED
|
||||
#if defined(GUID_DEFINED)
|
||||
#define GUID_FORMAT_DATA1 "lX"
|
||||
#else
|
||||
#define GUID_DEFINED
|
||||
typedef struct _GUID {
|
||||
_GUID(unsigned long d1, unsigned short d2, unsigned short d3, std::initializer_list<unsigned char> d4)
|
||||
: Data1(d1),
|
||||
Data2(d2),
|
||||
Data3(d3)
|
||||
{
|
||||
for (auto it = d4.begin(); it != d4.end(); ++it)
|
||||
Data4[it - d4.begin()] = *it;
|
||||
}
|
||||
|
||||
_GUID() = default;
|
||||
#include <AzCore/std/containers/array.h>
|
||||
|
||||
uint32_t Data1;
|
||||
struct _GUID {
|
||||
uint32_t Data1;
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[ 8 ];
|
||||
} GUID;
|
||||
AZStd::array<unsigned char,8> Data4;
|
||||
};
|
||||
using GUID = _GUID;
|
||||
#define GUID_FORMAT_DATA1 "X"
|
||||
#endif // GUID_DEFINED
|
||||
|
||||
#if !defined _SYS_GUID_OPERATOR_EQ_ && !defined _NO_SYS_GUID_OPERATOR_EQ_
|
||||
@@ -36,7 +32,7 @@ static bool inline operator==(const _GUID& lhs, const _GUID& rhs)
|
||||
return lhs.Data1 == rhs.Data1 &&
|
||||
lhs.Data2 == rhs.Data2 &&
|
||||
lhs.Data3 == rhs.Data3 &&
|
||||
memcmp(lhs.Data4, rhs.Data4, 8) == 0;
|
||||
lhs.Data4 == rhs.Data4;
|
||||
}
|
||||
static bool inline operator!=(const _GUID& lhs, const _GUID& rhs)
|
||||
{
|
||||
@@ -66,10 +62,9 @@ typedef const GUID& REFIID;
|
||||
const GUID name \
|
||||
= { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||
|
||||
static REFGUID GUID_NULL()
|
||||
inline constexpr GUID GUID_NULL()
|
||||
{
|
||||
static const GUID guid = { 0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
|
||||
return guid;
|
||||
return { 0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
|
||||
}
|
||||
|
||||
#define GUID_NULL GUID_NULL()
|
||||
|
||||
@@ -12,29 +12,29 @@ namespace AZ
|
||||
{
|
||||
namespace Simd
|
||||
{
|
||||
static AZ_ALIGN(constexpr float g_sinCoef1[4], 16) = { -0.0001950727f, -0.0001950727f, -0.0001950727f, -0.0001950727f };
|
||||
static AZ_ALIGN(constexpr float g_sinCoef2[4], 16) = { 0.0083320758f, 0.0083320758f, 0.0083320758f, 0.0083320758f };
|
||||
static AZ_ALIGN(constexpr float g_sinCoef3[4], 16) = { -0.1666665247f, -0.1666665247f, -0.1666665247f, -0.1666665247f };
|
||||
static AZ_ALIGN(constexpr float g_cosCoef1[4], 16) = { -0.0013602249f, -0.0013602249f, -0.0013602249f, -0.0013602249f };
|
||||
static AZ_ALIGN(constexpr float g_cosCoef2[4], 16) = { 0.0416566950f, 0.0416566950f, 0.0416566950f, 0.0416566950f };
|
||||
static AZ_ALIGN(constexpr float g_cosCoef3[4], 16) = { -0.4999990225f, -0.4999990225f, -0.4999990225f, -0.4999990225f };
|
||||
static AZ_ALIGN(constexpr float g_acosHiCoef1[4], 16) = { -0.0012624911f, -0.0012624911f, -0.0012624911f, -0.0012624911f };
|
||||
static AZ_ALIGN(constexpr float g_acosHiCoef2[4], 16) = { 0.0066700901f, 0.0066700901f, 0.0066700901f, 0.0066700901f };
|
||||
static AZ_ALIGN(constexpr float g_acosHiCoef3[4], 16) = { -0.0170881256f, -0.0170881256f, -0.0170881256f, -0.0170881256f };
|
||||
static AZ_ALIGN(constexpr float g_acosHiCoef4[4], 16) = { 0.0308918810f, 0.0308918810f, 0.0308918810f, 0.0308918810f };
|
||||
static AZ_ALIGN(constexpr float g_acosLoCoef1[4], 16) = { -0.0501743046f, -0.0501743046f, -0.0501743046f, -0.0501743046f };
|
||||
static AZ_ALIGN(constexpr float g_acosLoCoef2[4], 16) = { 0.0889789874f, 0.0889789874f, 0.0889789874f, 0.0889789874f };
|
||||
static AZ_ALIGN(constexpr float g_acosLoCoef3[4], 16) = { -0.2145988016f, -0.2145988016f, -0.2145988016f, -0.2145988016f };
|
||||
static AZ_ALIGN(constexpr float g_acosLoCoef4[4], 16) = { 1.5707963050f, 1.5707963050f, 1.5707963050f, 1.5707963050f };
|
||||
static AZ_ALIGN(constexpr float g_acosCoef1[4], 16) = { -0.0200752200f, -0.0200752200f, -0.0200752200f, -0.0200752200f };
|
||||
static AZ_ALIGN(constexpr float g_acosCoef2[4], 16) = { 0.0759031500f, 0.0759031500f, 0.0759031500f, 0.0759031500f };
|
||||
static AZ_ALIGN(constexpr float g_acosCoef3[4], 16) = { -0.2126757000f, -0.2126757000f, -0.2126757000f, -0.2126757000f };
|
||||
static AZ_ALIGN(constexpr float g_atanHiRange[4], 16) = { 2.4142135624f, 2.4142135624f, 2.4142135624f, 2.4142135624f };
|
||||
static AZ_ALIGN(constexpr float g_atanLoRange[4], 16) = { 0.4142135624f, 0.4142135624f, 0.4142135624f, 0.4142135624f };
|
||||
static AZ_ALIGN(constexpr float g_atanCoef1[4], 16) = { 8.05374449538e-2f, 8.05374449538e-2f, 8.05374449538e-2f, 8.05374449538e-2f };
|
||||
static AZ_ALIGN(constexpr float g_atanCoef2[4], 16) = { -1.38776856032e-1f, -1.38776856032e-1f, -1.38776856032e-1f, -1.38776856032e-1f };
|
||||
static AZ_ALIGN(constexpr float g_atanCoef3[4], 16) = { 1.99777106478e-1f, 1.99777106478e-1f, 1.99777106478e-1f, 1.99777106478e-1f };
|
||||
static AZ_ALIGN(constexpr float g_atanCoef4[4], 16) = { -3.33329491539e-1f, -3.33329491539e-1f, -3.33329491539e-1f, -3.33329491539e-1f };
|
||||
alignas(16) static constexpr float g_sinCoef1[4] = { -0.0001950727f, -0.0001950727f, -0.0001950727f, -0.0001950727f };
|
||||
alignas(16) static constexpr float g_sinCoef2[4] = { 0.0083320758f, 0.0083320758f, 0.0083320758f, 0.0083320758f };
|
||||
alignas(16) static constexpr float g_sinCoef3[4] = { -0.1666665247f, -0.1666665247f, -0.1666665247f, -0.1666665247f };
|
||||
alignas(16) static constexpr float g_cosCoef1[4] = { -0.0013602249f, -0.0013602249f, -0.0013602249f, -0.0013602249f };
|
||||
alignas(16) static constexpr float g_cosCoef2[4] = { 0.0416566950f, 0.0416566950f, 0.0416566950f, 0.0416566950f };
|
||||
alignas(16) static constexpr float g_cosCoef3[4] = { -0.4999990225f, -0.4999990225f, -0.4999990225f, -0.4999990225f };
|
||||
alignas(16) static constexpr float g_acosHiCoef1[4] = { -0.0012624911f, -0.0012624911f, -0.0012624911f, -0.0012624911f };
|
||||
alignas(16) static constexpr float g_acosHiCoef2[4] = { 0.0066700901f, 0.0066700901f, 0.0066700901f, 0.0066700901f };
|
||||
alignas(16) static constexpr float g_acosHiCoef3[4] = { -0.0170881256f, -0.0170881256f, -0.0170881256f, -0.0170881256f };
|
||||
alignas(16) static constexpr float g_acosHiCoef4[4] = { 0.0308918810f, 0.0308918810f, 0.0308918810f, 0.0308918810f };
|
||||
alignas(16) static constexpr float g_acosLoCoef1[4] = { -0.0501743046f, -0.0501743046f, -0.0501743046f, -0.0501743046f };
|
||||
alignas(16) static constexpr float g_acosLoCoef2[4] = { 0.0889789874f, 0.0889789874f, 0.0889789874f, 0.0889789874f };
|
||||
alignas(16) static constexpr float g_acosLoCoef3[4] = { -0.2145988016f, -0.2145988016f, -0.2145988016f, -0.2145988016f };
|
||||
alignas(16) static constexpr float g_acosLoCoef4[4] = { 1.5707963050f, 1.5707963050f, 1.5707963050f, 1.5707963050f };
|
||||
alignas(16) static constexpr float g_acosCoef1[4] = { -0.0200752200f, -0.0200752200f, -0.0200752200f, -0.0200752200f };
|
||||
alignas(16) static constexpr float g_acosCoef2[4] = { 0.0759031500f, 0.0759031500f, 0.0759031500f, 0.0759031500f };
|
||||
alignas(16) static constexpr float g_acosCoef3[4] = { -0.2126757000f, -0.2126757000f, -0.2126757000f, -0.2126757000f };
|
||||
alignas(16) static constexpr float g_atanHiRange[4] = { 2.4142135624f, 2.4142135624f, 2.4142135624f, 2.4142135624f };
|
||||
alignas(16) static constexpr float g_atanLoRange[4] = { 0.4142135624f, 0.4142135624f, 0.4142135624f, 0.4142135624f };
|
||||
alignas(16) static constexpr float g_atanCoef1[4] = { 8.05374449538e-2f, 8.05374449538e-2f, 8.05374449538e-2f, 8.05374449538e-2f };
|
||||
alignas(16) static constexpr float g_atanCoef2[4] = { -1.38776856032e-1f, -1.38776856032e-1f, -1.38776856032e-1f, -1.38776856032e-1f };
|
||||
alignas(16) static constexpr float g_atanCoef3[4] = { 1.99777106478e-1f, 1.99777106478e-1f, 1.99777106478e-1f, 1.99777106478e-1f };
|
||||
alignas(16) static constexpr float g_atanCoef4[4] = { -3.33329491539e-1f, -3.33329491539e-1f, -3.33329491539e-1f, -3.33329491539e-1f };
|
||||
|
||||
namespace Common
|
||||
{
|
||||
@@ -339,7 +339,6 @@ namespace AZ
|
||||
{
|
||||
const typename VecType::FloatType x_eq_0 = VecType::CmpEq(x, VecType::ZeroFloat());
|
||||
const typename VecType::FloatType x_ge_0 = VecType::CmpGtEq(x, VecType::ZeroFloat());
|
||||
const typename VecType::FloatType x_le_0 = VecType::CmpLtEq(x, VecType::ZeroFloat());
|
||||
const typename VecType::FloatType x_lt_0 = VecType::CmpLt(x, VecType::ZeroFloat());
|
||||
|
||||
const typename VecType::FloatType y_eq_0 = VecType::CmpEq(y, VecType::ZeroFloat());
|
||||
@@ -363,7 +362,6 @@ namespace AZ
|
||||
typename VecType::FloatType swap_sign_mask_offset = VecType::And(x_lt_0, y_lt_0);
|
||||
swap_sign_mask_offset = VecType::And(swap_sign_mask_offset, VecType::CastToFloat(FastLoadConstant<VecType>(Simd::g_negateMask)));
|
||||
|
||||
const typename VecType::FloatType offset0 = VecType::ZeroFloat();
|
||||
typename VecType::FloatType offset1 = FastLoadConstant<VecType>(g_Pi);
|
||||
offset1 = VecType::Xor(offset1, swap_sign_mask_offset);
|
||||
|
||||
|
||||
@@ -867,7 +867,6 @@ namespace AZ
|
||||
const FloatType cols0 = {{ rows[0].v[0], rows[1].v[0], rows[2].v[0], 0.0f }};
|
||||
const FloatType cols1 = {{ rows[0].v[1], rows[1].v[1], rows[2].v[1], 0.0f }};
|
||||
const FloatType cols2 = {{ rows[0].v[2], rows[1].v[2], rows[2].v[2], 0.0f }};
|
||||
const FloatType cols3 = {{ rows[0].v[3], rows[1].v[3], rows[2].v[3], 1.0f }};
|
||||
out[0] = cols0;
|
||||
out[1] = cols1;
|
||||
out[2] = cols2;
|
||||
|
||||
@@ -24,24 +24,24 @@ namespace AZ
|
||||
{
|
||||
namespace Simd
|
||||
{
|
||||
static AZ_ALIGN(constexpr float g_vec1111[4], 16) = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
static AZ_ALIGN(constexpr float g_vec1000[4], 16) = { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||
static AZ_ALIGN(constexpr float g_vec0100[4], 16) = { 0.0f, 1.0f, 0.0f, 0.0f };
|
||||
static AZ_ALIGN(constexpr float g_vec0010[4], 16) = { 0.0f, 0.0f, 1.0f, 0.0f };
|
||||
static AZ_ALIGN(constexpr float g_vec0001[4], 16) = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
static AZ_ALIGN(constexpr float g_Pi[4], 16) = { Constants::Pi, Constants::Pi, Constants::Pi, Constants::Pi };
|
||||
static AZ_ALIGN(constexpr float g_TwoPi[4], 16) = { Constants::TwoPi, Constants::TwoPi, Constants::TwoPi, Constants::TwoPi };
|
||||
static AZ_ALIGN(constexpr float g_HalfPi[4], 16) = { Constants::HalfPi, Constants::HalfPi, Constants::HalfPi, Constants::HalfPi };
|
||||
static AZ_ALIGN(constexpr float g_QuarterPi[4], 16) = { Constants::QuarterPi, Constants::QuarterPi, Constants::QuarterPi, Constants::QuarterPi };
|
||||
static AZ_ALIGN(constexpr float g_TwoOverPi[4], 16) = { Constants::TwoOverPi, Constants::TwoOverPi, Constants::TwoOverPi, Constants::TwoOverPi };
|
||||
static AZ_ALIGN(constexpr int32_t g_absMask[4], 16) = { (int32_t)0x7fffffff, (int32_t)0x7fffffff, (int32_t)0x7fffffff, (int32_t)0x7fffffff };
|
||||
static AZ_ALIGN(constexpr int32_t g_negateMask[4], 16) = { (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000 };
|
||||
static AZ_ALIGN(constexpr int32_t g_negateXMask[4], 16) = { (int32_t)0x80000000, (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x00000000 };
|
||||
static AZ_ALIGN(constexpr int32_t g_negateYMask[4], 16) = { (int32_t)0x00000000, (int32_t)0x80000000, (int32_t)0x00000000, (int32_t)0x00000000 };
|
||||
static AZ_ALIGN(constexpr int32_t g_negateZMask[4], 16) = { (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x80000000, (int32_t)0x00000000 };
|
||||
static AZ_ALIGN(constexpr int32_t g_negateWMask[4], 16) = { (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x80000000 };
|
||||
static AZ_ALIGN(constexpr int32_t g_negateXYZMask[4], 16) = { (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x00000000 };
|
||||
static AZ_ALIGN(constexpr int32_t g_wMask[4], 16) = { (int32_t)0xffffffff, (int32_t)0xffffffff, (int32_t)0xffffffff, (int32_t)0x00000000 };
|
||||
alignas(16) static constexpr float g_vec1111[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
alignas(16) static constexpr float g_vec1000[4] = { 1.0f, 0.0f, 0.0f, 0.0f };
|
||||
alignas(16) static constexpr float g_vec0100[4] = { 0.0f, 1.0f, 0.0f, 0.0f };
|
||||
alignas(16) static constexpr float g_vec0010[4] = { 0.0f, 0.0f, 1.0f, 0.0f };
|
||||
alignas(16) static constexpr float g_vec0001[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
alignas(16) static constexpr float g_Pi[4] = { Constants::Pi, Constants::Pi, Constants::Pi, Constants::Pi };
|
||||
alignas(16) static constexpr float g_TwoPi[4] = { Constants::TwoPi, Constants::TwoPi, Constants::TwoPi, Constants::TwoPi };
|
||||
alignas(16) static constexpr float g_HalfPi[4] = { Constants::HalfPi, Constants::HalfPi, Constants::HalfPi, Constants::HalfPi };
|
||||
alignas(16) static constexpr float g_QuarterPi[4] = { Constants::QuarterPi, Constants::QuarterPi, Constants::QuarterPi, Constants::QuarterPi };
|
||||
alignas(16) static constexpr float g_TwoOverPi[4] = { Constants::TwoOverPi, Constants::TwoOverPi, Constants::TwoOverPi, Constants::TwoOverPi };
|
||||
alignas(16) static constexpr int32_t g_absMask[4] = { (int32_t)0x7fffffff, (int32_t)0x7fffffff, (int32_t)0x7fffffff, (int32_t)0x7fffffff };
|
||||
alignas(16) static constexpr int32_t g_negateMask[4] = { (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000 };
|
||||
alignas(16) static constexpr int32_t g_negateXMask[4] = { (int32_t)0x80000000, (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x00000000 };
|
||||
alignas(16) static constexpr int32_t g_negateYMask[4] = { (int32_t)0x00000000, (int32_t)0x80000000, (int32_t)0x00000000, (int32_t)0x00000000 };
|
||||
alignas(16) static constexpr int32_t g_negateZMask[4] = { (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x80000000, (int32_t)0x00000000 };
|
||||
alignas(16) static constexpr int32_t g_negateWMask[4] = { (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x80000000 };
|
||||
alignas(16) static constexpr int32_t g_negateXYZMask[4] = { (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x00000000 };
|
||||
alignas(16) static constexpr int32_t g_wMask[4] = { (int32_t)0xffffffff, (int32_t)0xffffffff, (int32_t)0xffffffff, (int32_t)0x00000000 };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace AZ
|
||||
|
||||
Uuid Uuid::CreateStringSkipWarnings(const char* string, size_t stringLength, [[maybe_unused]] bool skipWarnings)
|
||||
{
|
||||
if (string == NULL)
|
||||
if (string == nullptr)
|
||||
{
|
||||
return Uuid::CreateNull();
|
||||
}
|
||||
@@ -71,7 +71,7 @@ namespace AZ
|
||||
|
||||
if (len < 32 || len > 38)
|
||||
{
|
||||
AZ_Warning("Math", skipWarnings, "Invalid UUID format %s (must be) {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} (or without dashes and braces)", string != NULL ? string : "null");
|
||||
AZ_Warning("Math", skipWarnings, "Invalid UUID format %s (must be) {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} (or without dashes and braces)", string != nullptr ? string : "null");
|
||||
return Uuid::CreateNull();
|
||||
}
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
// or _m128i and VMX ???
|
||||
AZ_ALIGN(unsigned char data[16], 16);
|
||||
alignas(16) unsigned char data[16];
|
||||
};
|
||||
} // namespace AZ
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ AllocationRecords::RegisterAllocation(void* address, size_t byteSize, size_t ali
|
||||
ai.m_timeStamp = AZStd::GetTimeNowMicroSecond();
|
||||
|
||||
// if we don't have a fileName,lineNum record the stack or if the user requested it.
|
||||
if ((fileName == 0 && m_mode == RECORD_STACK_IF_NO_FILE_LINE) || m_mode == RECORD_FULL)
|
||||
if ((fileName == nullptr && m_mode == RECORD_STACK_IF_NO_FILE_LINE) || m_mode == RECORD_FULL)
|
||||
{
|
||||
ai.m_stackFrames = m_numStackLevels ? reinterpret_cast<AZ::Debug::StackFrame*>(m_records.get_allocator().allocate(sizeof(AZ::Debug::StackFrame)*m_numStackLevels, 1)) : nullptr;
|
||||
if (ai.m_stackFrames)
|
||||
|
||||
@@ -39,9 +39,9 @@ namespace AZ
|
||||
return AZStd::hash<AZStd::string_view>{}(key);
|
||||
}
|
||||
};
|
||||
typedef AZStd::basic_string<char, AZStd::char_traits<char>, AZStdIAllocator> AMString;
|
||||
typedef AZStd::unordered_map<AMString, IAllocator*, AMStringHasher, AZStd::equal_to<>, AZStdIAllocator> AllocatorNameMap;
|
||||
typedef AZStd::unordered_map<AMString, AMString, AMStringHasher, AZStd::equal_to<>, AZStdIAllocator> AllocatorRemappings;
|
||||
using AMString = AZStd::basic_string<char, AZStd::char_traits<char>, AZStdIAllocator>;
|
||||
using AllocatorNameMap = AZStd::unordered_map<AMString, IAllocator*, AMStringHasher, AZStd::equal_to<>, AZStdIAllocator>;
|
||||
using AllocatorRemappings = AZStd::unordered_map<AMString, AMString, AMStringHasher, AZStd::equal_to<>, AZStdIAllocator>;
|
||||
|
||||
// For allocators that are created before we have an environment, we keep some module-local data for them so that we can register them
|
||||
// properly once the environment is attached.
|
||||
@@ -403,7 +403,7 @@ AllocatorManager::AddOutOfMemoryListener(const OutOfMemoryCBType& cb)
|
||||
void
|
||||
AllocatorManager::RemoveOutOfMemoryListener()
|
||||
{
|
||||
m_outOfMemoryListener = 0;
|
||||
m_outOfMemoryListener = nullptr;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -660,13 +660,13 @@ void AllocatorManager::GetAllocatorStats(size_t& allocatedBytes, size_t& capacit
|
||||
//=========================================================================
|
||||
AllocatorManager::MemoryBreak::MemoryBreak()
|
||||
{
|
||||
addressStart = NULL;
|
||||
addressEnd = NULL;
|
||||
addressStart = nullptr;
|
||||
addressEnd = nullptr;
|
||||
byteSize = 0;
|
||||
alignment = static_cast<size_t>(0xffffffff);
|
||||
name = NULL;
|
||||
name = nullptr;
|
||||
|
||||
fileName = NULL;
|
||||
fileName = nullptr;
|
||||
lineNum = -1;
|
||||
}
|
||||
|
||||
@@ -729,14 +729,14 @@ AllocatorManager::DebugBreak(void* address, const Debug::AllocationInfo& info)
|
||||
|
||||
AZ_Assert(!(m_memoryBreak[i].alignment == info.m_alignment), "User triggered breakpoint - alignment (%d)", info.m_alignment);
|
||||
AZ_Assert(!(m_memoryBreak[i].byteSize == info.m_byteSize), "User triggered breakpoint - allocation size (%d)", info.m_byteSize);
|
||||
AZ_Assert(!(info.m_name != NULL && m_memoryBreak[i].name != NULL && strcmp(m_memoryBreak[i].name, info.m_name) == 0), "User triggered breakpoint - name \"%s\"", info.m_name);
|
||||
AZ_Assert(!(info.m_name != nullptr && m_memoryBreak[i].name != nullptr && strcmp(m_memoryBreak[i].name, info.m_name) == 0), "User triggered breakpoint - name \"%s\"", info.m_name);
|
||||
if (m_memoryBreak[i].lineNum != 0)
|
||||
{
|
||||
AZ_Assert(!(info.m_fileName != NULL && m_memoryBreak[i].fileName != NULL && strcmp(m_memoryBreak[i].fileName, info.m_fileName) == 0 && m_memoryBreak[i].lineNum == info.m_lineNum), "User triggered breakpoint - file/line number : %s(%d)", info.m_fileName, info.m_lineNum);
|
||||
AZ_Assert(!(info.m_fileName != nullptr && m_memoryBreak[i].fileName != nullptr && strcmp(m_memoryBreak[i].fileName, info.m_fileName) == 0 && m_memoryBreak[i].lineNum == info.m_lineNum), "User triggered breakpoint - file/line number : %s(%d)", info.m_fileName, info.m_lineNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Assert(!(info.m_fileName != NULL && m_memoryBreak[i].fileName != NULL && strcmp(m_memoryBreak[i].fileName, info.m_fileName) == 0), "User triggered breakpoint - file name \"%s\"", info.m_fileName);
|
||||
AZ_Assert(!(info.m_fileName != nullptr && m_memoryBreak[i].fileName != nullptr && strcmp(m_memoryBreak[i].fileName, info.m_fileName) == 0), "User triggered breakpoint - file name \"%s\"", info.m_fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,7 @@ namespace AZ
|
||||
public:
|
||||
void ActivateAllocators()
|
||||
{
|
||||
// Note the parameter pack expansion, this creates the equivalent of a fold expression
|
||||
// For each type, call InitAllocator<T>(), then put 0 in the initializer list
|
||||
std::initializer_list<int> init{(InitAllocator<Allocators>(), 0)...};
|
||||
(InitAllocator<Allocators>(), ...);
|
||||
}
|
||||
|
||||
void DeactivateAllocators()
|
||||
|
||||
@@ -22,7 +22,7 @@ using namespace AZ;
|
||||
//=========================================================================
|
||||
BestFitExternalMapAllocator::BestFitExternalMapAllocator()
|
||||
: AllocatorBase(this, "BestFitExternalMapAllocator", "Best fit allocator with external tracking storage!")
|
||||
, m_schema(NULL)
|
||||
, m_schema(nullptr)
|
||||
{}
|
||||
|
||||
//=========================================================================
|
||||
@@ -47,7 +47,7 @@ BestFitExternalMapAllocator::Create(const Descriptor& desc)
|
||||
schemaDesc.m_memoryBlockByteSize = desc.m_memoryBlockByteSize;
|
||||
|
||||
m_schema = azcreate(BestFitExternalMapSchema, (schemaDesc), SystemAllocator);
|
||||
if (m_schema == NULL)
|
||||
if (m_schema == nullptr)
|
||||
{
|
||||
isReady = false;
|
||||
}
|
||||
@@ -63,7 +63,7 @@ void
|
||||
BestFitExternalMapAllocator::Destroy()
|
||||
{
|
||||
azdestroy(m_schema, SystemAllocator);
|
||||
m_schema = NULL;
|
||||
m_schema = nullptr;
|
||||
}
|
||||
|
||||
AllocatorDebugConfig BestFitExternalMapAllocator::GetDebugConfig()
|
||||
@@ -89,7 +89,7 @@ BestFitExternalMapAllocator::Allocate(size_type byteSize, size_type alignment, i
|
||||
byteSize = MemorySizeAdjustedUp(byteSize);
|
||||
|
||||
BestFitExternalMapAllocator::pointer_type address = m_schema->Allocate(byteSize, alignment, flags);
|
||||
if (address == 0)
|
||||
if (address == nullptr)
|
||||
{
|
||||
if (!OnOutOfMemory(byteSize, alignment, flags, name, fileName, lineNum))
|
||||
{
|
||||
@@ -100,7 +100,7 @@ BestFitExternalMapAllocator::Allocate(size_type byteSize, size_type alignment, i
|
||||
}
|
||||
}
|
||||
|
||||
AZ_Assert(address != 0, "BestFitExternalMapAllocator: Failed to allocate %d bytes aligned on %d (flags: 0x%08x) %s : %s (%d)!", byteSize, alignment, flags, name ? name : "(no name)", fileName ? fileName : "(no file name)", lineNum);
|
||||
AZ_Assert(address != nullptr, "BestFitExternalMapAllocator: Failed to allocate %d bytes aligned on %d (flags: 0x%08x) %s : %s (%d)!", byteSize, alignment, flags, name ? name : "(no name)", fileName ? fileName : "(no file name)", lineNum);
|
||||
AZ_MEMORY_PROFILE(ProfileAllocation(address, byteSize, alignment, name, fileName, lineNum, suppressStackRecord + 1));
|
||||
|
||||
return address;
|
||||
@@ -145,7 +145,7 @@ BestFitExternalMapAllocator::ReAllocate(pointer_type ptr, size_type newSize, siz
|
||||
(void)newSize;
|
||||
(void)newAlignment;
|
||||
AZ_Assert(false, "Not supported!");
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
|
||||
@@ -18,15 +18,15 @@ using namespace AZ;
|
||||
BestFitExternalMapSchema::BestFitExternalMapSchema(const Descriptor& desc)
|
||||
: m_desc(desc)
|
||||
, m_used(0)
|
||||
, m_freeChunksMap(FreeMapType::key_compare(), AZStdIAllocator(desc.m_mapAllocator != NULL ? desc.m_mapAllocator : &AllocatorInstance<SystemAllocator>::Get()))
|
||||
, m_allocChunksMap(AllocMapType::hasher(), AllocMapType::key_eq(), AZStdIAllocator(desc.m_mapAllocator != NULL ? desc.m_mapAllocator : &AllocatorInstance<SystemAllocator>::Get()))
|
||||
, m_freeChunksMap(FreeMapType::key_compare(), AZStdIAllocator(desc.m_mapAllocator != nullptr ? desc.m_mapAllocator : &AllocatorInstance<SystemAllocator>::Get()))
|
||||
, m_allocChunksMap(AllocMapType::hasher(), AllocMapType::key_eq(), AZStdIAllocator(desc.m_mapAllocator != nullptr ? desc.m_mapAllocator : &AllocatorInstance<SystemAllocator>::Get()))
|
||||
{
|
||||
if (m_desc.m_mapAllocator == NULL)
|
||||
if (m_desc.m_mapAllocator == nullptr)
|
||||
{
|
||||
m_desc.m_mapAllocator = &AllocatorInstance<SystemAllocator>::Get(); // used as our sub allocator
|
||||
}
|
||||
AZ_Assert(m_desc.m_memoryBlockByteSize > 0, "You must provide memory block size!");
|
||||
AZ_Assert(m_desc.m_memoryBlock != NULL, "You must provide memory block allocated as you with!");
|
||||
AZ_Assert(m_desc.m_memoryBlock != nullptr, "You must provide memory block allocated as you with!");
|
||||
//if( m_desc.m_memoryBlock == NULL) there is no point to automate this cause we need to flag this memory special, otherwise there is no point to use this allocator at all
|
||||
// m_desc.m_memoryBlock = azmalloc(SystemAllocator,m_desc.m_memoryBlockByteSize,16);
|
||||
m_freeChunksMap.insert(AZStd::make_pair(m_desc.m_memoryBlockByteSize, reinterpret_cast<char*>(m_desc.m_memoryBlock)));
|
||||
@@ -40,13 +40,13 @@ BestFitExternalMapSchema::pointer_type
|
||||
BestFitExternalMapSchema::Allocate(size_type byteSize, size_type alignment, int flags)
|
||||
{
|
||||
(void)flags;
|
||||
char* address = NULL;
|
||||
char* address = nullptr;
|
||||
AZ_Assert(alignment > 0 && (alignment & (alignment - 1)) == 0, "Alignment must be >0 and power of 2!");
|
||||
for (int i = 0; i < 2; ++i) // max 2 attempts to allocate
|
||||
{
|
||||
FreeMapType::iterator iter = m_freeChunksMap.find(byteSize);
|
||||
size_t blockSize = 0;
|
||||
char* blockAddress = NULL;
|
||||
char* blockAddress = nullptr;
|
||||
size_t preAllocBlockSize = 0;
|
||||
while (iter != m_freeChunksMap.end())
|
||||
{
|
||||
@@ -64,7 +64,7 @@ BestFitExternalMapSchema::Allocate(size_type byteSize, size_type alignment, int
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
if (address != NULL)
|
||||
if (address != nullptr)
|
||||
{
|
||||
// split blocks
|
||||
if (preAllocBlockSize) // if we have a block before the alignment
|
||||
@@ -94,7 +94,7 @@ BestFitExternalMapSchema::Allocate(size_type byteSize, size_type alignment, int
|
||||
void
|
||||
BestFitExternalMapSchema::DeAllocate(pointer_type ptr)
|
||||
{
|
||||
if (ptr == 0)
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -107,17 +107,17 @@ namespace AZ
|
||||
m_used = 0;
|
||||
|
||||
m_desc = desc;
|
||||
m_subAllocator = 0;
|
||||
m_subAllocator = nullptr;
|
||||
|
||||
for (int i = 0; i < Descriptor::m_maxNumBlocks; ++i)
|
||||
{
|
||||
m_memSpaces[i] = 0;
|
||||
m_memSpaces[i] = nullptr;
|
||||
m_ownMemoryBlock[i] = false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_desc.m_numMemoryBlocks; ++i)
|
||||
{
|
||||
if (m_desc.m_memoryBlocks[i] == 0) // Allocate memory block if requested!
|
||||
if (m_desc.m_memoryBlocks[i] == nullptr) // Allocate memory block if requested!
|
||||
{
|
||||
AZ_Assert(AllocatorInstance<SystemAllocator>::IsReady(), "You requested to allocate memory using the system allocator, but it's not created yet!");
|
||||
m_subAllocator = &AllocatorInstance<SystemAllocator>::Get();
|
||||
@@ -152,7 +152,7 @@ namespace AZ
|
||||
if (m_memSpaces[i])
|
||||
{
|
||||
AZDLMalloc::destroy_mspace(m_memSpaces[i]);
|
||||
m_memSpaces[i] = 0;
|
||||
m_memSpaces[i] = nullptr;
|
||||
|
||||
if (m_ownMemoryBlock[i])
|
||||
{
|
||||
@@ -172,7 +172,7 @@ namespace AZ
|
||||
AZ_UNUSED(lineNum);
|
||||
AZ_UNUSED(suppressStackRecord);
|
||||
int blockId = flags;
|
||||
AZ_Assert(m_memSpaces[blockId]!=0, "Invalid block id!");
|
||||
AZ_Assert(m_memSpaces[blockId]!=nullptr, "Invalid block id!");
|
||||
HeapSchema::pointer_type address = AZDLMalloc::mspace_memalign(m_memSpaces[blockId], alignment, byteSize);
|
||||
if (address)
|
||||
{
|
||||
@@ -186,7 +186,7 @@ namespace AZ
|
||||
{
|
||||
AZ_UNUSED(byteSize);
|
||||
AZ_UNUSED(alignment);
|
||||
if (ptr==0)
|
||||
if (ptr==nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -194,7 +194,7 @@ namespace AZ
|
||||
// if we use m_spaces just count the chunk sizes.
|
||||
m_used -= ChunckSize(ptr);
|
||||
#ifdef FOOTERS
|
||||
AZDLMalloc::mspace_free(0, ptr); ///< We use footers so we know which memspace the pointer belongs to.
|
||||
AZDLMalloc::mspace_free(nullptr, ptr); ///< We use footers so we know which memspace the pointer belongs to.
|
||||
#else
|
||||
int i = 0;
|
||||
for (; i < m_desc.m_numMemoryBlocks; ++i)
|
||||
@@ -248,7 +248,7 @@ namespace AZ
|
||||
HeapSchema::ChunckSize(pointer_type ptr)
|
||||
{
|
||||
// based on azmalloc_usable_size + the overhead
|
||||
if (ptr != 0)
|
||||
if (ptr != nullptr)
|
||||
{
|
||||
mchunkptr p = mem2chunk(ptr);
|
||||
//if (is_inuse(p)) // we can even skip this check since we track for double free and so on anyway
|
||||
|
||||
@@ -784,17 +784,17 @@ namespace AZ {
|
||||
// size == 0 acts as free
|
||||
void* realloc(void* ptr, size_t size)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
return alloc(size);
|
||||
}
|
||||
if (size == 0)
|
||||
{
|
||||
free(ptr);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
debug_check(ptr);
|
||||
void* newPtr = NULL;
|
||||
void* newPtr = nullptr;
|
||||
if (ptr_in_bucket(ptr))
|
||||
{
|
||||
if (is_small_allocation(size)) // no point to check m_isPoolAllocations as if it's false pointer can't be in a bucket.
|
||||
@@ -853,21 +853,21 @@ namespace AZ {
|
||||
{
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
if (ptr == NULL)
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
return alloc(size, alignment);
|
||||
}
|
||||
if (size == 0)
|
||||
{
|
||||
free(ptr);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
if ((size_t)ptr & (alignment - 1))
|
||||
{
|
||||
void* newPtr = alloc(size, alignment);
|
||||
if (!newPtr)
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
size_t count = this->size(ptr);
|
||||
if (count > size)
|
||||
@@ -879,7 +879,7 @@ namespace AZ {
|
||||
return newPtr;
|
||||
}
|
||||
debug_check(ptr);
|
||||
void* newPtr = NULL;
|
||||
void* newPtr = nullptr;
|
||||
if (ptr_in_bucket(ptr))
|
||||
{
|
||||
if (is_small_allocation(size) && alignment <= MAX_SMALL_ALLOCATION) // no point to check m_isPoolAllocations as if it was false, pointer can't be in a bucket
|
||||
@@ -931,7 +931,7 @@ namespace AZ {
|
||||
// returns the size of the resulting memory block
|
||||
inline size_t resize(void* ptr, size_t size)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -957,7 +957,7 @@ namespace AZ {
|
||||
// query the size of the memory block
|
||||
inline size_t size(void* ptr) const
|
||||
{
|
||||
if (ptr == NULL)
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -993,7 +993,7 @@ namespace AZ {
|
||||
// free the memory block
|
||||
inline void free(void* ptr)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1009,7 +1009,7 @@ namespace AZ {
|
||||
// free the memory block supplying the original size with DEFAULT_ALIGNMENT
|
||||
inline void free(void* ptr, size_t origSize)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1027,7 +1027,7 @@ namespace AZ {
|
||||
// free the memory block supplying the original size and alignment
|
||||
inline void free(void* ptr, size_t origSize, size_t oldAlignment)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1134,10 +1134,10 @@ namespace AZ {
|
||||
// If m_systemChunkSize is specified, use that size for allocating tree blocks from the OS
|
||||
// m_treePageAlignment should be OS_VIRTUAL_PAGE_SIZE in all cases with this trait as we work
|
||||
// with virtual memory addresses when the tree grows and we cannot specify an alignment in all cases
|
||||
: m_treePageSize(desc.m_fixedMemoryBlock != NULL ? desc.m_pageSize :
|
||||
: m_treePageSize(desc.m_fixedMemoryBlock != nullptr ? desc.m_pageSize :
|
||||
desc.m_systemChunkSize != 0 ? desc.m_systemChunkSize : OS_VIRTUAL_PAGE_SIZE)
|
||||
, m_treePageAlignment(desc.m_pageSize)
|
||||
, m_poolPageSize(desc.m_fixedMemoryBlock != NULL ? desc.m_poolPageSize : OS_VIRTUAL_PAGE_SIZE)
|
||||
, m_poolPageSize(desc.m_fixedMemoryBlock != nullptr ? desc.m_poolPageSize : OS_VIRTUAL_PAGE_SIZE)
|
||||
, m_subAllocator(desc.m_subAllocator)
|
||||
{
|
||||
#ifdef DEBUG_ALLOCATOR
|
||||
@@ -1246,7 +1246,7 @@ namespace AZ {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const HpAllocator::page* HpAllocator::bucket::get_free_page() const
|
||||
@@ -1259,7 +1259,7 @@ namespace AZ {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* HpAllocator::bucket::alloc(page* p)
|
||||
@@ -1359,7 +1359,7 @@ namespace AZ {
|
||||
p = bucket_grow(bsize, mBuckets[bi].marker());
|
||||
if (!p)
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
mBuckets[bi].add_free_page(p);
|
||||
}
|
||||
@@ -1385,7 +1385,7 @@ namespace AZ {
|
||||
p = bucket_grow(bsize, mBuckets[bi].marker());
|
||||
if (!p)
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
mBuckets[bi].add_free_page(p);
|
||||
}
|
||||
@@ -1406,7 +1406,7 @@ namespace AZ {
|
||||
void* newPtr = bucket_alloc(size);
|
||||
if (!newPtr)
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
memcpy(newPtr, ptr, AZStd::GetMin(elemSize - MEMORY_GUARD_SIZE, size - MEMORY_GUARD_SIZE));
|
||||
bucket_free(ptr);
|
||||
@@ -1426,7 +1426,7 @@ namespace AZ {
|
||||
void* newPtr = bucket_alloc_direct(bucket_spacing_function(AZ::SizeAlignUp(size, alignment)));
|
||||
if (!newPtr)
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
memcpy(newPtr, ptr, AZStd::GetMin(elemSize - MEMORY_GUARD_SIZE, size - MEMORY_GUARD_SIZE));
|
||||
bucket_free(ptr);
|
||||
@@ -1638,7 +1638,7 @@ namespace AZ {
|
||||
// create a dummy block to avoid prev() NULL checks and allow easy block shifts
|
||||
// potentially this dummy block might grow (due to shift_block) but not more than sizeof(free_node)
|
||||
block_header* front = (block_header*)mem;
|
||||
front->prev(0);
|
||||
front->prev(nullptr);
|
||||
front->size(0);
|
||||
front->set_used();
|
||||
block_header* back = (block_header*)front->mem();
|
||||
@@ -1777,7 +1777,7 @@ namespace AZ {
|
||||
newBl = tree_grow(size);
|
||||
if (!newBl)
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
HPPA_ASSERT(!newBl->used());
|
||||
@@ -1956,7 +1956,7 @@ namespace AZ {
|
||||
tree_free(ptr);
|
||||
return newPtr;
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* HpAllocator::tree_realloc_aligned(void* ptr, size_t size, size_t alignment)
|
||||
@@ -2044,7 +2044,7 @@ namespace AZ {
|
||||
tree_free(ptr);
|
||||
return newPtr;
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t HpAllocator::tree_resize(void* ptr, size_t size)
|
||||
@@ -2121,7 +2121,7 @@ namespace AZ {
|
||||
HPPA_ASSERT(!bl->used());
|
||||
HPPA_ASSERT(bl->prev() && bl->prev()->used());
|
||||
HPPA_ASSERT(bl->next() && bl->next()->used());
|
||||
if (bl->prev()->prev() == NULL && bl->next()->size() == 0)
|
||||
if (bl->prev()->prev() == nullptr && bl->next()->size() == 0)
|
||||
{
|
||||
tree_detach(bl);
|
||||
char* memStart = (char*)bl->prev();
|
||||
@@ -2539,11 +2539,11 @@ namespace AZ {
|
||||
if (m_desc.m_fixedMemoryBlockByteSize > 0)
|
||||
{
|
||||
AZ_Assert((m_desc.m_fixedMemoryBlockByteSize & (m_desc.m_pageSize - 1)) == 0, "Memory block size %d MUST be multiples of the of the page size %d!", m_desc.m_fixedMemoryBlockByteSize, m_desc.m_pageSize);
|
||||
if (m_desc.m_fixedMemoryBlock == NULL)
|
||||
if (m_desc.m_fixedMemoryBlock == nullptr)
|
||||
{
|
||||
AZ_Assert(m_desc.m_subAllocator != NULL, "Sub allocator must point to a valid allocator if m_fixedMemoryBlock is NOT allocated (NULL)!");
|
||||
AZ_Assert(m_desc.m_subAllocator != nullptr, "Sub allocator must point to a valid allocator if m_fixedMemoryBlock is NOT allocated (NULL)!");
|
||||
m_desc.m_fixedMemoryBlock = m_desc.m_subAllocator->Allocate(m_desc.m_fixedMemoryBlockByteSize, m_desc.m_fixedMemoryBlockAlignment, 0, "HphaSchema", __FILE__, __LINE__, 1);
|
||||
AZ_Assert(m_desc.m_fixedMemoryBlock != NULL, "Failed to allocate %d bytes!", m_desc.m_fixedMemoryBlockByteSize);
|
||||
AZ_Assert(m_desc.m_fixedMemoryBlock != nullptr, "Failed to allocate %d bytes!", m_desc.m_fixedMemoryBlockByteSize);
|
||||
m_ownMemoryBlock = true;
|
||||
}
|
||||
AZ_Assert((reinterpret_cast<size_t>(m_desc.m_fixedMemoryBlock) & static_cast<size_t>(desc.m_fixedMemoryBlockAlignment - 1)) == 0, "Memory block must be page size (%d bytes) aligned!", desc.m_fixedMemoryBlockAlignment);
|
||||
@@ -2570,7 +2570,7 @@ namespace AZ {
|
||||
if (m_ownMemoryBlock)
|
||||
{
|
||||
m_desc.m_subAllocator->DeAllocate(m_desc.m_fixedMemoryBlock, m_desc.m_fixedMemoryBlockByteSize, m_desc.m_fixedMemoryBlockAlignment);
|
||||
m_desc.m_fixedMemoryBlock = NULL;
|
||||
m_desc.m_fixedMemoryBlock = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2587,7 +2587,7 @@ namespace AZ {
|
||||
(void)lineNum;
|
||||
(void)suppressStackRecord;
|
||||
pointer_type address = m_allocator->alloc(byteSize, alignment);
|
||||
if (address == NULL)
|
||||
if (address == nullptr)
|
||||
{
|
||||
GarbageCollect();
|
||||
address = m_allocator->alloc(byteSize, alignment);
|
||||
@@ -2603,7 +2603,7 @@ namespace AZ {
|
||||
HphaSchema::ReAllocate(pointer_type ptr, size_type newSize, size_type newAlignment)
|
||||
{
|
||||
pointer_type address = m_allocator->realloc(ptr, newSize, newAlignment);
|
||||
if (address == NULL && newSize > 0)
|
||||
if (address == nullptr && newSize > 0)
|
||||
{
|
||||
GarbageCollect();
|
||||
address = m_allocator->realloc(ptr, newSize, newAlignment);
|
||||
@@ -2618,7 +2618,7 @@ namespace AZ {
|
||||
void
|
||||
HphaSchema::DeAllocate(pointer_type ptr, size_type size, size_type alignment)
|
||||
{
|
||||
if (ptr == 0)
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace AZ
|
||||
|
||||
m_allAllocatorRecords.push_back(allocator->GetRecords());
|
||||
|
||||
if (m_output == NULL)
|
||||
if (m_output == nullptr)
|
||||
{
|
||||
return; // we have no active output
|
||||
}
|
||||
@@ -154,7 +154,7 @@ namespace AZ
|
||||
delete allocatorRecords;
|
||||
allocator->SetRecords(nullptr);
|
||||
|
||||
if (m_output == NULL)
|
||||
if (m_output == nullptr)
|
||||
{
|
||||
return; // we have no active output
|
||||
}
|
||||
@@ -173,7 +173,7 @@ namespace AZ
|
||||
if (records)
|
||||
{
|
||||
const AllocationInfo* info = records->RegisterAllocation(address, byteSize, alignment, name, fileName, lineNum, stackSuppressCount + 1);
|
||||
if (m_output == NULL)
|
||||
if (m_output == nullptr)
|
||||
{
|
||||
return; // we have no active output
|
||||
}
|
||||
@@ -226,7 +226,7 @@ namespace AZ
|
||||
{
|
||||
records->UnregisterAllocation(address, byteSize, alignment, info);
|
||||
|
||||
if (m_output == NULL)
|
||||
if (m_output == nullptr)
|
||||
{
|
||||
return; // we have no active output
|
||||
}
|
||||
@@ -261,7 +261,7 @@ namespace AZ
|
||||
{
|
||||
records->ResizeAllocation(address, newSize);
|
||||
|
||||
if (m_output == NULL)
|
||||
if (m_output == nullptr)
|
||||
{
|
||||
return; // we have no active output
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace AZ
|
||||
address = AZ_OS_MALLOC(byteSize, alignment);
|
||||
}
|
||||
|
||||
if (address == 0 && byteSize > 0)
|
||||
if (address == nullptr && byteSize > 0)
|
||||
{
|
||||
AZ_Printf("Memory", "======================================================\n");
|
||||
AZ_Printf("Memory", "OSAllocator run out of system memory!\nWe can't track the debug allocator, since it's used for tracking and pipes trought the OS... here are the other allocator status:\n");
|
||||
|
||||
@@ -216,9 +216,9 @@ namespace AZ
|
||||
class OverrunDetectionSchemaImpl
|
||||
{
|
||||
public:
|
||||
typedef void* pointer_type;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
using pointer_type = void *;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
|
||||
OverrunDetectionSchemaImpl(const OverrunDetectionSchema::Descriptor& desc);
|
||||
~OverrunDetectionSchemaImpl();
|
||||
@@ -241,8 +241,8 @@ namespace AZ
|
||||
Internal::AllocationRecord* CreateAllocationRecord(void* p, size_t size) const;
|
||||
|
||||
private:
|
||||
typedef AZStd::mutex mutex_type;
|
||||
typedef AZStd::lock_guard<mutex_type> lock_type;
|
||||
using mutex_type = AZStd::mutex;
|
||||
using lock_type = AZStd::lock_guard<mutex_type>;
|
||||
|
||||
AZStd::unique_ptr<OverrunDetectionSchema::PlatformAllocator> m_platformAllocator;
|
||||
mutex_type m_mutex;
|
||||
@@ -511,7 +511,7 @@ AZ::OverrunDetectionSchemaImpl::OverrunDetectionSchemaImpl(const OverrunDetectio
|
||||
{
|
||||
m_platformAllocator.reset(new Internal::PlatformOverrunDetectionSchema);
|
||||
|
||||
auto info = m_platformAllocator->GetSystemInformation();
|
||||
[[maybe_unused]] auto info = m_platformAllocator->GetSystemInformation();
|
||||
AZ_Assert(info.m_pageSize == Internal::ODS_PAGE_SIZE, "System page size %d does not equal expected page size %d", info.m_pageSize, Internal::ODS_PAGE_SIZE);
|
||||
AZ_Assert(info.m_minimumAllocationSize == Internal::ODS_ALLOCATION_SIZE, "System minimum allocation size %d does not equal expected size %d", info.m_minimumAllocationSize, Internal::ODS_ALLOCATION_SIZE);
|
||||
|
||||
|
||||
@@ -278,7 +278,7 @@ namespace AZ
|
||||
Page* page = reinterpret_cast<Page*>(memBlock);
|
||||
if (!page->m_magic.Validate())
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
return page;
|
||||
}
|
||||
@@ -403,7 +403,7 @@ PoolAllocation<Allocator>::Allocate(size_t byteSize, size_t alignment)
|
||||
|
||||
u32 bucketIndex = static_cast<u32>((byteSize >> m_minAllocationShift)-1);
|
||||
BucketType& bucket = m_buckets[bucketIndex];
|
||||
PageType* page = 0;
|
||||
PageType* page = nullptr;
|
||||
if (!bucket.m_pages.empty())
|
||||
{
|
||||
page = &bucket.m_pages.front();
|
||||
@@ -411,7 +411,7 @@ PoolAllocation<Allocator>::Allocate(size_t byteSize, size_t alignment)
|
||||
// check if we have free slot in the page
|
||||
if (page->m_freeList.empty())
|
||||
{
|
||||
page = 0;
|
||||
page = nullptr;
|
||||
}
|
||||
else if (page->m_freeList.size()==1)
|
||||
{
|
||||
@@ -464,7 +464,7 @@ AZ_INLINE void
|
||||
PoolAllocation<Allocator>::DeAllocate(void* ptr)
|
||||
{
|
||||
PageType* page = m_allocator->PageFromAddress(ptr);
|
||||
if (page==NULL)
|
||||
if (page==nullptr)
|
||||
{
|
||||
AZ_Error("Memory", false, "Address 0x%08x is not in the ThreadPool!", ptr);
|
||||
return;
|
||||
@@ -503,7 +503,7 @@ PoolAllocation<Allocator>::DeAllocate(void* ptr)
|
||||
m_allocator->PushFreePage(page);
|
||||
}
|
||||
}
|
||||
else if (frontPage->m_next != 0)
|
||||
else if (frontPage->m_next != nullptr)
|
||||
{
|
||||
// if the next page has free slots free the current page
|
||||
if (frontPage->m_next->m_freeList.size() < maxElementsPerBucket)
|
||||
@@ -584,7 +584,7 @@ PoolAllocation<Allocator>::GarbageCollect(bool isForceFreeAllPages)
|
||||
// [9/15/2009]
|
||||
//=========================================================================
|
||||
PoolSchema::PoolSchema(const Descriptor& desc)
|
||||
: m_impl(NULL)
|
||||
: m_impl(nullptr)
|
||||
{
|
||||
(void)desc; // ignored here, applied in Create()
|
||||
}
|
||||
@@ -595,7 +595,7 @@ PoolSchema::PoolSchema(const Descriptor& desc)
|
||||
//=========================================================================
|
||||
PoolSchema::~PoolSchema()
|
||||
{
|
||||
AZ_Assert(m_impl==NULL, "You did not destroy the pool schema!");
|
||||
AZ_Assert(m_impl==nullptr, "You did not destroy the pool schema!");
|
||||
delete m_impl;
|
||||
}
|
||||
|
||||
@@ -605,12 +605,12 @@ PoolSchema::~PoolSchema()
|
||||
//=========================================================================
|
||||
bool PoolSchema::Create(const Descriptor& desc)
|
||||
{
|
||||
AZ_Assert(m_impl==NULL, "PoolSchema already created!");
|
||||
if (m_impl == NULL)
|
||||
AZ_Assert(m_impl==nullptr, "PoolSchema already created!");
|
||||
if (m_impl == nullptr)
|
||||
{
|
||||
m_impl = aznew PoolSchemaImpl(desc);
|
||||
}
|
||||
return (m_impl!=NULL);
|
||||
return (m_impl!=nullptr);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -620,7 +620,7 @@ bool PoolSchema::Create(const Descriptor& desc)
|
||||
bool PoolSchema::Destroy()
|
||||
{
|
||||
delete m_impl;
|
||||
m_impl = NULL;
|
||||
m_impl = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -751,7 +751,7 @@ PoolSchema::GetSubAllocator()
|
||||
PoolSchemaImpl::PoolSchemaImpl(const PoolSchema::Descriptor& desc)
|
||||
: m_pageAllocator(desc.m_pageAllocator ? desc.m_pageAllocator : &AllocatorInstance<SystemAllocator>::Get())
|
||||
, m_allocator(this, desc.m_pageSize, desc.m_minAllocationSize, desc.m_maxAllocationSize)
|
||||
, m_staticDataBlock(0)
|
||||
, m_staticDataBlock(nullptr)
|
||||
, m_numStaticPages(desc.m_numStaticPages)
|
||||
, m_isDynamic(desc.m_isDynamic)
|
||||
, m_pageSize(desc.m_pageSize)
|
||||
@@ -851,7 +851,7 @@ PoolSchemaImpl::AllocationSize(PoolSchema::pointer_type ptr)
|
||||
AZ_FORCE_INLINE PoolSchemaImpl::Page*
|
||||
PoolSchemaImpl::PopFreePage()
|
||||
{
|
||||
Page* page = 0;
|
||||
Page* page = nullptr;
|
||||
if (!m_freePages.empty())
|
||||
{
|
||||
page = &m_freePages.front();
|
||||
@@ -938,7 +938,7 @@ PoolSchemaImpl::Page::SetupFreeList(size_t elementSize, size_t pageDataBlockSize
|
||||
// [9/15/2009]
|
||||
//=========================================================================
|
||||
ThreadPoolSchema::ThreadPoolSchema(GetThreadPoolData getThreadPoolData, SetThreadPoolData setThreadPoolData)
|
||||
: m_impl(NULL)
|
||||
: m_impl(nullptr)
|
||||
, m_threadPoolGetter(getThreadPoolData)
|
||||
, m_threadPoolSetter(setThreadPoolData)
|
||||
{
|
||||
@@ -950,7 +950,7 @@ ThreadPoolSchema::ThreadPoolSchema(GetThreadPoolData getThreadPoolData, SetThrea
|
||||
//=========================================================================
|
||||
ThreadPoolSchema::~ThreadPoolSchema()
|
||||
{
|
||||
AZ_Assert(m_impl==NULL, "You did not destroy the thread pool schema!");
|
||||
AZ_Assert(m_impl==nullptr, "You did not destroy the thread pool schema!");
|
||||
delete m_impl;
|
||||
}
|
||||
|
||||
@@ -960,12 +960,12 @@ ThreadPoolSchema::~ThreadPoolSchema()
|
||||
//=========================================================================
|
||||
bool ThreadPoolSchema::Create(const Descriptor& desc)
|
||||
{
|
||||
AZ_Assert(m_impl==NULL, "PoolSchema already created!");
|
||||
if (m_impl == NULL)
|
||||
AZ_Assert(m_impl==nullptr, "PoolSchema already created!");
|
||||
if (m_impl == nullptr)
|
||||
{
|
||||
m_impl = aznew ThreadPoolSchemaImpl(desc, m_threadPoolGetter, m_threadPoolSetter);
|
||||
}
|
||||
return (m_impl!=NULL);
|
||||
return (m_impl!=nullptr);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -975,7 +975,7 @@ bool ThreadPoolSchema::Create(const Descriptor& desc)
|
||||
bool ThreadPoolSchema::Destroy()
|
||||
{
|
||||
delete m_impl;
|
||||
m_impl = NULL;
|
||||
m_impl = nullptr;
|
||||
return true;
|
||||
}
|
||||
//=========================================================================
|
||||
@@ -1099,7 +1099,7 @@ ThreadPoolSchemaImpl::ThreadPoolSchemaImpl(const ThreadPoolSchema::Descriptor& d
|
||||
: m_threadPoolGetter(threadPoolGetter)
|
||||
, m_threadPoolSetter(threadPoolSetter)
|
||||
, m_pageAllocator(desc.m_pageAllocator)
|
||||
, m_staticDataBlock(0)
|
||||
, m_staticDataBlock(nullptr)
|
||||
, m_numStaticPages(desc.m_numStaticPages)
|
||||
, m_pageSize(desc.m_pageSize)
|
||||
, m_minAllocationSize(desc.m_minAllocationSize)
|
||||
@@ -1112,7 +1112,7 @@ ThreadPoolSchemaImpl::ThreadPoolSchemaImpl(const ThreadPoolSchema::Descriptor& d
|
||||
SetCriticalSectionSpinCount(m_mutex.native_handle(), 4000);
|
||||
# endif
|
||||
|
||||
if (m_pageAllocator == 0)
|
||||
if (m_pageAllocator == nullptr)
|
||||
{
|
||||
m_pageAllocator = &AllocatorInstance<SystemAllocator>::Get(); // use the SystemAllocator if no page allocator is provided
|
||||
}
|
||||
@@ -1211,7 +1211,7 @@ ThreadPoolSchemaImpl::Allocate(ThreadPoolSchema::size_type byteSize, ThreadPoolS
|
||||
{
|
||||
// deallocate elements if they were freed from other threads
|
||||
Page::FakeNodeLF* fakeLFNode;
|
||||
while ((fakeLFNode = threadData->m_freedElements.pop())!=0)
|
||||
while ((fakeLFNode = threadData->m_freedElements.pop())!=nullptr)
|
||||
{
|
||||
threadData->m_allocator.DeAllocate(fakeLFNode);
|
||||
}
|
||||
@@ -1228,12 +1228,12 @@ void
|
||||
ThreadPoolSchemaImpl::DeAllocate(ThreadPoolSchema::pointer_type ptr)
|
||||
{
|
||||
Page* page = PageFromAddress(ptr);
|
||||
if (page==NULL)
|
||||
if (page==nullptr)
|
||||
{
|
||||
AZ_Error("Memory", false, "Address 0x%08x is not in the ThreadPool!", ptr);
|
||||
return;
|
||||
}
|
||||
AZ_Assert(page->m_threadData!=0, ("We must have valid page thread data for the page!"));
|
||||
AZ_Assert(page->m_threadData!=nullptr, ("We must have valid page thread data for the page!"));
|
||||
ThreadPoolData* threadData = m_threadPoolGetter();
|
||||
if (threadData == page->m_threadData)
|
||||
{
|
||||
@@ -1262,11 +1262,11 @@ ThreadPoolSchema::size_type
|
||||
ThreadPoolSchemaImpl::AllocationSize(ThreadPoolSchema::pointer_type ptr)
|
||||
{
|
||||
Page* page = PageFromAddress(ptr);
|
||||
if (page==NULL)
|
||||
if (page==nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
AZ_Assert(page->m_threadData!=0, ("We must have valid page thread data for the page!"));
|
||||
AZ_Assert(page->m_threadData!=nullptr, ("We must have valid page thread data for the page!"));
|
||||
return page->m_threadData->m_allocator.AllocationSize(ptr);
|
||||
}
|
||||
|
||||
@@ -1282,7 +1282,7 @@ ThreadPoolSchemaImpl::PopFreePage()
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
|
||||
if (m_freePages.empty())
|
||||
{
|
||||
page = NULL;
|
||||
page = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1387,7 +1387,7 @@ ThreadPoolData::~ThreadPoolData()
|
||||
{
|
||||
// deallocate elements if they were freed from other threads
|
||||
ThreadPoolSchemaImpl::Page::FakeNodeLF* fakeLFNode;
|
||||
while ((fakeLFNode = m_freedElements.pop())!=0)
|
||||
while ((fakeLFNode = m_freedElements.pop())!=nullptr)
|
||||
{
|
||||
m_allocator.DeAllocate(fakeLFNode);
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ SystemAllocator::Create(const Descriptor& desc)
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HEAP
|
||||
m_allocator = azcreate(HeapSchema, (heapDesc), SystemAllocator);
|
||||
#endif
|
||||
if (m_allocator == NULL)
|
||||
if (m_allocator == nullptr)
|
||||
{
|
||||
isReady = false;
|
||||
}
|
||||
@@ -237,7 +237,7 @@ SystemAllocator::Allocate(size_type byteSize, size_type alignment, int flags, co
|
||||
byteSize = MemorySizeAdjustedUp(byteSize);
|
||||
SystemAllocator::pointer_type address = m_allocator->Allocate(byteSize, alignment, flags, name, fileName, lineNum, suppressStackRecord + 1);
|
||||
|
||||
if (address == 0)
|
||||
if (address == nullptr)
|
||||
{
|
||||
// Free all memory we can and try again!
|
||||
AllocatorManager::Instance().GarbageCollect();
|
||||
@@ -245,7 +245,7 @@ SystemAllocator::Allocate(size_type byteSize, size_type alignment, int flags, co
|
||||
address = m_allocator->Allocate(byteSize, alignment, flags, name, fileName, lineNum, suppressStackRecord + 1);
|
||||
}
|
||||
|
||||
if (address == 0)
|
||||
if (address == nullptr)
|
||||
{
|
||||
byteSize = MemorySizeAdjustedDown(byteSize); // restore original size
|
||||
|
||||
@@ -258,7 +258,7 @@ SystemAllocator::Allocate(size_type byteSize, size_type alignment, int flags, co
|
||||
}
|
||||
}
|
||||
|
||||
AZ_Assert(address != 0, "SystemAllocator: Failed to allocate %d bytes aligned on %d (flags: 0x%08x) %s : %s (%d)!", byteSize, alignment, flags, name ? name : "(no name)", fileName ? fileName : "(no file name)", lineNum);
|
||||
AZ_Assert(address != nullptr, "SystemAllocator: Failed to allocate %d bytes aligned on %d (flags: 0x%08x) %s : %s (%d)!", byteSize, alignment, flags, name ? name : "(no name)", fileName ? fileName : "(no file name)", lineNum);
|
||||
|
||||
AZ_PROFILE_MEMORY_ALLOC_EX(MemoryReserved, fileName, lineNum, address, byteSize, name);
|
||||
AZ_MEMORY_PROFILE(ProfileAllocation(address, byteSize, alignment, name, fileName, lineNum, suppressStackRecord + 1));
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace AZ
|
||||
AZ_Assert(m_numAttached == 0, "We should not delete an environment while there are %d modules attached! Unload all DLLs first!", m_numAttached);
|
||||
#endif
|
||||
|
||||
for (auto variableIt : m_variableMap)
|
||||
for (const auto &variableIt : m_variableMap)
|
||||
{
|
||||
EnvironmentVariableHolderBase* holder = reinterpret_cast<EnvironmentVariableHolderBase*>(variableIt.second);
|
||||
if (holder)
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace AZ
|
||||
{
|
||||
Internal::NameData* nameData = keyValue.second;
|
||||
const int useCount = keyValue.second->m_useCount;
|
||||
const bool hadCollision = keyValue.second->m_hashCollision;
|
||||
[[maybe_unused]] const bool hadCollision = keyValue.second->m_hashCollision;
|
||||
|
||||
if (useCount == 0)
|
||||
{
|
||||
|
||||
@@ -41,11 +41,17 @@ namespace AZ::NativeUI
|
||||
AZStd::string result = DisplayBlockingDialog("Assert Failed!", message, options);
|
||||
|
||||
if (result.compare(buttonNames[0]) == 0)
|
||||
{
|
||||
return AssertAction::IGNORE_ASSERT;
|
||||
}
|
||||
else if (result.compare(buttonNames[1]) == 0)
|
||||
{
|
||||
return AssertAction::IGNORE_ALL_ASSERTS;
|
||||
}
|
||||
else if (result.compare(buttonNames[2]) == 0)
|
||||
{
|
||||
return AssertAction::BREAK;
|
||||
}
|
||||
|
||||
return AssertAction::NONE;
|
||||
}
|
||||
|
||||
@@ -88,15 +88,6 @@
|
||||
|
||||
# define AZ_FORCE_INLINE __forceinline
|
||||
|
||||
/// Aligns a declaration.
|
||||
# define AZ_ALIGN(_decl, _alignment) \
|
||||
AZ_PUSH_DISABLE_WARNING(4324, "-Wunknown-warning-option") \
|
||||
__declspec(align(_alignment)) \
|
||||
_decl \
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
/// Return the alignment of a type. This if for internal use only (use AZStd::alignment_of<>())
|
||||
# define AZ_INTERNAL_ALIGNMENT_OF(_type) __alignof(_type)
|
||||
/// Pointer will be aliased.
|
||||
# define AZ_MAY_ALIAS
|
||||
/// Function signature macro
|
||||
@@ -120,15 +111,7 @@
|
||||
#define AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
# define AZ_FORCE_INLINE inline
|
||||
/// Aligns a declaration.
|
||||
# define AZ_ALIGN(_decl, _alignment) \
|
||||
AZ_PUSH_DISABLE_WARNING(4324, "-Wunknown-warning-option") \
|
||||
_decl \
|
||||
__attribute__((aligned(_alignment)))
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
/// Return the alignment of a type. This if for internal use only (use AZStd::alignment_of<>())
|
||||
# define AZ_INTERNAL_ALIGNMENT_OF(_type) __alignof__(_type)
|
||||
/// Pointer will be aliased.
|
||||
# define AZ_MAY_ALIAS __attribute__((__may_alias__))
|
||||
/// Function signature macro
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace AZ
|
||||
{
|
||||
inline namespace PlatformDefaults
|
||||
{
|
||||
static const char* PlatformNames[PlatformId::NumPlatformIds] = { PlatformPC, PlatformAndroid, PlatformIOS, PlatformMac, PlatformProvo, PlatformSalem, PlatformJasper, PlatformServer, PlatformAll, PlatformAllClient };
|
||||
static const char* PlatformNames[PlatformId::NumPlatformIds] = { PlatformPC, PlatformLinux, PlatformAndroid, PlatformIOS, PlatformMac, PlatformProvo, PlatformSalem, PlatformJasper, PlatformServer, PlatformAll, PlatformAllClient };
|
||||
|
||||
const char* PlatformIdToPalFolder(AZ::PlatformId platform)
|
||||
{
|
||||
@@ -27,6 +27,8 @@ namespace AZ
|
||||
{
|
||||
case AZ::PC:
|
||||
return "PC";
|
||||
case AZ::LINUX_ID:
|
||||
return "Linux";
|
||||
case AZ::ANDROID_ID:
|
||||
return "Android";
|
||||
case AZ::IOS:
|
||||
@@ -56,10 +58,14 @@ namespace AZ
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform)
|
||||
{
|
||||
if (osPlatform == PlatformCodeNameWindows || osPlatform == PlatformCodeNameLinux)
|
||||
if (osPlatform == PlatformCodeNameWindows)
|
||||
{
|
||||
return PlatformPC;
|
||||
}
|
||||
if (osPlatform == PlatformCodeNameLinux)
|
||||
{
|
||||
return PlatformLinux;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameMac)
|
||||
{
|
||||
return PlatformMac;
|
||||
@@ -201,6 +207,8 @@ namespace AZ
|
||||
{
|
||||
case PlatformId::PC:
|
||||
platformCodes.emplace_back(PlatformCodeNameWindows);
|
||||
break;
|
||||
case PlatformId::LINUX_ID:
|
||||
platformCodes.emplace_back(PlatformCodeNameLinux);
|
||||
break;
|
||||
case PlatformId::ANDROID_ID:
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace AZ
|
||||
inline namespace PlatformDefaults
|
||||
{
|
||||
constexpr char PlatformPC[] = "pc";
|
||||
constexpr char PlatformLinux[] = "linux";
|
||||
constexpr char PlatformAndroid[] = "android";
|
||||
constexpr char PlatformIOS[] = "ios";
|
||||
constexpr char PlatformMac[] = "mac";
|
||||
@@ -50,6 +51,7 @@ namespace AZ
|
||||
AZ_ENUM_WITH_UNDERLYING_TYPE(PlatformId, int,
|
||||
(Invalid, -1),
|
||||
PC,
|
||||
LINUX_ID,
|
||||
ANDROID_ID,
|
||||
IOS,
|
||||
MAC_ID,
|
||||
@@ -63,12 +65,13 @@ namespace AZ
|
||||
// Add new platforms above this
|
||||
NumPlatformIds
|
||||
);
|
||||
constexpr int NumClientPlatforms = 7;
|
||||
constexpr int NumClientPlatforms = 8;
|
||||
constexpr int NumPlatforms = NumClientPlatforms + 1; // 1 "Server" platform currently
|
||||
enum class PlatformFlags : AZ::u32
|
||||
{
|
||||
Platform_NONE = 0x00,
|
||||
Platform_PC = 1 << PlatformId::PC,
|
||||
Platform_LINUX = 1 << PlatformId::LINUX_ID,
|
||||
Platform_ANDROID = 1 << PlatformId::ANDROID_ID,
|
||||
Platform_IOS = 1 << PlatformId::IOS,
|
||||
Platform_MAC = 1 << PlatformId::MAC_ID,
|
||||
@@ -83,7 +86,7 @@ namespace AZ
|
||||
// A special platform that will always correspond to all non-server platforms, even if new ones are added
|
||||
Platform_ALL_CLIENT = 1ULL << 31,
|
||||
|
||||
AllNamedPlatforms = Platform_PC | Platform_ANDROID | Platform_IOS | Platform_MAC | Platform_PROVO | Platform_SALEM | Platform_JASPER | Platform_SERVER,
|
||||
AllNamedPlatforms = Platform_PC | Platform_LINUX | Platform_ANDROID | Platform_IOS | Platform_MAC | Platform_PROVO | Platform_SALEM | Platform_JASPER | Platform_SERVER,
|
||||
};
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(PlatformFlags);
|
||||
|
||||
@@ -121,12 +121,12 @@ namespace AZ
|
||||
{
|
||||
delete attrIt.second;
|
||||
}
|
||||
|
||||
|
||||
if (m_overload)
|
||||
{
|
||||
delete m_overload;
|
||||
}
|
||||
|
||||
|
||||
m_attributes.clear();
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ namespace AZ
|
||||
if (GetNumArguments() == overload->GetNumArguments())
|
||||
{
|
||||
bool anyDifference = false;
|
||||
|
||||
|
||||
for (size_t i(0), sentinel(GetNumArguments()); !anyDifference && i < sentinel; ++i)
|
||||
{
|
||||
const BehaviorParameter* thisArg = GetArgument(i);
|
||||
@@ -273,7 +273,7 @@ namespace AZ
|
||||
auto attributes = AZStd::move(m_attributes);
|
||||
|
||||
// Actually delete everything
|
||||
for (auto propertyIt : events)
|
||||
for (const auto &propertyIt : events)
|
||||
{
|
||||
delete propertyIt.second.m_broadcast;
|
||||
delete propertyIt.second.m_event;
|
||||
@@ -519,20 +519,20 @@ namespace AZ
|
||||
AZStd::vector<BehaviorMethod*> BehaviorClass::GetOverloads(const AZStd::string& name) const
|
||||
{
|
||||
AZStd::vector<BehaviorMethod*> overloads;
|
||||
|
||||
|
||||
auto methodIter = m_methods.find(name);
|
||||
if (methodIter != m_methods.end())
|
||||
{
|
||||
overloads = GetOverloadsIncludeMethod(methodIter->second);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return overloads;
|
||||
}
|
||||
|
||||
AZStd::vector<BehaviorMethod*> BehaviorClass::GetOverloadsIncludeMethod(BehaviorMethod* method) const
|
||||
{
|
||||
AZStd::vector<BehaviorMethod*> overloads;
|
||||
|
||||
|
||||
auto iter = method;
|
||||
while (iter)
|
||||
{
|
||||
@@ -546,7 +546,7 @@ namespace AZ
|
||||
AZStd::vector<BehaviorMethod*> BehaviorClass::GetOverloadsExcludeMethod(BehaviorMethod* method) const
|
||||
{
|
||||
AZStd::vector<BehaviorMethod*> overloads;
|
||||
|
||||
|
||||
auto iter = method->m_overload;
|
||||
while (iter)
|
||||
{
|
||||
@@ -972,5 +972,5 @@ namespace AZ
|
||||
return enumRttiHelper.GetTypeId();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace AZ
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace AZ
|
||||
|
||||
constexpr const char* k_PropertyNameGetterSuffix = "::Getter";
|
||||
constexpr const char* k_PropertyNameSetterSuffix = "::Setter";
|
||||
|
||||
|
||||
/// Typedef for class unwrapping callback (i.e. used for things like smart_ptr<T> to unwrap for T)
|
||||
using BehaviorClassUnwrapperFunction = void(*)(void* /*classPtr*/, void*& /*unwrappedClass*/, AZ::Uuid& /*unwrappedClassTypeId*/, void* /*userData*/);
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace AZ
|
||||
IfPresent,
|
||||
};
|
||||
|
||||
struct BehaviorObject // same as DynamicSerializableField, make sure we merge them... so we can store the object easily
|
||||
struct BehaviorObject // same as DynamicSerializableField, make sure we merge them... so we can store the object easily
|
||||
{
|
||||
AZ_TYPE_INFO(BehaviorObject, "{2813cdfb-0a4a-411c-9216-72a7b644d1dd}");
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace AZ
|
||||
/// Convert to BehaviorObject implicitly for passing generic parameters (usually not known at compile time)
|
||||
operator BehaviorObject() const;
|
||||
|
||||
/// Converts internally the value to a specific type known at compile time. \returns true if conversion was successful.
|
||||
/// Converts internally the value to a specific type known at compile time. \returns true if conversion was successful.
|
||||
template<class T>
|
||||
bool ConvertTo();
|
||||
|
||||
@@ -452,7 +452,7 @@ namespace AZ
|
||||
namespace Internal
|
||||
{
|
||||
const AZ::TypeId& GetUnderlyingTypeId(const IRttiHelper& enumRttiHelper);
|
||||
|
||||
|
||||
// Converts sourceAddress to targetType
|
||||
inline bool ConvertValueTo(void* sourceAddress, const IRttiHelper* sourceRtti, const AZ::Uuid& targetType, void*& targetAddress, BehaviorParameter::TempValueParameterAllocator& tempAllocator)
|
||||
{
|
||||
@@ -520,7 +520,7 @@ namespace AZ
|
||||
static const int s_startNamedArgumentIndex = s_startArgumentIndex; // +1 for result type
|
||||
|
||||
BehaviorMethodImpl(FunctionPointer functionPointer, BehaviorContext* context, const AZStd::string& name = AZStd::string());
|
||||
|
||||
|
||||
bool Call(BehaviorValueParameter* arguments, unsigned int numArguments, BehaviorValueParameter* result) const override;
|
||||
|
||||
bool HasResult() const override;
|
||||
@@ -548,7 +548,7 @@ namespace AZ
|
||||
BehaviorParameter m_parameters[sizeof...(Args)+s_startNamedArgumentIndex];
|
||||
AZStd::array<BehaviorParameterMetadata, sizeof...(Args)+s_startNamedArgumentIndex> m_metadataParameters; ///< Stores the per parameter metadata which is used to add names, tooltips, trait, default values, etc... to the parameters
|
||||
};
|
||||
|
||||
|
||||
#if __cpp_noexcept_function_type
|
||||
// C++17 makes exception specifications as part of the type in paper P0012R1
|
||||
// Therefore noexcept overloads must be distinguished from non-noexcept overloads
|
||||
@@ -732,7 +732,7 @@ namespace AZ
|
||||
|
||||
BehaviorEBusEvent(FunctionPointer functionPointer, BehaviorContext* context);
|
||||
BehaviorEBusEvent(FunctionPointerConst functionPointer, BehaviorContext* context);
|
||||
|
||||
|
||||
template<bool IsBusId>
|
||||
inline AZStd::enable_if_t<IsBusId> SetBusIdType();
|
||||
|
||||
@@ -813,7 +813,7 @@ namespace AZ
|
||||
: SetFunctionParameters<R(C::*)(Args...)>
|
||||
{};
|
||||
#endif
|
||||
|
||||
|
||||
template<class FunctionType>
|
||||
struct BehaviorOnDemandReflectHelper;
|
||||
template<class R, class... Args>
|
||||
@@ -997,14 +997,14 @@ namespace AZ
|
||||
} // namespace Internal
|
||||
|
||||
/**
|
||||
* Behavior representation of reflected class.
|
||||
* Behavior representation of reflected class.
|
||||
*/
|
||||
class BehaviorClass
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(BehaviorClass, SystemAllocator, 0);
|
||||
|
||||
BehaviorClass();
|
||||
BehaviorClass();
|
||||
~BehaviorClass();
|
||||
|
||||
/// Hooks to override default memory allocation for the class (AZ_CLASS_ALLOCATOR is used by default)
|
||||
@@ -1065,7 +1065,7 @@ namespace AZ
|
||||
|
||||
void* m_userData;
|
||||
AZStd::string m_name;
|
||||
AZStd::vector<AZ::Uuid> m_baseClasses;
|
||||
AZStd::vector<AZ::Uuid> m_baseClasses;
|
||||
AZStd::unordered_map<AZStd::string, BehaviorMethod*> m_methods;
|
||||
AZStd::unordered_map<AZStd::string, BehaviorProperty*> m_properties;
|
||||
AttributeArray m_attributes;
|
||||
@@ -1081,7 +1081,7 @@ namespace AZ
|
||||
AZ::Uuid m_wrappedTypeId;
|
||||
// Store all owned instances for unload verification?
|
||||
};
|
||||
|
||||
|
||||
// Helper macros to generate getter and setter function from a pointer to value or member value
|
||||
// Syntax BehaviorValueGetter(&globalValue) BehaviorValueGetter(&Class::MemberValue)
|
||||
# define BehaviorValueGetter(valueAddress) &AZ::Internal::BehaviorValuePropertyHelper<decltype(valueAddress)>::Get<valueAddress>
|
||||
@@ -1095,7 +1095,7 @@ namespace AZ
|
||||
* Property representation, a property has getter and setter. A read only property will have a "nullptr" for a setter.
|
||||
* You can use lambdas, global of member function. If you want to just expose a variable (not write the function and handle changes)
|
||||
* you can use \ref BehaviorValueProperty macros (or BehaviorValueGetter/Setter to control read/write functionality)
|
||||
* Member constants are a property too, use \ref BehaviorConstant for it. Everything is either a property or a method, the main reason
|
||||
* Member constants are a property too, use \ref BehaviorConstant for it. Everything is either a property or a method, the main reason
|
||||
* why we "push" people to use functions is that in most cases when we manipulate an object, you will need to do more than just set a value
|
||||
* to a new value.
|
||||
*/
|
||||
@@ -1163,7 +1163,7 @@ namespace AZ
|
||||
};
|
||||
|
||||
/**
|
||||
* RAII class which keeps track of functions reflected to the BehaviorContext
|
||||
* RAII class which keeps track of functions reflected to the BehaviorContext
|
||||
* when it is supplied as an OnDemandReflectionOwner
|
||||
*/
|
||||
class ScopedBehaviorOnDemandReflector
|
||||
@@ -1182,7 +1182,7 @@ namespace AZ
|
||||
AZ_CLASS_ALLOCATOR(BehaviorEBus, SystemAllocator, 0);
|
||||
|
||||
typedef void(*QueueFunctionType)(void* /*userData1*/, void* /*userData2*/);
|
||||
|
||||
|
||||
struct VirtualProperty
|
||||
{
|
||||
VirtualProperty(BehaviorEBusEventSender* getter, BehaviorEBusEventSender* setter)
|
||||
@@ -1294,7 +1294,7 @@ namespace AZ
|
||||
AZStd::string m_scriptPath;
|
||||
#endif
|
||||
|
||||
AZStd::string GetScriptPath() const
|
||||
AZStd::string GetScriptPath() const
|
||||
{
|
||||
#if defined(PERFORMANCE_BUILD) || !defined(_RELEASE) // m_scriptPath is only available in non-Release mode
|
||||
return m_scriptPath;
|
||||
@@ -1303,8 +1303,8 @@ namespace AZ
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetScriptPath(const char* scriptPath)
|
||||
{
|
||||
void SetScriptPath(const char* scriptPath)
|
||||
{
|
||||
#if defined(PERFORMANCE_BUILD) || !defined(_RELEASE) // m_scriptPath is only available in non-Release mode
|
||||
m_scriptPath = scriptPath;
|
||||
#else
|
||||
@@ -1346,7 +1346,7 @@ namespace AZ
|
||||
virtual void OnAddGlobalProperty(const char* propertyName, BehaviorProperty* prop) { (void)propertyName; (void)prop; }
|
||||
virtual void OnRemoveGlobalProperty(const char* propertyName, BehaviorProperty* prop) { (void)propertyName; (void)prop; }
|
||||
|
||||
/// Called when a class is added or removed
|
||||
/// Called when a class is added or removed
|
||||
virtual void OnAddClass(const char* className, BehaviorClass* behaviorClass) { (void)className; (void)behaviorClass; }
|
||||
virtual void OnRemoveClass(const char* className, BehaviorClass* behaviorClass) { (void)className; (void)behaviorClass; }
|
||||
|
||||
@@ -1358,10 +1358,10 @@ namespace AZ
|
||||
using BehaviorContextBus = AZ::EBus<BehaviorContextEvents>;
|
||||
|
||||
/**
|
||||
* BehaviorContext is used to reflect classes, methods and EBuses for runtime interaction. A typical consumer of this context and different
|
||||
* BehaviorContext is used to reflect classes, methods and EBuses for runtime interaction. A typical consumer of this context and different
|
||||
* scripting systems (i.e. Lua, Visual Script, etc.). Even though (as designed) there are overlaps between some context they have very different
|
||||
* purpose and set of rules. For example SerializeContext, doesn't reflect any methods, it just reflects data fields that will be stored for initial object
|
||||
* setup, it handles version conversion and so thing, this related to storing the object to a persistent storage. Behavior context, doesn't need to deal with versions as
|
||||
* setup, it handles version conversion and so thing, this related to storing the object to a persistent storage. Behavior context, doesn't need to deal with versions as
|
||||
* no data is stored, just methods for manipulating the object state.
|
||||
*/
|
||||
class BehaviorContext : public ReflectContext
|
||||
@@ -1379,7 +1379,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
template<class Bus>
|
||||
static void QueueFunction(BehaviorEBus::QueueFunctionType f, void* userData1, void* userData2)
|
||||
static void QueueFunction(BehaviorEBus::QueueFunctionType f, void* userData1, void* userData2)
|
||||
{
|
||||
Bus::QueueFunction(f, userData1, userData2);
|
||||
}
|
||||
@@ -1484,8 +1484,8 @@ namespace AZ
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static void SetClassDefaultAllocator(BehaviorClass* behaviorClass, const AZStd::false_type& /*HasAZClassAllocator<T>*/)
|
||||
{
|
||||
static void SetClassDefaultAllocator(BehaviorClass* behaviorClass, const AZStd::false_type& /*HasAZClassAllocator<T>*/)
|
||||
{
|
||||
behaviorClass->m_allocate = &DefaultSystemAllocator<T>::Allocate;
|
||||
behaviorClass->m_deallocate = &DefaultSystemAllocator<T>::DeAllocate;
|
||||
}
|
||||
@@ -1522,20 +1522,20 @@ namespace AZ
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static void SetClassDefaultConstructor(BehaviorClass* behaviorClass, const AZStd::true_type& /*AZStd::is_constructible<T>*/)
|
||||
static void SetClassDefaultConstructor(BehaviorClass* behaviorClass, const AZStd::true_type& /*AZStd::is_constructible<T>*/)
|
||||
{
|
||||
behaviorClass->m_defaultConstructor = &DefaultConstruct<T>;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static void SetClassDefaultDestructor(BehaviorClass* behaviorClass, const AZStd::true_type& /*AZStd::is_destructible<T>*/)
|
||||
static void SetClassDefaultDestructor(BehaviorClass* behaviorClass, const AZStd::true_type& /*AZStd::is_destructible<T>*/)
|
||||
{
|
||||
behaviorClass->m_destructor = &DefaultDestruct<T>;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static void SetClassDefaultCopyConstructor(BehaviorClass* behaviorClass, const AZStd::true_type& /*AZStd::is_copy_constructible<T>*/)
|
||||
{
|
||||
static void SetClassDefaultCopyConstructor(BehaviorClass* behaviorClass, const AZStd::true_type& /*AZStd::is_copy_constructible<T>*/)
|
||||
{
|
||||
behaviorClass->m_cloner = &DefaultCopyConstruct<T>;
|
||||
}
|
||||
|
||||
@@ -1585,7 +1585,7 @@ namespace AZ
|
||||
const char* m_name;
|
||||
BehaviorMethod* m_method;
|
||||
};
|
||||
|
||||
|
||||
struct GlobalPropertyBuilder : public AZ::Internal::GenericAttributes<GlobalPropertyBuilder>
|
||||
{
|
||||
typedef AZ::Internal::GenericAttributes<GlobalPropertyBuilder> Base;
|
||||
@@ -1608,7 +1608,7 @@ namespace AZ
|
||||
ClassBuilder(BehaviorContext* context, BehaviorClass* behaviorClass);
|
||||
~ClassBuilder();
|
||||
ClassBuilder* operator->();
|
||||
|
||||
|
||||
/**
|
||||
* Sets custom allocator for a class, this function will error if this not inside a class.
|
||||
* This is only for very specific cases when you want to override AZ_CLASS_ALLOCATOR or you are dealing with 3rd party classes, otherwise
|
||||
@@ -1659,9 +1659,9 @@ namespace AZ
|
||||
ClassBuilder* Constant(const char* name, Getter getter);
|
||||
|
||||
/**
|
||||
* You can describe buses that this class uses to communicate. Those buses will be used by tools when
|
||||
* You can describe buses that this class uses to communicate. Those buses will be used by tools when
|
||||
* you need to give developers hints as to what buses this class interacts with.
|
||||
* You don't need to reflect all buses that your class uses, just the ones related to
|
||||
* You don't need to reflect all buses that your class uses, just the ones related to
|
||||
* class behavior. Please refer to component documentation for more information on
|
||||
* the pattern of Request and Notification buses.
|
||||
* {@
|
||||
@@ -1717,10 +1717,10 @@ namespace AZ
|
||||
|
||||
/**
|
||||
* With request buses (please refer to component communication patterns documentation) we ofter have EBus events
|
||||
* that represent a getter and a setter for a value. To allow our tools to take advantage of it, you can reflect
|
||||
* that represent a getter and a setter for a value. To allow our tools to take advantage of it, you can reflect
|
||||
* VirtualProperty to indicate which event is the getter and which is the setter.
|
||||
* This function validates that getter event has no argument and a result and setter function has no results and only
|
||||
* one argument which is the same type as the result of the getter.
|
||||
* one argument which is the same type as the result of the getter.
|
||||
* \note Make sure you call this function after you have reflected the getter and setter events as it will report an error
|
||||
* if we can't find the function
|
||||
*/
|
||||
@@ -1731,7 +1731,7 @@ namespace AZ
|
||||
|
||||
BehaviorContext();
|
||||
~BehaviorContext();
|
||||
|
||||
|
||||
///< \deprecated Use "Method(const char*, Function, const AZStd::array<ParameterOverrides, AZStd::function_traits<Function>::num_args>&, const char*)" instead
|
||||
///< This method does not support passing in argument names and tooltips nor does it support overriding specific parameter Behavior traits
|
||||
template<class Function>
|
||||
@@ -1741,7 +1741,7 @@ namespace AZ
|
||||
///< This method does not support passing in argument names and tooltips nor does it support overriding specific parameter Behavior traits
|
||||
template<class Function>
|
||||
GlobalMethodBuilder Method(const char* name, Function f, const char* deprecatedName, BehaviorValues* defaultValues = nullptr, const char* dbgDesc = nullptr);
|
||||
|
||||
|
||||
template<class Function>
|
||||
GlobalMethodBuilder Method(const char* name, Function f, const AZStd::array<BehaviorParameterOverrides, AZStd::function_traits<Function>::num_args>& args, const char* dbgDesc = nullptr);
|
||||
|
||||
@@ -1836,13 +1836,13 @@ namespace AZ
|
||||
|
||||
/**
|
||||
* Helper MACRO to help you write the EBus handler that you want to reflect to behavior. This is not required, but generally we recommend reflecting all useful
|
||||
* buses as this enable people to "script" complex behaviors.
|
||||
* buses as this enable people to "script" complex behaviors.
|
||||
* You don't have to use this macro to write a Handler, but some people find it useful
|
||||
* Here is an example how to use it:
|
||||
* class MyEBusBehaviorHandler : public MyEBus::Handler, public AZ::BehaviorEBusHandler
|
||||
* {
|
||||
* public:
|
||||
* AZ_EBUS_BEHAVIOR_BINDER(MyEBusBehaviorHandler, "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXXX}",Allocator, OnEvent1, OnEvent2 and so on);
|
||||
* AZ_EBUS_BEHAVIOR_BINDER(MyEBusBehaviorHandler, "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXXX}",Allocator, OnEvent1, OnEvent2 and so on);
|
||||
* // now you need implementations for those event
|
||||
*
|
||||
*
|
||||
@@ -1854,7 +1854,7 @@ namespace AZ
|
||||
* // The AZ_EBUS_BEHAVIOR_BINDER defines FN_EventName for each index. You can also cache it yourself (but it's slower), static int cacheIndex = GetFunctionIndex("OnEvent1"); and use that .
|
||||
* CallResult(result, FN_OnEvent1, data); // forward to the binding (there can be none, this is why we need to always have properly set result, when there is one)
|
||||
* return result; // return the result like you will in any normal EBus even with result
|
||||
* } *
|
||||
* } *
|
||||
* // handle the other events here
|
||||
* };
|
||||
*
|
||||
@@ -1922,7 +1922,7 @@ namespace AZ
|
||||
/**
|
||||
* Provides the same functionality of the AZ_EBUS_BEHAVIOR_BINDER macro above with the additional ability to specify the names and a tooltips of handler methods
|
||||
* after listing the handler method in the macro.
|
||||
* An example Usage is
|
||||
* An example Usage is
|
||||
* class MyEBusBehaviorHandler : public MyEBus::Handler, public AZ::BehaviorEBusHandler
|
||||
* {
|
||||
* public:
|
||||
@@ -1930,7 +1930,7 @@ namespace AZ
|
||||
* OnEvent2, ({#OnEvent2 first parameter name(float), #OnEvent2 first parameter tooltip(float)}, {#OnEvent2 second parameter name(bool), {#OnEvent2 second parameter tooltip(bool)}),
|
||||
* OnEvent3, ());
|
||||
* // The reason for needing parenthesis around the parameter name and tooltip object(AZ::BehaviorParameterOverrides) is to prevent the macro from parsing the comma in the intializer as seperate parameters
|
||||
* // When using this macro, the BehaviorParameterOverrides objects must be placed after every listing a function as a handler. Furthermore the number of BehaviorParameterOverrides objects for each function must match the number of parameters
|
||||
* // When using this macro, the BehaviorParameterOverrides objects must be placed after every listing a function as a handler. Furthermore the number of BehaviorParameterOverrides objects for each function must match the number of parameters
|
||||
* // to that function
|
||||
* // Ex. for a function called HugeEvent with a signature of void HugeEvent(int, float, double, char, short), two arguments must be supplied to the macro.
|
||||
* // 1. HugeEvent
|
||||
@@ -2181,7 +2181,7 @@ namespace AZ
|
||||
// Template implementations
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
inline BehaviorObject::BehaviorObject()
|
||||
: m_address(nullptr)
|
||||
@@ -2569,7 +2569,7 @@ namespace AZ
|
||||
m_getter = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// assure that TR_THIS_PTR is set on the first parameter
|
||||
m_getter->OverrideParameterTraits(0, AZ::BehaviorParameter::TR_THIS_PTR, 0);
|
||||
}
|
||||
@@ -2847,7 +2847,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
template<class R, class... Args>
|
||||
void BehaviorEBusHandler::CallResult(R& result, int index, Args&&... args) const
|
||||
{
|
||||
@@ -2904,7 +2904,7 @@ namespace AZ
|
||||
{
|
||||
return ClassBuilder<T>(this, static_cast<BehaviorClass*>(nullptr));
|
||||
}
|
||||
|
||||
|
||||
auto classTypeIt = m_typeToClassMap.find(typeUuid);
|
||||
if (IsRemovingReflection())
|
||||
{
|
||||
@@ -2933,7 +2933,7 @@ namespace AZ
|
||||
// class already reflected, display name and uuid
|
||||
char uuidName[AZ::Uuid::MaxStringBuffer];
|
||||
classTypeIt->first.ToString(uuidName, AZ::Uuid::MaxStringBuffer);
|
||||
|
||||
|
||||
AZ_Error("Reflection", false, "Class '%s' is already registered using Uuid: %s!", name, uuidName);
|
||||
return ClassBuilder<T>(this, static_cast<BehaviorClass*>(nullptr));
|
||||
}
|
||||
@@ -3002,7 +3002,7 @@ namespace AZ
|
||||
|
||||
if (m_class && (!Base::m_context->IsRemovingReflection()))
|
||||
{
|
||||
for (auto method : m_class->m_methods)
|
||||
for (const auto &method : m_class->m_methods)
|
||||
{
|
||||
m_class->PostProcessMethod(Base::m_context, *method.second);
|
||||
if (MethodReturnsAzEventByReferenceOrPointer(*method.second))
|
||||
@@ -3485,7 +3485,7 @@ namespace AZ
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
BehaviorContext::EBusBuilder<T> BehaviorContext::EBus(const char* name, const char* deprecatedName /*=nullptr*/, const char* toolTip /*=nullptr*/)
|
||||
@@ -3748,9 +3748,9 @@ namespace AZ
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_ebus->m_virtualProperties.insert(AZStd::make_pair(name, BehaviorEBus::VirtualProperty(getter, setter)));
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -3774,8 +3774,7 @@ namespace AZ
|
||||
template<class... Functions>
|
||||
inline void OnDemandReflectFunctions(OnDemandReflectionOwner* onDemandReflection, AZStd::Internal::pack_traits_arg_sequence<Functions...>)
|
||||
{
|
||||
using PackExpander = bool[];
|
||||
PackExpander{ true, (BehaviorOnDemandReflectHelper<typename AZStd::function_traits<Functions>::raw_fp_type>::QueueReflect(onDemandReflection), true)... };
|
||||
(BehaviorOnDemandReflectHelper<typename AZStd::function_traits<Functions>::raw_fp_type>::QueueReflect(onDemandReflection), ...);
|
||||
}
|
||||
|
||||
// Assumes parameters array is big enough to store all parameters
|
||||
@@ -3869,7 +3868,7 @@ namespace AZ
|
||||
SetParameters<R>(m_parameters, this);
|
||||
SetParameters<Args...>(&m_parameters[s_startNamedArgumentIndex], this);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template<class R, class... Args>
|
||||
bool BehaviorMethodImpl<R(Args...)>::Call(BehaviorValueParameter* arguments, unsigned int numArguments, BehaviorValueParameter* result) const
|
||||
@@ -3877,7 +3876,7 @@ namespace AZ
|
||||
size_t totalArguments = GetNumArguments();
|
||||
if (numArguments < totalArguments)
|
||||
{
|
||||
// We are cloning all arguments on the stack, since Call is called only from Invoke we can reserve bigger "arguments" array
|
||||
// We are cloning all arguments on the stack, since Call is called only from Invoke we can reserve bigger "arguments" array
|
||||
// that can always handle all parameters. So far the don't use default values that ofter, so we will optimize for the common case first.
|
||||
BehaviorValueParameter* newArguments = reinterpret_cast<BehaviorValueParameter*>(alloca(sizeof(BehaviorValueParameter)* totalArguments));
|
||||
// clone the input parameters (we don't need to clone temp buffers, etc. as they will be still on the stack)
|
||||
@@ -4073,7 +4072,7 @@ namespace AZ
|
||||
{
|
||||
m_isConst = true;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template<class R, class C, class... Args>
|
||||
bool BehaviorMethodImpl<R(C::*)(Args...)>::Call(BehaviorValueParameter* arguments, unsigned int numArguments, BehaviorValueParameter* result) const
|
||||
@@ -4081,7 +4080,7 @@ namespace AZ
|
||||
size_t totalArguments = GetNumArguments();
|
||||
if (numArguments < totalArguments)
|
||||
{
|
||||
// We are cloning all arguments on the stack, since Call is called only from Invoke we can reserve bigger "arguments" array
|
||||
// We are cloning all arguments on the stack, since Call is called only from Invoke we can reserve bigger "arguments" array
|
||||
// that can always handle all parameters. So far the don't use default values that ofter, so we will optimize for the common case first.
|
||||
BehaviorValueParameter* newArguments = reinterpret_cast<BehaviorValueParameter*>(alloca(sizeof(BehaviorValueParameter)* totalArguments));
|
||||
// clone the input parameters (we don't need to clone temp buffers, etc. as they will be still on the stack)
|
||||
@@ -4285,7 +4284,7 @@ namespace AZ
|
||||
{
|
||||
m_isConst = true;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template<class EBus, BehaviorEventType EventType, class R, class C, class... Args>
|
||||
template<bool IsBusId>
|
||||
@@ -4308,7 +4307,7 @@ namespace AZ
|
||||
size_t totalArguments = GetNumArguments();
|
||||
if (numArguments < totalArguments)
|
||||
{
|
||||
// We are cloning all arguments on the stack, since Call is called only from Invoke we can reserve bigger "arguments" array
|
||||
// We are cloning all arguments on the stack, since Call is called only from Invoke we can reserve bigger "arguments" array
|
||||
// that can always handle all parameters. So far the don't use default values that ofter, so we will optimize for the common case first.
|
||||
BehaviorValueParameter* newArguments = reinterpret_cast<BehaviorValueParameter*>(alloca(sizeof(BehaviorValueParameter)* totalArguments));
|
||||
// clone the input parameters (we don't need to clone temp buffers, etc. as they will be still on the stack)
|
||||
@@ -4498,7 +4497,7 @@ namespace AZ
|
||||
template<class R, class... Args>
|
||||
void SetFunctionParameters<R(Args...)>::Set(AZStd::vector<BehaviorParameter>& params)
|
||||
{
|
||||
// result, userdata, arguments
|
||||
// result, userdata, arguments
|
||||
params.resize(sizeof...(Args) + eBehaviorBusForwarderEventIndices::ParameterFirst);
|
||||
SetParameters<R>(¶ms[eBehaviorBusForwarderEventIndices::Result], nullptr);
|
||||
SetParameters<void*>(¶ms[eBehaviorBusForwarderEventIndices::UserData], nullptr);
|
||||
|
||||
@@ -493,7 +493,7 @@ namespace AZ
|
||||
const void* result = GetTypeId() == asType ? instance : nullptr;
|
||||
|
||||
using dummy = bool[];
|
||||
dummy{ true, (CastInternal<TArgs>(result, instance, asType), true)... };
|
||||
[[maybe_unused]] dummy d { true, (CastInternal<TArgs>(result, instance, asType), true)... };
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -517,7 +517,7 @@ namespace AZ
|
||||
bool result = GetTypeId() == id;
|
||||
|
||||
using dummy = bool[];
|
||||
dummy{ true, (IsTypeOfInternal<TArgs>(result, id), true)... };
|
||||
[[maybe_unused]] dummy d = { true, (IsTypeOfInternal<TArgs>(result, id), true)... };
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -534,7 +534,7 @@ namespace AZ
|
||||
callback(GetActualUuid(instance), instance);
|
||||
|
||||
using dummy = bool[];
|
||||
dummy{ true, (RttiHelper<TArgs>{}.EnumHierarchy(callback, instance), true)... };
|
||||
[[maybe_unused]] dummy d = { true, (RttiHelper<TArgs>{}.EnumHierarchy(callback, instance), true)... };
|
||||
}
|
||||
TypeTraits GetTypeTraits() const override
|
||||
{
|
||||
|
||||
@@ -1463,9 +1463,9 @@ static void* LuaMemoryHook(void* userData, void* ptr, size_t osize, size_t nsize
|
||||
{
|
||||
allocator->DeAllocate(ptr);
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
else if (ptr == NULL)
|
||||
else if (ptr == nullptr)
|
||||
{
|
||||
return allocator->Allocate(nsize, LUA_DEFAULT_ALIGNMENT, 0, "Script", __FILE__, __LINE__, 1);
|
||||
}
|
||||
@@ -1708,7 +1708,7 @@ LUA_API const Node* lua_getDummyNode()
|
||||
"Invalid stack!");
|
||||
lua_pop(m_nativeContext, (currentTop - m_startVariableIndex) + 1);
|
||||
|
||||
m_nativeContext = NULL;
|
||||
m_nativeContext = nullptr;
|
||||
m_startVariableIndex = 0;
|
||||
m_numArguments = 0;
|
||||
m_numResults = 0;
|
||||
@@ -2038,7 +2038,7 @@ LUA_API const Node* lua_getDummyNode()
|
||||
LSV_BEGIN_VARIABLE(m_nativeContext);
|
||||
|
||||
valueIndex = 0;
|
||||
name = NULL;
|
||||
name = nullptr;
|
||||
index = -1;
|
||||
if (m_mode == MD_INSPECT)
|
||||
{
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
, m_numErrors(0)
|
||||
{
|
||||
using namespace AZStd::placeholders;
|
||||
m_context->SetErrorHook(AZStd::bind(&ScriptErrorCatcher::ErrorCB, this, _1, _2, _3));
|
||||
m_context->SetErrorHook([this](ScriptContext* a, ScriptContext::ErrorType b, const char* c) { ErrorCB(a,b,c); });
|
||||
}
|
||||
~ScriptErrorCatcher()
|
||||
{
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
// [6/29/2012]
|
||||
//=========================================================================
|
||||
ScriptContextDebug::ScriptContextDebug(ScriptContext& scriptContext, bool isEnableStackRecord)
|
||||
: m_luaDebug(NULL)
|
||||
: m_luaDebug(nullptr)
|
||||
, m_currentStackLevel(-1)
|
||||
, m_stepStackLevel(-1)
|
||||
, m_isRecordCallstack(isEnableStackRecord)
|
||||
@@ -104,7 +104,7 @@ void ScriptContextDebug::ConnectHook()
|
||||
//=========================================================================
|
||||
void ScriptContextDebug::DisconnectHook()
|
||||
{
|
||||
lua_sethook(m_context.NativeContext(), 0, 0, 0);
|
||||
lua_sethook(m_context.NativeContext(), nullptr, 0, 0);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -149,7 +149,7 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe
|
||||
|
||||
lua_rawgeti(l, -2, AZ_LUA_CLASS_METATABLE_NAME_INDEX); // load class name
|
||||
AZ_Assert(lua_isstring(l, -1), "Internal scipt error: class without a classname at index %d", AZ_LUA_CLASS_METATABLE_NAME_INDEX);
|
||||
|
||||
|
||||
if (!enumClass(lua_tostring(l, -1), behaviorClass->m_typeId, userData))
|
||||
{
|
||||
lua_pop(l, 5);
|
||||
@@ -199,7 +199,7 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe
|
||||
// for any non-built in methods
|
||||
if (strncmp(name, "__", 2) != 0)
|
||||
{
|
||||
const char* dbgParamInfo = NULL;
|
||||
const char* dbgParamInfo = nullptr;
|
||||
|
||||
// attempt to get the name
|
||||
bool popDebugName = lua_getupvalue(l, -1, 2) != nullptr;
|
||||
@@ -278,7 +278,7 @@ ScriptContextDebug::EnumRegisteredGlobals(EnumMethod enumMethod, EnumProperty en
|
||||
{
|
||||
if (strncmp(name, "__", 2) != 0)
|
||||
{
|
||||
const char* dbgParamInfo = NULL;
|
||||
const char* dbgParamInfo = nullptr;
|
||||
lua_getupvalue(l, -1, 2);
|
||||
if (lua_isstring(l, -1))
|
||||
{
|
||||
@@ -606,7 +606,7 @@ void AZ::LuaHook(lua_State* l, lua_Debug* ar)
|
||||
lua_pop(l, 1);
|
||||
//
|
||||
bool doBreak = false;
|
||||
ScriptContextDebug::Breakpoint* bp = NULL;
|
||||
ScriptContextDebug::Breakpoint* bp = nullptr;
|
||||
ScriptContextDebug::Breakpoint localBreakPoint;
|
||||
|
||||
lua_getinfo(l, "Sunl", ar);
|
||||
@@ -735,7 +735,7 @@ void AZ::LuaHook(lua_State* l, lua_Debug* ar)
|
||||
{
|
||||
context->m_luaDebug = ar;
|
||||
context->m_breakCallback(context, bp);
|
||||
context->m_luaDebug = NULL;
|
||||
context->m_luaDebug = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,7 +752,7 @@ ScriptContextDebug::EnumLocals(EnumLocalCallback& cb)
|
||||
int local = 1;
|
||||
const char* name;
|
||||
ScriptDataContext dc;
|
||||
while ((name = lua_getlocal(l, m_luaDebug, local)) != NULL)
|
||||
while ((name = lua_getlocal(l, m_luaDebug, local)) != nullptr)
|
||||
{
|
||||
if (name[0] != '(') // skip temporary variables
|
||||
{
|
||||
@@ -846,7 +846,7 @@ ScriptContextDebug::EnableBreakpoints(BreakpointCallback& cb)
|
||||
void
|
||||
ScriptContextDebug::DisableBreakpoints()
|
||||
{
|
||||
m_breakCallback = NULL;
|
||||
m_breakCallback = nullptr;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -1079,7 +1079,7 @@ ScriptContextDebug::WriteValue(const DebugValue& value, const char* valueName, i
|
||||
int valueTableIndex = -1;
|
||||
if (valueName[0] == '[')
|
||||
{
|
||||
valueTableIndex = static_cast<int>(strtol(valueName + 1, NULL, 10));
|
||||
valueTableIndex = static_cast<int>(strtol(valueName + 1, nullptr, 10));
|
||||
}
|
||||
if (strcmp(valueName, "__metatable__") == 0) // metatable are read only
|
||||
{
|
||||
@@ -1114,7 +1114,7 @@ ScriptContextDebug::WriteValue(const DebugValue& value, const char* valueName, i
|
||||
} break;
|
||||
case LUA_TNUMBER:
|
||||
{
|
||||
lua_pushnumber(l, static_cast<lua_Number>(strtod(value.m_value.c_str(), NULL)));
|
||||
lua_pushnumber(l, static_cast<lua_Number>(strtod(value.m_value.c_str(), nullptr)));
|
||||
if (localIndex != -1)
|
||||
{
|
||||
lua_setlocal(l, m_luaDebug, localIndex);
|
||||
@@ -1256,7 +1256,7 @@ ScriptContextDebug::WriteValue(const DebugValue& value, const char* valueName, i
|
||||
else
|
||||
{
|
||||
lua_pushvalue(l, -5); // copy the user data (this pointer)
|
||||
lua_pushnumber(l, static_cast<lua_Number>(strtod(subElement.m_value.c_str(), NULL)));
|
||||
lua_pushnumber(l, static_cast<lua_Number>(strtod(subElement.m_value.c_str(), nullptr)));
|
||||
lua_call(l, 2, 0); // call the setter
|
||||
}
|
||||
break;
|
||||
@@ -1375,7 +1375,7 @@ ScriptContextDebug::GetValue(DebugValue& value)
|
||||
{
|
||||
int iLocal = 1;
|
||||
const char* localName;
|
||||
while ((localName = lua_getlocal(l, m_luaDebug, iLocal)) != NULL)
|
||||
while ((localName = lua_getlocal(l, m_luaDebug, iLocal)) != nullptr)
|
||||
{
|
||||
if (localName[0] != '(' && strcmp(name, localName) == 0)
|
||||
{
|
||||
@@ -1460,7 +1460,7 @@ ScriptContextDebug::SetValue(const DebugValue& sourceValue)
|
||||
// create hierarchy from tokens
|
||||
const DebugValue* value = &sourceValue;
|
||||
DebugValue untokenizedValue;
|
||||
|
||||
|
||||
if (tokens.size() > 1)
|
||||
{
|
||||
untokenizedValue.m_name = tokens[0];
|
||||
@@ -1519,7 +1519,7 @@ ScriptContextDebug::SetValue(const DebugValue& sourceValue)
|
||||
{
|
||||
int iLocal = 1;
|
||||
const char* localName;
|
||||
while ((localName = lua_getlocal(l, m_luaDebug, iLocal)) != NULL)
|
||||
while ((localName = lua_getlocal(l, m_luaDebug, iLocal)) != nullptr)
|
||||
{
|
||||
lua_pop(l, 1);
|
||||
if (localName[0] != '(' && strcmp(name, localName) == 0)
|
||||
|
||||
@@ -209,39 +209,35 @@ namespace AZ
|
||||
//! performance sensitive code.
|
||||
AZ_INLINE bool CompareAnyValue(const AZStd::any& lhs, const AZStd::any& rhs)
|
||||
{
|
||||
bool isEqual = false;
|
||||
|
||||
if (lhs.type() != rhs.type())
|
||||
if (lhs.type() == rhs.type())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
AZ::SerializeContext* serializeContext = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
|
||||
|
||||
AZ::SerializeContext* serializeContext = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
|
||||
|
||||
const AZ::SerializeContext::ClassData* classData = serializeContext->FindClassData(lhs.type());
|
||||
if (classData)
|
||||
{
|
||||
if (classData->m_serializer)
|
||||
const AZ::SerializeContext::ClassData* classData = serializeContext->FindClassData(lhs.type());
|
||||
if (classData)
|
||||
{
|
||||
isEqual = classData->m_serializer->CompareValueData(AZStd::any_cast<void>(&lhs), AZStd::any_cast<void>(&rhs));
|
||||
}
|
||||
else
|
||||
{
|
||||
AZStd::vector<AZ::u8> myData;
|
||||
AZ::IO::ByteContainerStream<decltype(myData)> myDataStream(&myData);
|
||||
if (classData->m_serializer)
|
||||
{
|
||||
return classData->m_serializer->CompareValueData(AZStd::any_cast<void>(&lhs), AZStd::any_cast<void>(&rhs));
|
||||
}
|
||||
else
|
||||
{
|
||||
AZStd::vector<AZ::u8> myData;
|
||||
AZ::IO::ByteContainerStream<decltype(myData)> myDataStream(&myData);
|
||||
|
||||
AZ::Utils::SaveObjectToStream(myDataStream, AZ::ObjectStream::ST_BINARY, AZStd::any_cast<void>(&lhs), lhs.type());
|
||||
AZ::Utils::SaveObjectToStream(myDataStream, AZ::ObjectStream::ST_BINARY, AZStd::any_cast<void>(&lhs), lhs.type());
|
||||
|
||||
AZStd::vector<AZ::u8> otherData;
|
||||
AZ::IO::ByteContainerStream<decltype(otherData)> otherDataStream(&otherData);
|
||||
AZStd::vector<AZ::u8> otherData;
|
||||
AZ::IO::ByteContainerStream<decltype(otherData)> otherDataStream(&otherData);
|
||||
|
||||
AZ::Utils::SaveObjectToStream(otherDataStream, AZ::ObjectStream::ST_BINARY, AZStd::any_cast<void>(&rhs), rhs.type());
|
||||
isEqual = (myData.size() == otherData.size()) && (memcmp(myData.data(), otherData.data(), myData.size()) == 0);
|
||||
AZ::Utils::SaveObjectToStream(otherDataStream, AZ::ObjectStream::ST_BINARY, AZStd::any_cast<void>(&rhs), rhs.type());
|
||||
return (myData.size() == otherData.size()) && (memcmp(myData.data(), otherData.data(), myData.size()) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isEqual;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1320,7 +1320,7 @@ namespace AZ
|
||||
(void)classElement;
|
||||
void* reserveElement{};
|
||||
using DummyArray = bool[];
|
||||
DummyArray{ true, (ReserveElementTuple<Indices>(tupleRef, classElement, reserveElement))... };
|
||||
[[maybe_unused]] DummyArray dummy = { true, (ReserveElementTuple<Indices>(tupleRef, classElement, reserveElement))... };
|
||||
return reserveElement;
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +135,6 @@ namespace AZ
|
||||
AZStd::list<SerializeContext::ClassElement> m_dynamicClassElements; ///< Storage for class elements that represent dynamic serializable fields.
|
||||
};
|
||||
|
||||
static bool ConvertLegacyBoolToEnum(AZ::SerializeContext& context, AZStd::any& patchAny, const DataNode& sourceNode);
|
||||
static void ReportDataPatchMismatch(SerializeContext* context, const SerializeContext::ClassElement* classElement, const TypeId& patchDataTypeId);
|
||||
|
||||
//=========================================================================
|
||||
|
||||
@@ -213,9 +213,13 @@ namespace AZ
|
||||
void* object, const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context, ContinuationFlags flags)
|
||||
{
|
||||
bool loadAsNewInstance = (flags & ContinuationFlags::LoadAsNewInstance) == ContinuationFlags::LoadAsNewInstance;
|
||||
JsonDeserializer::UseTypeDeserializer useCustom = (flags & ContinuationFlags::IgnoreTypeSerializer) == ContinuationFlags::IgnoreTypeSerializer
|
||||
? JsonDeserializer::UseTypeDeserializer::No
|
||||
: JsonDeserializer::UseTypeDeserializer::Yes;
|
||||
|
||||
return (flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer
|
||||
? JsonDeserializer::LoadToPointer(object, typeId, value, context)
|
||||
: JsonDeserializer::Load(object, typeId, value, loadAsNewInstance, context);
|
||||
? JsonDeserializer::LoadToPointer(object, typeId, value, useCustom, context)
|
||||
: JsonDeserializer::Load(object, typeId, value, loadAsNewInstance, useCustom, context);
|
||||
}
|
||||
|
||||
JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueStoring(
|
||||
@@ -224,11 +228,15 @@ namespace AZ
|
||||
{
|
||||
using namespace JsonSerializationResult;
|
||||
|
||||
JsonSerializer::UseTypeSerializer useCustom = (flags & ContinuationFlags::IgnoreTypeSerializer) == ContinuationFlags::IgnoreTypeSerializer
|
||||
? JsonSerializer::UseTypeSerializer::No
|
||||
: JsonSerializer::UseTypeSerializer::Yes;
|
||||
|
||||
if ((flags & ContinuationFlags::ReplaceDefault) == ContinuationFlags::ReplaceDefault && !context.ShouldKeepDefaults())
|
||||
{
|
||||
if ((flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer)
|
||||
{
|
||||
return JsonSerializer::StoreFromPointer(output, object, nullptr, typeId, context);
|
||||
return JsonSerializer::StoreFromPointer(output, object, nullptr, typeId, useCustom, context);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -241,19 +249,19 @@ namespace AZ
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return result.Combine(JsonSerializer::Store(output, object, nullptr, typeId, context));
|
||||
return result.Combine(JsonSerializer::Store(output, object, nullptr, typeId, useCustom, context));
|
||||
}
|
||||
else
|
||||
{
|
||||
void* defaultObjectPtr = AZStd::any_cast<void>(&newDefaultObject);
|
||||
return JsonSerializer::Store(output, object, defaultObjectPtr, typeId, context);
|
||||
return JsonSerializer::Store(output, object, defaultObjectPtr, typeId, useCustom, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer ?
|
||||
JsonSerializer::StoreFromPointer(output, object, defaultObject, typeId, context) :
|
||||
JsonSerializer::Store(output, object, defaultObject, typeId, context);
|
||||
JsonSerializer::StoreFromPointer(output, object, defaultObject, typeId, useCustom, context) :
|
||||
JsonSerializer::Store(output, object, defaultObject, typeId, useCustom, context);
|
||||
}
|
||||
|
||||
JsonSerializationResult::ResultCode BaseJsonSerializer::LoadTypeId(Uuid& typeId, const rapidjson::Value& input,
|
||||
|
||||
@@ -159,12 +159,13 @@ namespace AZ
|
||||
|
||||
enum class ContinuationFlags
|
||||
{
|
||||
None = 0, //! No extra flags.
|
||||
ResolvePointer = 1 << 0, //! The pointer passed in contains a pointer. The (de)serializer will attempt to resolve to an instance.
|
||||
ReplaceDefault = 1 << 1, //! The default value provided for storing will be replaced with a newly created one.
|
||||
LoadAsNewInstance = 1 << 2 //! Treats the value as if it's a newly created instance. This may trigger serializers marked with
|
||||
//! OperationFlags::InitializeNewInstance. Used for instance by pointers or new instances added to
|
||||
//! an array.
|
||||
None = 0, //! No extra flags.
|
||||
ResolvePointer = 1 << 0, //! The pointer passed in contains a pointer. The (de)serializer will attempt to resolve to an instance.
|
||||
ReplaceDefault = 1 << 1, //! The default value provided for storing will be replaced with a newly created one.
|
||||
LoadAsNewInstance = 1 << 2, //! Treats the value as if it's a newly created instance. This may trigger serializers marked with
|
||||
//! OperationFlags::InitializeNewInstance. Used for instance by pointers or new instances added to
|
||||
//! an array.
|
||||
IgnoreTypeSerializer = 1 << 3, //! Ignore the custom/specific serializer for the TypeId
|
||||
};
|
||||
|
||||
enum class OperationFlags
|
||||
|
||||
@@ -38,7 +38,8 @@ namespace AZ
|
||||
}
|
||||
|
||||
JsonSerializationResult::ResultCode JsonDeserializer::Load(
|
||||
void* object, const Uuid& typeId, const rapidjson::Value& value, bool isNewInstance, JsonDeserializerContext& context)
|
||||
void* object, const Uuid& typeId, const rapidjson::Value& value, bool isNewInstance, UseTypeDeserializer custom,
|
||||
JsonDeserializerContext& context)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
@@ -48,8 +49,8 @@ namespace AZ
|
||||
"Target object for Json Serialization is pointing to nothing during loading.");
|
||||
}
|
||||
|
||||
BaseJsonSerializer* serializer = context.GetRegistrationContext()->GetSerializerForType(typeId);
|
||||
if (serializer)
|
||||
if (BaseJsonSerializer* serializer
|
||||
= (custom == UseTypeDeserializer::Yes ? context.GetRegistrationContext()->GetSerializerForType(typeId) : nullptr))
|
||||
{
|
||||
return DeserializerDefaultCheck(serializer, object, typeId, value, isNewInstance, context);
|
||||
}
|
||||
@@ -70,8 +71,11 @@ namespace AZ
|
||||
// type itself has not been reflected using EnumBuilder. Treat it as an enum.
|
||||
return LoadEnum(object, *classData, value, context);
|
||||
}
|
||||
serializer = context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId());
|
||||
if (serializer)
|
||||
|
||||
if (BaseJsonSerializer* serializer
|
||||
= (custom == UseTypeDeserializer::Yes)
|
||||
? context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId())
|
||||
: nullptr)
|
||||
{
|
||||
return DeserializerDefaultCheck(serializer, object, typeId, value, isNewInstance, context);
|
||||
}
|
||||
@@ -101,7 +105,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
JsonSerializationResult::ResultCode JsonDeserializer::LoadToPointer(void* object, const Uuid& typeId,
|
||||
const rapidjson::Value& value, JsonDeserializerContext& context)
|
||||
const rapidjson::Value& value, UseTypeDeserializer useCustom, JsonDeserializerContext& context)
|
||||
{
|
||||
using namespace JsonSerializationResult;
|
||||
|
||||
@@ -134,7 +138,7 @@ namespace AZ
|
||||
const SerializeContext::ClassData* resolvedClassData = context.GetSerializeContext()->FindClassData(resolvedTypeId);
|
||||
if (resolvedClassData)
|
||||
{
|
||||
status = JsonDeserializer::Load(*objectPtr, resolvedTypeId, value, true, context);
|
||||
status = JsonDeserializer::Load(*objectPtr, resolvedTypeId, value, true, useCustom, context);
|
||||
|
||||
*objectPtr = resolvedClassData->m_azRtti->Cast(*objectPtr, typeId);
|
||||
|
||||
@@ -171,11 +175,11 @@ namespace AZ
|
||||
}
|
||||
AZ_Assert(classElement.m_azRtti->GetTypeId() == classElement.m_typeId,
|
||||
"Type id mismatch during deserialization of a json file. (%s vs %s)");
|
||||
return LoadToPointer(object, classElement.m_typeId, value, context);
|
||||
return LoadToPointer(object, classElement.m_typeId, value, UseTypeDeserializer::Yes, context);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Load(object, classElement.m_typeId, value, false, context);
|
||||
return Load(object, classElement.m_typeId, value, false, UseTypeDeserializer::Yes, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -571,11 +575,23 @@ namespace AZ
|
||||
if (loadedTypeId.m_determination == TypeIdDetermination::FailedToDetermine ||
|
||||
loadedTypeId.m_determination == TypeIdDetermination::FailedDueToMultipleTypeIds)
|
||||
{
|
||||
AZStd::string_view message = loadedTypeId.m_determination == TypeIdDetermination::FailedDueToMultipleTypeIds ?
|
||||
"Unable to resolve provided type because the same name points to multiple types." :
|
||||
"Unable to resolve provided type.";
|
||||
status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, message);
|
||||
return ResolvePointerResult::FullyProcessed;
|
||||
auto typeField = pointerData.FindMember(JsonSerialization::TypeIdFieldIdentifier);
|
||||
if (typeField != pointerData.MemberEnd() && typeField->value.IsString())
|
||||
{
|
||||
const char* format = loadedTypeId.m_determination == TypeIdDetermination::FailedToDetermine ?
|
||||
"Unable to resolve provided type: %.*s." :
|
||||
"Unable to resolve provided type %.*s because the same name points to multiple types.";
|
||||
status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown,
|
||||
AZStd::string::format(format, typeField->value.GetStringLength(), typeField->value.GetString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* message = loadedTypeId.m_determination == TypeIdDetermination::FailedToDetermine ?
|
||||
"Unable to resolve provided type." :
|
||||
"Unable to resolve provided type because the same name points to multiple types.";
|
||||
status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, message);
|
||||
}
|
||||
return ResolvePointerResult::FullyProcessed;
|
||||
}
|
||||
|
||||
if (loadedTypeId.m_typeId != objectType)
|
||||
|
||||
@@ -28,6 +28,11 @@ namespace AZ
|
||||
FullyProcessed,
|
||||
ContinueProcessing
|
||||
};
|
||||
enum class UseTypeDeserializer : bool
|
||||
{
|
||||
No,
|
||||
Yes
|
||||
};
|
||||
enum class TypeIdDetermination : u8
|
||||
{
|
||||
ExplicitTypeId, // Type id was explicitly defined using "$type".
|
||||
@@ -55,10 +60,11 @@ namespace AZ
|
||||
JsonDeserializer(JsonDeserializer&& rhs) = delete;
|
||||
|
||||
static JsonSerializationResult::ResultCode Load(
|
||||
void* object, const Uuid& typeId, const rapidjson::Value& value, bool isNewInstance, JsonDeserializerContext& context);
|
||||
void* object, const Uuid& typeId, const rapidjson::Value& value, bool isNewInstance, UseTypeDeserializer useCustom,
|
||||
JsonDeserializerContext& context);
|
||||
|
||||
static JsonSerializationResult::ResultCode LoadToPointer(void* object, const Uuid& typeId, const rapidjson::Value& value,
|
||||
JsonDeserializerContext& context);
|
||||
UseTypeDeserializer useCustom, JsonDeserializerContext& context);
|
||||
|
||||
static JsonSerializationResult::ResultCode LoadWithClassElement(void* object, const rapidjson::Value& value,
|
||||
const SerializeContext::ClassElement& classElement, JsonDeserializerContext& context);
|
||||
|
||||
@@ -245,7 +245,7 @@ namespace AZ
|
||||
{
|
||||
StackedString path(StackedString::Format::JsonPointer);
|
||||
JsonDeserializerContext context(settings);
|
||||
result = JsonDeserializer::Load(object, objectType, root, false, context);
|
||||
result = JsonDeserializer::Load(object, objectType, root, false, JsonDeserializer::UseTypeDeserializer::Yes, context);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -322,7 +322,7 @@ namespace AZ
|
||||
|
||||
JsonSerializerContext context(settings, allocator);
|
||||
StackedString path(StackedString::Format::ContextPath);
|
||||
result = JsonSerializer::Store(output, object, defaultObject, objectType, context);
|
||||
result = JsonSerializer::Store(output, object, defaultObject, objectType, JsonSerializer::UseTypeSerializer::Yes, context);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
namespace AZ
|
||||
{
|
||||
JsonSerializationResult::ResultCode JsonSerializer::Store(rapidjson::Value& output, const void* object, const void* defaultObject,
|
||||
const Uuid& typeId, JsonSerializerContext& context)
|
||||
const Uuid& typeId, UseTypeSerializer custom, JsonSerializerContext& context)
|
||||
{
|
||||
using namespace JsonSerializationResult;
|
||||
|
||||
@@ -32,8 +32,8 @@ namespace AZ
|
||||
|
||||
// First check if there's a generic serializer registered for this. This makes it possible to use serializers that
|
||||
// are not (directly) registered with the Serialize Context.
|
||||
auto serializer = context.GetRegistrationContext()->GetSerializerForType(typeId);
|
||||
if (serializer)
|
||||
if (BaseJsonSerializer* serializer
|
||||
= (custom == UseTypeSerializer::Yes ? context.GetRegistrationContext()->GetSerializerForType(typeId) : nullptr))
|
||||
{
|
||||
// Start by setting the object to be an explicit default.
|
||||
output.SetObject();
|
||||
@@ -57,17 +57,18 @@ namespace AZ
|
||||
"No factory available to create a default object for comparison.");
|
||||
}
|
||||
void* defaultObjectPtr = AZStd::any_cast<void>(&defaultObjectInstance);
|
||||
ResultCode conversionResult = StoreWithClassData(output, object, defaultObjectPtr, *classData, StoreTypeId::No, context);
|
||||
ResultCode conversionResult = StoreWithClassData(output, object, defaultObjectPtr, *classData, StoreTypeId::No
|
||||
, UseTypeSerializer::Yes, context);
|
||||
return ResultCode::Combine(result, conversionResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
return StoreWithClassData(output, object, defaultObject, *classData, StoreTypeId::No, context);
|
||||
return StoreWithClassData(output, object, defaultObject, *classData, StoreTypeId::No, custom, context);
|
||||
}
|
||||
}
|
||||
|
||||
JsonSerializationResult::ResultCode JsonSerializer::StoreFromPointer(rapidjson::Value& output, const void* object,
|
||||
const void* defaultObject, const Uuid& typeId, JsonSerializerContext& context)
|
||||
const void* defaultObject, const Uuid& typeId, UseTypeSerializer custom, JsonSerializerContext& context)
|
||||
{
|
||||
using namespace JsonSerializationResult;
|
||||
|
||||
@@ -85,19 +86,21 @@ namespace AZ
|
||||
AZ_Assert(classData->m_azRtti->GetTypeId() == typeId, "Type id mismatch in '%s' during serialization to a json file. (%s vs %s)",
|
||||
classData->m_name, classData->m_azRtti->GetTypeId().ToString<AZStd::string>().c_str(), typeId.ToString<AZStd::string>().c_str());
|
||||
|
||||
return StoreWithClassDataFromPointer(output, object, defaultObject, *classData, context);
|
||||
return StoreWithClassDataFromPointer(output, object, defaultObject, *classData, custom, context);
|
||||
}
|
||||
|
||||
JsonSerializationResult::ResultCode JsonSerializer::StoreWithClassData(rapidjson::Value& node, const void* object,
|
||||
const void* defaultObject, const SerializeContext::ClassData& classData, StoreTypeId storeTypeId,
|
||||
JsonSerializerContext& context)
|
||||
UseTypeSerializer custom, JsonSerializerContext& context)
|
||||
{
|
||||
using namespace JsonSerializationResult;
|
||||
|
||||
// Start by setting the object to be an explicit default.
|
||||
node.SetObject();
|
||||
|
||||
auto serializer = context.GetRegistrationContext()->GetSerializerForType(classData.m_typeId);
|
||||
auto serializer = custom == UseTypeSerializer::Yes
|
||||
? context.GetRegistrationContext()->GetSerializerForType(classData.m_typeId) : nullptr;
|
||||
|
||||
if (serializer)
|
||||
{
|
||||
ResultCode result = serializer->Store(node, object, defaultObject, classData.m_typeId, context);
|
||||
@@ -153,12 +156,11 @@ namespace AZ
|
||||
}
|
||||
|
||||
JsonSerializationResult::ResultCode JsonSerializer::StoreWithClassDataFromPointer(rapidjson::Value& output, const void* object,
|
||||
const void* defaultObject, const SerializeContext::ClassData& classData, JsonSerializerContext& context)
|
||||
const void* defaultObject, const SerializeContext::ClassData& classData, UseTypeSerializer custom, JsonSerializerContext& context)
|
||||
{
|
||||
using namespace JsonSerializationResult;
|
||||
|
||||
StoreTypeId storeTypeId = StoreTypeId::No;
|
||||
Uuid resolvedTypeId = classData.m_typeId;
|
||||
const SerializeContext::ClassData* resolvedClassData = &classData;
|
||||
AZStd::any defaultPointerObject;
|
||||
|
||||
@@ -176,7 +178,7 @@ namespace AZ
|
||||
}
|
||||
else
|
||||
{
|
||||
return StoreWithClassData(output, object, defaultObject, *resolvedClassData, storeTypeId, context);
|
||||
return StoreWithClassData(output, object, defaultObject, *resolvedClassData, storeTypeId, custom, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,8 +223,8 @@ namespace AZ
|
||||
{
|
||||
rapidjson::Value value;
|
||||
ResultCode result = classElement.m_flags & SerializeContext::ClassElement::FLG_POINTER ?
|
||||
StoreWithClassDataFromPointer(value, object, defaultObject, *elementClassData, context):
|
||||
StoreWithClassData(value, object, defaultObject, *elementClassData, StoreTypeId::No, context);
|
||||
StoreWithClassDataFromPointer(value, object, defaultObject, *elementClassData, UseTypeSerializer::Yes, context):
|
||||
StoreWithClassData(value, object, defaultObject, *elementClassData, StoreTypeId::No, UseTypeSerializer::Yes, context);
|
||||
if (result.GetProcessing() != Processing::Halted)
|
||||
{
|
||||
if (parentNode.IsObject())
|
||||
|
||||
@@ -26,6 +26,11 @@ namespace AZ
|
||||
No,
|
||||
Yes
|
||||
};
|
||||
enum class UseTypeSerializer : bool
|
||||
{
|
||||
No,
|
||||
Yes
|
||||
};
|
||||
enum class ResolvePointerResult
|
||||
{
|
||||
FullyProcessed,
|
||||
@@ -41,16 +46,18 @@ namespace AZ
|
||||
JsonSerializer(JsonSerializer&& rhs) = delete;
|
||||
|
||||
static JsonSerializationResult::ResultCode Store(rapidjson::Value& output, const void* object, const void* defaultObject,
|
||||
const Uuid& typeId, JsonSerializerContext& context);
|
||||
const Uuid& typeId, UseTypeSerializer useCustom, JsonSerializerContext& context);
|
||||
|
||||
static JsonSerializationResult::ResultCode StoreFromPointer(rapidjson::Value& output, const void* object, const void* defaultObject,
|
||||
const Uuid& typeId, JsonSerializerContext& context);
|
||||
const Uuid& typeId, UseTypeSerializer custom, JsonSerializerContext& context);
|
||||
|
||||
static JsonSerializationResult::ResultCode StoreWithClassData(rapidjson::Value& node, const void* object, const void* defaultObject,
|
||||
const SerializeContext::ClassData& classData, StoreTypeId storeTypeId, JsonSerializerContext& context);
|
||||
const SerializeContext::ClassData& classData, StoreTypeId storeTypeId, UseTypeSerializer custom,
|
||||
JsonSerializerContext& context);
|
||||
|
||||
static JsonSerializationResult::ResultCode StoreWithClassDataFromPointer(rapidjson::Value& output, const void* object,
|
||||
const void* defaultObject, const SerializeContext::ClassData& classData, JsonSerializerContext& context);
|
||||
const void* defaultObject, const SerializeContext::ClassData& classData, UseTypeSerializer custom,
|
||||
JsonSerializerContext& context);
|
||||
|
||||
static JsonSerializationResult::ResultCode StoreWithClassElement(rapidjson::Value& parentNode, const void* object,
|
||||
const void* defaultObject, const SerializeContext::ClassElement& classElement, JsonSerializerContext& context);
|
||||
|
||||
+14
-4
@@ -6,7 +6,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AtomCore/Serialization/Json/JsonUtils.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
@@ -23,6 +22,8 @@
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
#include <AzCore/Serialization/Json/JsonUtils.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace JsonSerializationUtils
|
||||
@@ -31,7 +32,6 @@ namespace AZ
|
||||
static const char* FileType = "JsonSerialization";
|
||||
static const char* VersionTag = "Version";
|
||||
static const char* ClassNameTag = "ClassName";
|
||||
static const char* ClassIdTag = "ClassId";
|
||||
static const char* ClassDataTag = "ClassData";
|
||||
|
||||
AZ::Outcome<void, AZStd::string> WriteJsonString(const rapidjson::Document& document, AZStd::string& jsonText, WriteJsonSettings settings)
|
||||
@@ -209,6 +209,11 @@ namespace AZ
|
||||
|
||||
AZ::Outcome<rapidjson::Document, AZStd::string> ReadJsonString(AZStd::string_view jsonText)
|
||||
{
|
||||
if (jsonText.empty())
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Failed to parse JSON: input string is empty."));
|
||||
}
|
||||
|
||||
rapidjson::Document jsonDocument;
|
||||
jsonDocument.Parse<rapidjson::kParseCommentsFlag>(jsonText.data(), jsonText.size());
|
||||
if (jsonDocument.HasParseError())
|
||||
@@ -332,6 +337,11 @@ namespace AZ
|
||||
|
||||
// validate class name
|
||||
auto classData = loadSettings.m_serializeContext->FindClassData(classId);
|
||||
if (!classData)
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("Try to load class from Id %s", classId.ToString<AZStd::string>().c_str()));
|
||||
}
|
||||
|
||||
if (azstricmp(classData->m_name, className) != 0)
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("Try to load class %s from class %s data", classData->m_name, className));
|
||||
@@ -343,9 +353,9 @@ namespace AZ
|
||||
{
|
||||
return AZ::Failure(deserializeErrors);
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
AZ::Outcome<AZStd::any, AZStd::string> LoadAnyObjectFromStream(IO::GenericStream& stream, const JsonDeserializerSettings* settings)
|
||||
{
|
||||
@@ -43,7 +43,7 @@ namespace AZ
|
||||
|
||||
if (!overwriteExisting)
|
||||
{
|
||||
auto emplaceResult = m_context->m_handledTypesMap.try_emplace(uuid, serializer);
|
||||
[[maybe_unused]] auto emplaceResult = m_context->m_handledTypesMap.try_emplace(uuid, serializer);
|
||||
AZ_Assert(
|
||||
emplaceResult.second,
|
||||
"Couldn't register Json serializer %s. Another serializer (%s) has already been registered for the same Uuid (%s).",
|
||||
|
||||
@@ -1520,6 +1520,7 @@ namespace AZ
|
||||
{
|
||||
if (m_writeElementResultStack.empty())
|
||||
{
|
||||
AZ_UNUSED(classData); // Prevent unused warning in release builds
|
||||
AZ_Error("Serialize", false, "CloseElement is attempted to be called without a corresponding WriteElement when writing class %s", classData->m_name);
|
||||
return true;
|
||||
}
|
||||
@@ -1581,6 +1582,7 @@ namespace AZ
|
||||
{
|
||||
if (m_writeElementResultStack.empty())
|
||||
{
|
||||
AZ_UNUSED(classData); // Prevent unused warning in release builds
|
||||
AZ_Error("Serialize", false, "CloseElement is attempted to be called without a corresponding WriteElement when writing class %s", classData->m_name);
|
||||
return true;
|
||||
}
|
||||
@@ -1644,6 +1646,7 @@ namespace AZ
|
||||
{
|
||||
if (m_writeElementResultStack.empty())
|
||||
{
|
||||
AZ_UNUSED(classData); // Prevent unused warning in release builds
|
||||
AZ_Error("Serialize", false, "CloseElement is attempted to be called without a corresponding WriteElement when writing class %s", classData->m_name);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace AZ
|
||||
AZ_Assert(targetPointer, "You must provide a target pointer");
|
||||
|
||||
bool foundSuccess = false;
|
||||
typedef AZStd::function<void(void**, const SerializeContext::ClassData**, const Uuid&, SerializeContext*)> CreationCallback;
|
||||
using CreationCallback = AZStd::function<void (void **, const SerializeContext::ClassData **, const Uuid &, SerializeContext *)>;
|
||||
auto handler = [&targetPointer, objectClassData, &foundSuccess](void** instance, const SerializeContext::ClassData** classData, const Uuid& classId, SerializeContext* context)
|
||||
{
|
||||
void* convertibleInstance{};
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace AZ
|
||||
{
|
||||
AZ_Assert(textVersion == 0, "Unknown char, short, int version!");
|
||||
(void)textVersion;
|
||||
long value = strtol(text, NULL, 10);
|
||||
long value = strtol(text, nullptr, 10);
|
||||
AZ_SERIALIZE_SWAP_ENDIAN(value, isDataBigEndian);
|
||||
return static_cast<size_t>(stream.Write(sizeof(T), reinterpret_cast<void*>(&value)));
|
||||
}
|
||||
@@ -124,7 +124,7 @@ namespace AZ
|
||||
{
|
||||
AZ_Assert(textVersion == 0, "Unknown unsigned char, short, int version!");
|
||||
(void)textVersion;
|
||||
unsigned long value = strtoul(text, NULL, 10);
|
||||
unsigned long value = strtoul(text, nullptr, 10);
|
||||
AZ_SERIALIZE_SWAP_ENDIAN(value, isDataBigEndian);
|
||||
return static_cast<size_t>(stream.Write(sizeof(T), reinterpret_cast<void*>(&value)));
|
||||
}
|
||||
@@ -158,7 +158,7 @@ namespace AZ
|
||||
{
|
||||
AZ_Assert(textVersion == 0, "Unknown unsigned char, short, int version!");
|
||||
(void)textVersion;
|
||||
long value = strtol(text, NULL, 10);
|
||||
long value = strtol(text, nullptr, 10);
|
||||
AZ_SERIALIZE_SWAP_ENDIAN(value, isDataBigEndian);
|
||||
return static_cast<size_t>(stream.Write(sizeof(T), reinterpret_cast<void*>(&value)));
|
||||
}
|
||||
@@ -192,7 +192,7 @@ namespace AZ
|
||||
{
|
||||
AZ_Assert(textVersion == 0, "Unknown unsigned char, short, int version!");
|
||||
(void)textVersion;
|
||||
unsigned long value = strtoul(text, NULL, 10);
|
||||
unsigned long value = strtoul(text, nullptr, 10);
|
||||
AZ_SERIALIZE_SWAP_ENDIAN(value, isDataBigEndian);
|
||||
return static_cast<size_t>(stream.Write(sizeof(T), reinterpret_cast<void*>(&value)));
|
||||
}
|
||||
@@ -225,7 +225,7 @@ namespace AZ
|
||||
{
|
||||
AZ_Assert(textVersion == 0, "Unknown unsigned char, short, int version!");
|
||||
(void)textVersion;
|
||||
AZ::s64 value = strtoll(text, NULL, 10);
|
||||
AZ::s64 value = strtoll(text, nullptr, 10);
|
||||
AZ_SERIALIZE_SWAP_ENDIAN(value, isDataBigEndian);
|
||||
return static_cast<size_t>(stream.Write(sizeof(AZ::s64), reinterpret_cast<void*>(&value)));
|
||||
}
|
||||
@@ -258,7 +258,7 @@ namespace AZ
|
||||
{
|
||||
AZ_Assert(textVersion == 0, "Unknown unsigned char, short, int version!");
|
||||
(void)textVersion;
|
||||
unsigned long long value = strtoull(text, NULL, 10);
|
||||
unsigned long long value = strtoull(text, nullptr, 10);
|
||||
AZ_SERIALIZE_SWAP_ENDIAN(value, isDataBigEndian);
|
||||
return static_cast<size_t>(stream.Write(sizeof(AZ::u64), reinterpret_cast<void*>(&value)));
|
||||
}
|
||||
@@ -292,7 +292,7 @@ namespace AZ
|
||||
{
|
||||
AZ_Assert(textVersion == 0, "Unknown float/double version!");
|
||||
(void)textVersion;
|
||||
double value = strtod(text, NULL);
|
||||
double value = strtod(text, nullptr);
|
||||
AZ_SERIALIZE_SWAP_ENDIAN(value, isDataBigEndian);
|
||||
|
||||
T data = static_cast<T>(value);
|
||||
@@ -815,7 +815,7 @@ namespace AZ
|
||||
const ClassData* fromClass = FindClassData(fromClassId);
|
||||
if (!fromClass)
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < fromClass->m_elements.size(); ++i)
|
||||
@@ -831,7 +831,7 @@ namespace AZ
|
||||
|
||||
if (!fromClass->m_azRtti)
|
||||
{
|
||||
return NULL; // Reflection info failed to cast and we can't find rtti info
|
||||
return nullptr; // Reflection info failed to cast and we can't find rtti info
|
||||
}
|
||||
fromClassHelper = fromClass->m_azRtti;
|
||||
}
|
||||
@@ -841,7 +841,7 @@ namespace AZ
|
||||
const ClassData* toClass = FindClassData(toClassId);
|
||||
if (!toClass || !toClass->m_azRtti)
|
||||
{
|
||||
return NULL; // We can't cast without class data or rtti helper
|
||||
return nullptr; // We can't cast without class data or rtti helper
|
||||
}
|
||||
toClassHelper = toClass->m_azRtti;
|
||||
}
|
||||
@@ -855,7 +855,7 @@ namespace AZ
|
||||
// [5/22/2012]
|
||||
//=========================================================================
|
||||
SerializeContext::DataElement::DataElement()
|
||||
: m_name(0)
|
||||
: m_name(nullptr)
|
||||
, m_nameCrc(0)
|
||||
, m_dataSize(0)
|
||||
, m_byteStream(&m_buffer)
|
||||
@@ -1045,7 +1045,7 @@ namespace AZ
|
||||
//=========================================================================
|
||||
bool SerializeContext::DataElementNode::Convert(SerializeContext& sc, const char* name, const Uuid& id)
|
||||
{
|
||||
AZ_Assert(name != NULL && strlen(name) > 0, "Empty name is an INVALID element name!");
|
||||
AZ_Assert(name != nullptr && strlen(name) > 0, "Empty name is an INVALID element name!");
|
||||
u32 nameCrc = Crc32(name);
|
||||
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
@@ -1165,7 +1165,7 @@ namespace AZ
|
||||
int SerializeContext::DataElementNode::AddElement(SerializeContext& sc, const char* name, const ClassData& classData)
|
||||
{
|
||||
(void)sc;
|
||||
AZ_Assert(name != NULL && strlen(name) > 0, "Empty name is an INVALID element name!");
|
||||
AZ_Assert(name != nullptr && strlen(name) > 0, "Empty name is an INVALID element name!");
|
||||
u32 nameCrc = Crc32(name);
|
||||
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
@@ -1703,7 +1703,7 @@ namespace AZ
|
||||
|
||||
m_classData->second.m_serializer = AZStd::move(serializer);
|
||||
return this;
|
||||
|
||||
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -1801,7 +1801,7 @@ namespace AZ
|
||||
void* objectPtr = ptr;
|
||||
const AZ::Uuid* classIdPtr = &classId;
|
||||
const SerializeContext::ClassData* dataClassInfo = classData;
|
||||
|
||||
|
||||
if (classElement)
|
||||
{
|
||||
// if we are a pointer, then we may be pointing to a derived type.
|
||||
@@ -1854,14 +1854,14 @@ namespace AZ
|
||||
DbgStackEntry de;
|
||||
de.m_dataPtr = objectPtr;
|
||||
de.m_uuidPtr = classIdPtr;
|
||||
de.m_elementName = classElement ? classElement->m_name : NULL;
|
||||
de.m_elementName = classElement ? classElement->m_name : nullptr;
|
||||
de.m_classData = dataClassInfo;
|
||||
de.m_classElement = classElement;
|
||||
callContext->m_errorHandler->Push(de);
|
||||
}
|
||||
#endif // AZ_ENABLE_SERIALIZER_DEBUG
|
||||
|
||||
if (dataClassInfo == NULL)
|
||||
if (dataClassInfo == nullptr)
|
||||
{
|
||||
#if defined (AZ_ENABLE_SERIALIZER_DEBUG)
|
||||
AZStd::string error;
|
||||
@@ -2182,9 +2182,9 @@ namespace AZ
|
||||
|
||||
AZ::SerializeContext::DataPatchUpgradeHandler::~DataPatchUpgradeHandler()
|
||||
{
|
||||
for (auto fieldUpgrades : m_upgrades)
|
||||
for (const auto& fieldUpgrades : m_upgrades)
|
||||
{
|
||||
for (auto versionUpgrades : fieldUpgrades.second)
|
||||
for (const auto& versionUpgrades : fieldUpgrades.second)
|
||||
{
|
||||
for (auto* upgrade : versionUpgrades.second)
|
||||
{
|
||||
@@ -2192,8 +2192,8 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AZ::SerializeContext::DataPatchUpgradeHandler::AddFieldUpgrade(DataPatchUpgrade* upgrade)
|
||||
{
|
||||
// Find the field
|
||||
@@ -2448,7 +2448,7 @@ namespace AZ
|
||||
classData->m_eventHandler->OnWriteEnd(dataPtr);
|
||||
classData->m_eventHandler->OnObjectCloned(dataPtr);
|
||||
}
|
||||
|
||||
|
||||
if (classData->m_serializer)
|
||||
{
|
||||
classData->m_serializer->PostClone(dataPtr);
|
||||
@@ -2489,7 +2489,7 @@ namespace AZ
|
||||
{
|
||||
if (cd.m_azRtti->IsTypeOf(typeId))
|
||||
{
|
||||
if (!callback(&cd, 0))
|
||||
if (!callback(&cd, nullptr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -2507,7 +2507,7 @@ namespace AZ
|
||||
// if both classes have azRtti they will be enumerated already by the code above (azrtti)
|
||||
if (cd.m_azRtti == nullptr || cd.m_elements[i].m_azRtti == nullptr)
|
||||
{
|
||||
if (!callback(&cd, 0))
|
||||
if (!callback(&cd, nullptr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -2539,7 +2539,7 @@ namespace AZ
|
||||
if (baseClassData)
|
||||
{
|
||||
callbackData.m_reportedTypes.push_back(baseClassData->m_typeId);
|
||||
if (!callback(baseClassData, 0))
|
||||
if (!callback(baseClassData, nullptr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -2586,8 +2586,8 @@ namespace AZ
|
||||
void SerializeContext::RegisterDataContainer(AZStd::unique_ptr<IDataContainer> dataContainer)
|
||||
{
|
||||
m_dataContainers.push_back(AZStd::move(dataContainer));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// EnumerateBaseRTTIEnumCallback
|
||||
// [11/13/2012]
|
||||
@@ -2731,10 +2731,10 @@ namespace AZ
|
||||
//=========================================================================
|
||||
void SerializeContext::IDataContainer::DeletePointerData(SerializeContext* context, const ClassElement* classElement, const void* element)
|
||||
{
|
||||
AZ_Assert(context != NULL && classElement != NULL && element != NULL, "Invalid input");
|
||||
AZ_Assert(context != nullptr && classElement != nullptr && element != nullptr, "Invalid input");
|
||||
const AZ::Uuid* elemUuid = &classElement->m_typeId;
|
||||
// find the class data for the specific element
|
||||
const SerializeContext::ClassData* classData = classElement->m_genericClassInfo ? classElement->m_genericClassInfo->GetClassData() : context->FindClassData(*elemUuid, NULL, 0);
|
||||
const SerializeContext::ClassData* classData = classElement->m_genericClassInfo ? classElement->m_genericClassInfo->GetClassData() : context->FindClassData(*elemUuid, nullptr, 0);
|
||||
if (classElement->m_flags & SerializeContext::ClassElement::FLG_POINTER)
|
||||
{
|
||||
const void* dataPtr = *reinterpret_cast<void* const*>(element);
|
||||
@@ -2745,7 +2745,7 @@ namespace AZ
|
||||
if (*actualClassId != *elemUuid)
|
||||
{
|
||||
// we are pointing to derived type, adjust class data, uuid and pointer.
|
||||
classData = context->FindClassData(*actualClassId, NULL, 0);
|
||||
classData = context->FindClassData(*actualClassId, nullptr, 0);
|
||||
elemUuid = actualClassId;
|
||||
if (classData)
|
||||
{
|
||||
@@ -2754,7 +2754,7 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
}
|
||||
if (classData == NULL)
|
||||
if (classData == nullptr)
|
||||
{
|
||||
if ((classElement->m_flags & ClassElement::FLG_POINTER) != 0)
|
||||
{
|
||||
@@ -3250,7 +3250,7 @@ namespace AZ
|
||||
return m_moduleOSAllocator;
|
||||
}
|
||||
|
||||
// Take advantage of static variables being unique per dll module to clean up module specific registered classes when the module unloads
|
||||
// Take advantage of static variables being unique per dll module to clean up module specific registered classes when the module unloads
|
||||
SerializeContext::PerModuleGenericClassInfo& GetCurrentSerializeContextModule()
|
||||
{
|
||||
static SerializeContext::PerModuleGenericClassInfo s_ModuleCleanupInstance;
|
||||
|
||||
@@ -602,7 +602,7 @@ namespace AZ
|
||||
///< @param resultPtr output parameter that is populated with the memory address that can be used to store an element of the convertible type
|
||||
///< @param convertibleTypeId type to check to determine if it can converted to an element of class represent by this Class Data
|
||||
///< @param classPtr memory address of the class represented by the ClassData
|
||||
///< @return true if a non-null memory address has been returned that can store the convertible type
|
||||
///< @return true if a non-null memory address has been returned that can store the convertible type
|
||||
bool ConvertFromType(void*& convertibleTypePtr, const TypeId& convertibleTypeId, void* classPtr, AZ::SerializeContext& serializeContext) const;
|
||||
|
||||
/// Find the persistence id (check base classes) \todo this is a TEMP fix, analyze and cache that information in the class
|
||||
@@ -797,8 +797,8 @@ namespace AZ
|
||||
virtual void* ReserveElement(void* instance, const ClassElement* classElement) = 0;
|
||||
/// Free an element that was reserved using ReserveElement, but was not stored by calling StoreElement.
|
||||
virtual void FreeReservedElement(void* instance, void* element, SerializeContext* deletePointerDataContext)
|
||||
{
|
||||
RemoveElement(instance, element, deletePointerDataContext);
|
||||
{
|
||||
RemoveElement(instance, element, deletePointerDataContext);
|
||||
}
|
||||
/// Get an element's address by its index (called before the element is loaded).
|
||||
virtual void* GetElementByIndex(void* instance, const ClassElement* classElement, size_t index) = 0;
|
||||
@@ -858,7 +858,7 @@ namespace AZ
|
||||
|
||||
/**
|
||||
* Data Converter interface which can be used to provide a conversion operation from to unrelated C++ types
|
||||
* derived class to base class casting is taken care of through the RTTI system so those relations should not be
|
||||
* derived class to base class casting is taken care of through the RTTI system so those relations should not be
|
||||
* check within this class
|
||||
*/
|
||||
class IDataConverter
|
||||
@@ -879,7 +879,7 @@ namespace AZ
|
||||
///< @param convertibleTypeId type to check to determine if it can converted to an element of class represent by this Class Data
|
||||
///< @param classPtr memory address of the class represented by the @classData type
|
||||
///< @param classData reference to the metadata representing the type stored in classPtr
|
||||
///< @return true if a non-null memory address has been returned that can store the convertible type
|
||||
///< @return true if a non-null memory address has been returned that can store the convertible type
|
||||
virtual bool ConvertFromType(void*& convertibleTypePtr, const TypeId& convertibleTypeId, void* classPtr, const SerializeContext::ClassData& classData, SerializeContext& /*serializeContext*/)
|
||||
{
|
||||
if (classData.m_typeId == convertibleTypeId)
|
||||
@@ -1054,7 +1054,7 @@ namespace AZ
|
||||
AZStd::vector<AZ::Uuid> FindClassId(const AZ::Crc32& classNameCrc) const;
|
||||
|
||||
/// Find GenericClassData data based on the supplied class ID
|
||||
GenericClassInfo* FindGenericClassInfo(const Uuid& classId) const;
|
||||
GenericClassInfo* FindGenericClassInfo(const Uuid& classId) const;
|
||||
|
||||
/// Creates an AZStd::any based on the provided class Uuid, or returns an empty AZStd::any if no class data is found or the class is virtual
|
||||
AZStd::any CreateAny(const Uuid& classId);
|
||||
@@ -1161,7 +1161,7 @@ namespace AZ
|
||||
|
||||
/* Declare a name change of a serialized field
|
||||
* These are used by the serializer to repair old data patches
|
||||
*
|
||||
*
|
||||
*/
|
||||
ClassBuilder* NameChange(unsigned int fromVersion, unsigned int toVersion, AZStd::string_view oldFieldName, AZStd::string_view newFieldName);
|
||||
|
||||
@@ -1403,7 +1403,7 @@ namespace AZ
|
||||
template<class ValueType>
|
||||
struct SerializeGenericTypeInfo
|
||||
{
|
||||
// Provides a specific type alias that can be used to create GenericClassInfo of the
|
||||
// Provides a specific type alias that can be used to create GenericClassInfo of the
|
||||
// specified type. By default this is GenericClassInfo class which is abstract
|
||||
using ClassInfoType = GenericClassInfo;
|
||||
|
||||
@@ -1938,7 +1938,7 @@ namespace AZ
|
||||
if (m_context->IsRemovingReflection())
|
||||
{
|
||||
// Delete any attributes allocated for this call.
|
||||
for (auto attributePair : attributes)
|
||||
for (auto& attributePair : attributes)
|
||||
{
|
||||
delete attributePair.second;
|
||||
}
|
||||
@@ -1955,7 +1955,7 @@ namespace AZ
|
||||
m_classData->second.m_name,
|
||||
AzTypeInfo<ClassType>::Name());
|
||||
|
||||
// SerializeGenericTypeInfo<ValueType>::GetClassTypeId() is needed solely because
|
||||
// SerializeGenericTypeInfo<ValueType>::GetClassTypeId() is needed solely because
|
||||
// the SerializeGenericTypeInfo specialization for AZ::Data::Asset<T> returns the GetAssetClassId() value
|
||||
// and not the AzTypeInfo<AZ::Data::Asset<T>>::Uuid()
|
||||
// Therefore in order to remain backwards compatible the SerializeGenericTypeInfo<ValueType>::GetClassTypeId specialization
|
||||
|
||||
@@ -483,9 +483,9 @@ namespace AZ
|
||||
}
|
||||
private:
|
||||
static void ObjectStreamWriter(SerializeContext::EnumerateInstanceCallContext& callContext, const void* variantPtr,
|
||||
const SerializeContext::ClassData& variantClassData, const SerializeContext::ClassElement* variantClassElement)
|
||||
[[maybe_unused]] const SerializeContext::ClassData& variantClassData, const SerializeContext::ClassElement* variantClassElement)
|
||||
{
|
||||
auto alternativeVisitor = [&callContext, &variantClassData, variantClassElement](auto&& elementAlt)
|
||||
auto alternativeVisitor = [&callContext, variantClassElement](auto&& elementAlt)
|
||||
{
|
||||
using AltType = AZStd::remove_cvref_t<decltype(elementAlt)>;
|
||||
const SerializeContext& context = *callContext.m_context;
|
||||
|
||||
@@ -550,7 +550,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
}
|
||||
registry.Set(FilePathKey_ProjectUserPath, projectUserPath.Native());
|
||||
|
||||
// Set the user directory with the provided path or using project/user as default
|
||||
// Set the log directory with the provided path or using project/user/log as default
|
||||
auto projectLogPathKey = FixedValueString::format("%s/project_log_path", BootstrapSettingsRootKey);
|
||||
AZ::IO::FixedMaxPath projectLogPath;
|
||||
if (!registry.Get(projectLogPath.Native(), projectLogPathKey))
|
||||
@@ -640,7 +640,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
}
|
||||
|
||||
#if !AZ_TRAIT_OS_IS_HOST_OS_PLATFORM
|
||||
// Setup the cache and user paths when to platform specific locations when running on non-host platforms
|
||||
// Setup the cache, user, and log paths to platform specific locations when running on non-host platforms
|
||||
path = engineRoot;
|
||||
if (AZStd::optional<AZ::IO::FixedMaxPathString> nonHostCacheRoot = Utils::GetDefaultAppRootPath();
|
||||
nonHostCacheRoot)
|
||||
@@ -656,13 +656,16 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
if (AZStd::optional<AZ::IO::FixedMaxPathString> devWriteStorage = Utils::GetDevWriteStoragePath();
|
||||
devWriteStorage)
|
||||
{
|
||||
registry.Set(FilePathKey_DevWriteStorage, *devWriteStorage);
|
||||
registry.Set(FilePathKey_ProjectUserPath, *devWriteStorage);
|
||||
const AZ::IO::FixedMaxPath devWriteStoragePath(*devWriteStorage);
|
||||
registry.Set(FilePathKey_DevWriteStorage, devWriteStoragePath.LexicallyNormal().Native());
|
||||
registry.Set(FilePathKey_ProjectUserPath, (devWriteStoragePath / "user").LexicallyNormal().Native());
|
||||
registry.Set(FilePathKey_ProjectLogPath, (devWriteStoragePath / "user/log").LexicallyNormal().Native());
|
||||
}
|
||||
else
|
||||
{
|
||||
registry.Set(FilePathKey_DevWriteStorage, path.LexicallyNormal().Native());
|
||||
registry.Set(FilePathKey_ProjectUserPath, (path / "user").LexicallyNormal().Native());
|
||||
registry.Set(FilePathKey_ProjectLogPath, (path / "user/log").LexicallyNormal().Native());
|
||||
}
|
||||
#endif // AZ_TRAIT_OS_IS_HOST_OS_PLATFORM
|
||||
}
|
||||
@@ -1001,7 +1004,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
}
|
||||
AZ::SettingsRegistryInterface::VisitResponse Traverse(
|
||||
AZStd::string_view path, AZStd::string_view valueName, AZ::SettingsRegistryInterface::VisitAction action,
|
||||
AZ::SettingsRegistryInterface::Type type)
|
||||
AZ::SettingsRegistryInterface::Type type) override
|
||||
{
|
||||
// Pass the pointer path to the inclusion filter if available
|
||||
if (m_dumperSettings.m_includeFilter && !m_dumperSettings.m_includeFilter(path))
|
||||
@@ -1055,7 +1058,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
AZ::SettingsRegistryInterface::VisitResponse::Done;
|
||||
}
|
||||
|
||||
void Visit(AZStd::string_view, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type, bool value)
|
||||
void Visit(AZStd::string_view, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type, bool value) override
|
||||
{
|
||||
m_result = m_result && WriteName(valueName) && m_writer.Bool(value);
|
||||
}
|
||||
@@ -1070,12 +1073,12 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
m_result = m_result && WriteName(valueName) && m_writer.Uint64(value);
|
||||
}
|
||||
|
||||
void Visit(AZStd::string_view, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type, double value)
|
||||
void Visit(AZStd::string_view, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type, double value) override
|
||||
{
|
||||
m_result = m_result && WriteName(valueName) && m_writer.Double(value);
|
||||
}
|
||||
|
||||
void Visit(AZStd::string_view, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type, AZStd::string_view value)
|
||||
void Visit(AZStd::string_view, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type, AZStd::string_view value) override
|
||||
{
|
||||
m_result = m_result && WriteName(valueName) && m_writer.String(value.data(), aznumeric_caster(value.size()));
|
||||
}
|
||||
|
||||
@@ -3839,6 +3839,7 @@ namespace AZ
|
||||
{
|
||||
if (instance->GetId() == existingInstance.GetId())
|
||||
{
|
||||
AZ_UNUSED(sliceReference); // Prevent unused warning in release builds
|
||||
AZ_Warning("Slice", false, "Multiple slice instances with the same ID from slice %s were found. The last instance found has been loaded.",
|
||||
sliceReference.GetSliceAsset().GetHint().c_str());
|
||||
return true;
|
||||
|
||||
@@ -187,7 +187,7 @@ void
|
||||
HSM::ClearStateHandler(StateId id)
|
||||
{
|
||||
m_states[id].handler.clear();
|
||||
m_states[id].name = NULL;
|
||||
m_states[id].name = nullptr;
|
||||
m_states[id].superId = InvalidStateId;
|
||||
}
|
||||
|
||||
|
||||
@@ -103,13 +103,10 @@ namespace AZ
|
||||
|
||||
struct State
|
||||
{
|
||||
State()
|
||||
: superId(InvalidStateId)
|
||||
, name(NULL) {}
|
||||
StateHandler handler;
|
||||
StateId superId; ///< State id of the super state, InvalidStateId if this is a top state InvalidStateId.
|
||||
StateId subId; ///< If != InvalidStateId it will enter the sub ID after the state Enter event is called.
|
||||
const char* name;
|
||||
StateId superId = InvalidStateId; ///< State id of the super state, InvalidStateId if this is a top state InvalidStateId.
|
||||
StateId subId = InvalidStateId; ///< If != InvalidStateId it will enter the sub ID after the state Enter event is called.
|
||||
const char* name = nullptr;
|
||||
};
|
||||
AZStd::array<State, MaxNumberOfStates> m_states;
|
||||
};
|
||||
|
||||
@@ -44,7 +44,6 @@ namespace UnitTest
|
||||
MOCK_CONST_METHOD0(GetAppRoot, const char* ());
|
||||
MOCK_CONST_METHOD0(GetEngineRoot, const char* ());
|
||||
MOCK_CONST_METHOD0(GetExecutableFolder, const char* ());
|
||||
MOCK_METHOD0(GetDrillerManager, AZ::Debug::DrillerManager* ());
|
||||
MOCK_CONST_METHOD1(QueryApplicationType, void(AZ::ApplicationTypeQuery&));
|
||||
};
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/UnitTest/UnitTest.h>
|
||||
|
||||
#include <AzCore/Debug/BudgetTracker.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Driller/Driller.h>
|
||||
#include <AzCore/Memory/MemoryDriller.h>
|
||||
@@ -162,7 +163,7 @@ namespace UnitTest
|
||||
struct CreationCounter
|
||||
{
|
||||
AZ_TYPE_INFO(CreationCounter, "{E9E35486-4366-4066-86E5-1A8CEB44198B}");
|
||||
AZ_ALIGN(int test[size / sizeof(int)], alignment);
|
||||
alignas(alignment) int test[size / sizeof(int)];
|
||||
|
||||
static int s_count;
|
||||
static int s_copied;
|
||||
|
||||
@@ -81,8 +81,12 @@ namespace AZ
|
||||
if (settingsFile.IsOpen())
|
||||
{
|
||||
IO::SystemFileStream settingsFileStream(&settingsFile, false);
|
||||
ObjectStream::ClassReadyCB readyCB(AZStd::bind(&UserSettingsProvider::OnSettingLoaded, this, AZStd::placeholders::_1, AZStd::placeholders::_2, AZStd::placeholders::_3));
|
||||
|
||||
ObjectStream::ClassReadyCB readyCB(
|
||||
[this](void* classPtr, const Uuid& classId, const SerializeContext* sc)
|
||||
{
|
||||
OnSettingLoaded(classPtr, classId, sc);
|
||||
});
|
||||
|
||||
// do not try to load assets during User Settings Provider bootup - we are still initializing the application!
|
||||
// in addition, the file may contain settings we don't understand, from other applications - don't error on those.
|
||||
settingsLoaded = ObjectStream::LoadBlocking(&settingsFileStream, *sc, readyCB, ObjectStream::FilterDescriptor(&AZ::Data::AssetFilterNoAssetLoading, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES));
|
||||
@@ -104,7 +108,7 @@ namespace AZ
|
||||
{
|
||||
AZStd::vector<char> saveBuffer;
|
||||
AZ::IO::ByteContainerStream<AZStd::vector<char>> byteStream(&saveBuffer);
|
||||
|
||||
|
||||
ObjectStream* objStream = ObjectStream::Create(&byteStream, *sc, ObjectStream::ST_XML);
|
||||
bool writtenOk = objStream->WriteClass(&m_settings);
|
||||
bool streamOk = objStream->Finalize();
|
||||
|
||||
@@ -93,20 +93,18 @@ set(FILES
|
||||
Debug/AssetTracking.h
|
||||
Debug/AssetTrackingTypesImpl.h
|
||||
Debug/AssetTrackingTypes.h
|
||||
Debug/Budget.h
|
||||
Debug/Budget.cpp
|
||||
Debug/BudgetTracker.h
|
||||
Debug/BudgetTracker.cpp
|
||||
Debug/LocalFileEventLogger.h
|
||||
Debug/LocalFileEventLogger.cpp
|
||||
Debug/FrameProfiler.h
|
||||
Debug/FrameProfilerBus.h
|
||||
Debug/FrameProfilerComponent.cpp
|
||||
Debug/FrameProfilerComponent.h
|
||||
Debug/IEventLogger.h
|
||||
Debug/MemoryProfiler.h
|
||||
Debug/Profiler.cpp
|
||||
Debug/Profiler.inl
|
||||
Debug/Profiler.h
|
||||
Debug/ProfilerBus.h
|
||||
Debug/ProfilerDriller.cpp
|
||||
Debug/ProfilerDriller.h
|
||||
Debug/ProfilerDrillerBus.h
|
||||
Debug/StackTracer.h
|
||||
Debug/EventTrace.h
|
||||
Debug/EventTrace.cpp
|
||||
@@ -531,6 +529,8 @@ set(FILES
|
||||
Serialization/Json/JsonStringConversionUtils.h
|
||||
Serialization/Json/JsonSystemComponent.h
|
||||
Serialization/Json/JsonSystemComponent.cpp
|
||||
Serialization/Json/JsonUtils.h
|
||||
Serialization/Json/JsonUtils.cpp
|
||||
Serialization/Json/MapSerializer.h
|
||||
Serialization/Json/MapSerializer.cpp
|
||||
Serialization/Json/RegistrationContext.h
|
||||
@@ -570,8 +570,6 @@ set(FILES
|
||||
Statistics/StatisticalProfilerProxySystemComponent.cpp
|
||||
Statistics/StatisticalProfilerProxySystemComponent.h
|
||||
Statistics/StatisticsManager.h
|
||||
Statistics/TimeDataStatisticsManager.cpp
|
||||
Statistics/TimeDataStatisticsManager.h
|
||||
StringFunc/StringFunc.cpp
|
||||
StringFunc/StringFunc.h
|
||||
UserSettings/UserSettings.cpp
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user