Merge from main

This commit is contained in:
jonbeer
2021-05-04 09:09:27 -07:00
9337 changed files with 135927 additions and 693498 deletions
@@ -26,4 +26,4 @@ namespace AZ
template <typename T>
using Instance = AZStd::intrusive_ptr<T>;
}
}
}
@@ -60,4 +60,4 @@ namespace AZ
return m_guid != rhs.m_guid || m_subId != rhs.m_subId;
}
}
}
}
@@ -35,4 +35,4 @@ namespace AZStd
base_type::assign(list.begin(), list.end());
}
};
}
}
@@ -158,4 +158,4 @@ namespace AZStd
/// Old elements will be evicted if the capacity is exceeded.
size_t m_capacity = 0;
};
} // namespace AZStd
} // namespace AZStd
@@ -76,4 +76,4 @@ namespace AZStd
base_type::m_container.set_allocator(allocator);
}
};
}
}
@@ -231,4 +231,4 @@ namespace AZStd
protected:
RandomAccessContainer m_container;
};
}
}
@@ -16,4 +16,4 @@ set(FILES
lru_cache.cpp
Main.cpp
vector_set.cpp
)
)
+1 -1
View File
@@ -169,4 +169,4 @@ namespace UnitTest
intintptr_cache.clear();
EXPECT_EQ(p->use_count(), 1);
}
}
}
+1 -1
View File
@@ -282,4 +282,4 @@ namespace UnitTest
VectorSetTester<AZStd::fixed_vector_set<int32_t, 64>> tester;
tester.TestIteratorsConst();
}
}
}
@@ -193,4 +193,4 @@ public class KeyboardHandler
private Activity m_activity;
private InputMethodManager m_inputManager;
private DummyTextView m_textView;
}
}
@@ -88,4 +88,4 @@ public class APKHandler
private static AssetManager s_assetManager = null;
private static boolean s_debug = false;
}
}
@@ -320,4 +320,4 @@ public class ObbDownloaderActivity extends Activity implements IDownloaderClient
private int m_buttonPauseTextId;
private int m_kbPerSecondTextId;
private int m_timeRemainingTextId;
}
}
@@ -37,4 +37,4 @@ public class ObbDownloaderAlarmReceiver extends BroadcastReceiver
e.printStackTrace();
}
}
}
}
@@ -75,4 +75,4 @@ public class ObbDownloaderService extends DownloaderService
private byte[] m_salt = new byte[] { 23, 12, 4, -12, -34, 23,
-120, 122, -23, -104, -2, -4, 12, 3, -21, 123, -11, 4, -11, 32
};
}
}
@@ -84,4 +84,4 @@ public class SimpleObject
// ----
private static final String TAG = "SimpleObject";
}
}
@@ -11,4 +11,4 @@
set(FILES
AzAutoGen.py
)
)
@@ -417,4 +417,4 @@ namespace AZ
return true;
}
}
}
}
@@ -219,4 +219,4 @@ namespace AZ
bool m_isRunning; //!< Internal flag indicating if the application is running, mainly used to determine if we shoudl be blocking on the event pump while paused
};
} // namespace Android
} // namespace AZ
} // namespace AZ
@@ -485,4 +485,4 @@ namespace AZ { namespace Android
} // namespace AZ
#include <AzCore/Android/JNI/Internal/Object_impl.h>
#include <AzCore/Android/JNI/Internal/Object_impl.h>
@@ -1104,8 +1104,11 @@ namespace AZ
// If we either already had valid asset data, or just created it via FindOrCreateAsset, try to queue the load.
if (m_assetData && m_assetData->GetId().IsValid())
{
// Only try to queue if the asset isn't already loading or loaded.
if (m_assetData->GetStatus() == AZ::Data::AssetData::AssetStatus::NotLoaded)
// Try to queue if the asset isn't already loading or loaded.
// Also try to queue if the asset *is* already loading or loaded, but we're the only one with a strong reference
// (i.e. use count == 1), because that means it was in the process of being garbage-collected.
if ((m_assetData->GetStatus() == AZ::Data::AssetData::AssetStatus::NotLoaded) ||
(m_assetData->GetUseCount() == 1))
{
*this = AssetInternal::GetAsset(m_assetData->GetId(), m_assetData->GetType(), loadBehavior, loadParams);
}
@@ -255,7 +255,7 @@ namespace AZ
bool AssetContainer::IsValid() const
{
return (m_containerAssetId.IsValid() && m_initComplete);
return (m_containerAssetId.IsValid() && m_initComplete && m_rootAsset);
}
void AssetContainer::CheckReady()
@@ -341,6 +341,7 @@ namespace AZ
void AssetContainer::OnAssetError(Asset<AssetData> asset)
{
AZ_Warning("AssetContainer", false, "Error loading asset %s", asset->GetId().ToString<AZStd::string>().c_str());
HandleReadyAsset(asset);
}
@@ -366,7 +367,10 @@ namespace AZ
auto remainingPreloadIter = m_preloadList.find(waiterId);
if (remainingPreloadIter == m_preloadList.end())
{
AZ_Warning("AssetContainer", !m_initComplete, "Couldn't find waiting list for %s", waiterId.ToString<AZStd::string>().c_str());
// If we got here without an entry on the preload list, it probably means this asset was triggered to load multiple
// times, some with dependencies and some without. To ensure that we don't disturb the loads that expect the
// dependencies, just silently return and don't treat the asset as finished loading. We'll rely on the other load
// to send an OnAssetReady() whenever its expected dependencies are met.
return;
}
if (!remainingPreloadIter->second.erase(preloadID))
@@ -610,7 +614,12 @@ namespace AZ
}
for(auto& thisList : preloadList)
{
m_preloadList[thisList.first].insert(thisList.second.begin(), thisList.second.end());
// Only save the entry to the final preload list if it has at least one dependent asset still remaining after
// the checks above.
if (!thisList.second.empty())
{
m_preloadList[thisList.first].insert(thisList.second.begin(), thisList.second.end());
}
}
}
}
@@ -208,6 +208,7 @@ namespace AZ::Data
void AssetDataStream::Close()
{
AZ_Assert(m_isOpen, "Attempting to close a stream that hasn't been opened.");
AZ_Assert(m_curReadRequest == nullptr, "Attempting to close a stream with a read request in flight.");
// Destroy the asset buffer and unlock the allocator, so the allocator itself knows that it is no longer needed.
if (m_buffer != m_preloadedData.data())
@@ -222,6 +223,16 @@ namespace AZ::Data
AZ_PROFILE_INTERVAL_END(AZ::Debug::ProfileCategory::AzCore, this);
}
void AssetDataStream::RequestCancel()
{
AZStd::scoped_lock<AZStd::mutex> lock(m_readRequestMutex);
if (m_curReadRequest)
{
auto streamer = Interface<IO::IStreamer>::Get();
m_curReadRequest = streamer->Cancel(m_curReadRequest);
}
}
void AssetDataStream::Seek(AZ::IO::OffsetType bytes, AZ::IO::GenericStream::SeekMode mode)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
@@ -82,6 +82,10 @@ namespace AZ::Data
//! Gets the size of data loaded (so far).
size_t GetLoadedSize() const { return m_loadedSize; }
//! Request a cancellation of any current IO streamer requests.
//! Note: This is asynchronous and not guaranteed to cancel if the request is already in-process.
void RequestCancel();
private:
//! Perform any operations needed by all variants of Open()
void OpenInternal(size_t assetSize, const char* streamName);
@@ -28,6 +28,8 @@ namespace AZ::Data::AssetInternal
class WeakAsset
{
public:
static constexpr bool EnableAssetCancellation = false;
WeakAsset() = default;
WeakAsset(AssetData* assetData, AssetLoadBehavior assetReferenceLoadBehavior);
@@ -111,7 +113,14 @@ namespace AZ::Data::AssetInternal
// - If the left and right sides are the same, clearing the right side's reference means one less reference will exist
if (m_assetData)
{
m_assetData->ReleaseWeak();
if constexpr (EnableAssetCancellation)
{
m_assetData->ReleaseWeak();
}
else
{
m_assetData->Release();
}
}
m_assetData = AZStd::move(rhs.m_assetData);
rhs.m_assetData = nullptr;
@@ -141,13 +150,27 @@ namespace AZ::Data::AssetInternal
if (assetData)
{
assetData->AcquireWeak();
if constexpr (EnableAssetCancellation)
{
assetData->AcquireWeak();
}
else
{
assetData->Acquire();
}
m_assetId = assetData->GetId();
}
if (m_assetData)
{
m_assetData->ReleaseWeak();
if constexpr (EnableAssetCancellation)
{
m_assetData->ReleaseWeak();
}
else
{
m_assetData->Release();
}
}
m_assetData = assetData;
@@ -1454,32 +1454,48 @@ namespace AZ
//=========================================================================
void AssetManager::ReloadAssetFromData(const Asset<AssetData>& asset)
{
AZ_Assert(asset.Get(), "Asset data for reload is missing.");
AZStd::scoped_lock<AZStd::recursive_mutex> assetLock(m_assetMutex);
AZ_Assert(m_assets.find(asset.GetId()) != m_assets.end(), "Unable to reload asset %s because its not in the AssetManager's asset list.", asset.ToString<AZStd::string>().c_str());
AZ_Assert(m_assets.find(asset.GetId()) == m_assets.end() || asset->RTTI_GetType() == m_assets.find(asset.GetId())->second->RTTI_GetType(),
"New and old data types are mismatched!");
bool shouldAssignAssetData = false;
auto found = m_assets.find(asset.GetId());
if ((found == m_assets.end()) || (asset->RTTI_GetType() != found->second->RTTI_GetType()))
{
return; // this will just lead to crashes down the line and the above asserts cover this.
}
AZ_Assert(asset.Get(), "Asset data for reload is missing.");
AZStd::scoped_lock<AZStd::recursive_mutex> assetLock(m_assetMutex);
AZ_Assert(
m_assets.find(asset.GetId()) != m_assets.end(),
"Unable to reload asset %s because it's not in the AssetManager's asset list.", asset.ToString<AZStd::string>().c_str());
AZ_Assert(
m_assets.find(asset.GetId()) == m_assets.end() ||
asset->RTTI_GetType() == m_assets.find(asset.GetId())->second->RTTI_GetType(),
"New and old data types are mismatched!");
AssetData* newData = asset.Get();
if (found->second != newData)
{
// Notify users that we are about to change asset
AssetBus::Event(asset.GetId(), &AssetBus::Events::OnAssetPreReload, asset);
// Resolve the asset handler and account for the new asset instance.
auto found = m_assets.find(asset.GetId());
if ((found == m_assets.end()) || (asset->RTTI_GetType() != found->second->RTTI_GetType()))
{
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());
return; // this will just lead to crashes down the line and the above asserts cover this.
}
AssetData* newData = asset.Get();
if (found->second != newData)
{
// Notify users that we are about to change asset
AssetBus::Event(asset.GetId(), &AssetBus::Events::OnAssetPreReload, asset);
// Resolve the asset handler and account for the new asset instance.
{
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());
}
shouldAssignAssetData = true;
}
}
// We specifically perform this outside of the m_assetMutex lock so that the lock isn't held at the point that
// OnAssetReload is triggered inside of AssignAssetData. Otherwise, we open up a high potential for deadlocks.
if (shouldAssignAssetData)
{
AssignAssetData(asset);
}
}
@@ -2144,7 +2160,7 @@ namespace AZ
if (curIter != m_assetContainers.end())
{
auto newRef = curIter->second.lock();
if (newRef)
if (newRef && newRef->IsValid())
{
return newRef;
}
@@ -19,7 +19,6 @@
#include <AzCore/Jobs/JobManagerComponent.h>
#include <AzCore/Serialization/Json/JsonSystemComponent.h>
#include <AzCore/Memory/MemoryComponent.h>
#include <AzCore/NativeUI/NativeUISystemComponent.h>
#include <AzCore/Script/ScriptSystemComponent.h>
#include <AzCore/Slice/SliceComponent.h>
#include <AzCore/Slice/SliceSystemComponent.h>
@@ -43,7 +42,6 @@ namespace AZ
AssetManagerComponent::CreateDescriptor(),
UserSettingsComponent::CreateDescriptor(),
Debug::FrameProfilerComponent::CreateDescriptor(),
NativeUI::NativeUISystemComponent::CreateDescriptor(),
SliceComponent::CreateDescriptor(),
SliceSystemComponent::CreateDescriptor(),
SliceMetadataInfoComponent::CreateDescriptor(),
@@ -28,6 +28,8 @@
#include <AzCore/Memory/AllocatorManager.h>
#include <AzCore/Memory/MallocSchema.h>
#include <AzCore/NativeUI/NativeUIRequests.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/ObjectStream.h>
#include <AzCore/Serialization/Utils.h>
@@ -341,6 +343,16 @@ namespace AZ
;
}
}
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->EBus<ComponentApplicationBus>("ComponentApplicationBus")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Category, "Components")
->Event("GetEntityName", &ComponentApplicationBus::Events::GetEntityName)
->Event("SetEntityName", &ComponentApplicationBus::Events::SetEntityName);
}
}
//=========================================================================
@@ -414,7 +426,7 @@ namespace AZ
// Now that the Allocators are initialized, the Command Line parameters can be parsed
m_commandLine.Parse(m_argC, m_argV);
ParseCommandLine(m_commandLine);
SettingsRegistryMergeUtils::ParseCommandLine(m_commandLine);
// Create the settings registry and register it with the AZ interface system
// This is done after the AppRoot has been calculated so that the Bootstrap.cfg
@@ -517,10 +529,42 @@ namespace AZ
DestroyAllocator();
}
void ReportBadEngineRoot()
{
AZStd::string errorMessage = {"Unable to determine a valid path to the engine.\n"
"Check parameters such as --project-path and --engine-path and make sure they are valid.\n"};
if (auto registry = AZ::SettingsRegistry::Get(); registry != nullptr)
{
AZ::SettingsRegistryInterface::FixedValueString filePathErrorStr;
if (registry->Get(filePathErrorStr, AZ::SettingsRegistryMergeUtils::FilePathKey_ErrorText); !filePathErrorStr.empty())
{
errorMessage += "Additional Info:\n";
errorMessage += filePathErrorStr.c_str();
}
}
if (auto nativeUI = AZ::Interface<AZ::NativeUI::NativeUIRequests>::Get(); nativeUI != nullptr)
{
nativeUI->DisplayOkDialog("O3DE Fatal Error", errorMessage.c_str(), false);
}
else
{
AZ_Error("ComponentApplication", false, "O3DE Fatal Error: %s\n", errorMessage.c_str());
}
}
Entity* ComponentApplication::Create(const Descriptor& descriptor, const StartupParameters& startupParameters)
{
AZ_Assert(!m_isStarted, "Component application already started!");
if (m_engineRoot.empty())
{
ReportBadEngineRoot();
return nullptr;
}
m_startupParameters = startupParameters;
m_descriptor = descriptor;
@@ -861,46 +905,6 @@ namespace AZ
}
}
void ComponentApplication::ParseCommandLine(const AZ::CommandLine& commandLine)
{
struct OptionKeyToRegsetKey
{
AZStd::string_view m_optionKey;
AZStd::string m_regsetKey;
};
// Provide overrides for the engine root, the project root and the project cache root
AZStd::array commandOptions = {
OptionKeyToRegsetKey{ "engine-path", AZStd::string::format("%s/engine_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) },
OptionKeyToRegsetKey{ "project-path", AZStd::string::format("%s/project_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) },
OptionKeyToRegsetKey{ "project-cache-path", AZStd::string::format("%s/project_cache_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) }
};
AZStd::fixed_vector<AZStd::string, commandOptions.size()> overrideArgs;
for (auto&& [optionKey, regsetKey] : commandOptions)
{
if (size_t optionCount = commandLine.GetNumSwitchValues(optionKey); optionCount > 0)
{
// Use the last supplied command option value to override previous values
auto overrideArg = AZStd::string::format(R"(--regset="%s=%s")", regsetKey.c_str(),
commandLine.GetSwitchValue(optionKey, optionCount - 1).c_str());
overrideArgs.emplace_back(AZStd::move(overrideArg));
}
}
if (!overrideArgs.empty())
{
// Dump the input command line, add the additional option overrides
// and Parse the new command line into the Component Application command line
AZ::CommandLine::ParamContainer commandLineArgs;
commandLine.Dump(commandLineArgs);
commandLineArgs.insert(commandLineArgs.end(), AZStd::make_move_iterator(overrideArgs.begin()),
AZStd::make_move_iterator(overrideArgs.end()));
m_commandLine.Parse(commandLineArgs);
}
}
void ComponentApplication::MergeSettingsToRegistry(SettingsRegistryInterface& registry)
{
SettingsRegistryInterface::Specializations specializations;
@@ -1050,6 +1054,20 @@ namespace AZ
return AZStd::string();
}
//=========================================================================
// SetEntityName
//=========================================================================
bool ComponentApplication::SetEntityName(const EntityId& id, const AZStd::string_view name)
{
Entity* entity = FindEntity(id);
if (entity)
{
entity->SetName(name);
return true;
}
return false;
}
//=========================================================================
// EnumerateEntities
//=========================================================================
@@ -209,6 +209,7 @@ namespace AZ
bool DeleteEntity(const EntityId& id) override;
Entity* FindEntity(const EntityId& id) override;
AZStd::string GetEntityName(const EntityId& id) override;
bool SetEntityName(const EntityId& id, const AZStd::string_view name) override;
void EnumerateEntities(const ComponentApplicationRequests::EntityCallback& callback) override;
ComponentApplication* GetApplication() override { return this; }
/// Returns the serialize context that has been registered with the app, if there is one.
@@ -327,9 +328,6 @@ namespace AZ
/// Create the drillers
void CreateDrillers();
/// Parse ComponentApplication specific command line arguments
void ParseCommandLine(const AZ::CommandLine& commandLine);
virtual void MergeSettingsToRegistry(SettingsRegistryInterface& registry);
//! Sets the specializations that will be used when loading the Settings Registry. Extend this in derived
@@ -130,7 +130,13 @@ namespace AZ
//! @param entity A reference to the entity whose name you are seeking.
//! @return The name of the entity with the specified entity ID.
//! If no entity is found for the specified ID, it returns an empty string.
virtual AZStd::string GetEntityName(const EntityId& id) { (void)id; return AZStd::string(); };
virtual AZStd::string GetEntityName(const EntityId& id) { (void)id; return AZStd::string(); }
//! Sets the name of the entity that has the specified entity ID.
//! Entity names are not enforced to be unique.
//! @param entityId A reference to the entity whose name you want to change.
//! @return True if the name was changed successfully, false if it wasn't.
virtual bool SetEntityName([[maybe_unused]] const EntityId& id, [[maybe_unused]] const AZStd::string_view name) { return false; }
//! The type that AZ::ComponentApplicationRequests::EnumerateEntities uses to
//! pass entity callbacks to the application for enumeration.
@@ -87,4 +87,4 @@ namespace AZ
size_t m_nextBlockSize;
unsigned int m_compressedBufferIndex;
};
};
};
@@ -63,13 +63,13 @@ namespace AZ
static AssetTrackingImpl* GetSharedInstance();
static ThreadData& GetSharedThreadData();
using MasterAssets = AZStd::unordered_map<AssetTrackingId, AssetMasterInfo, AZStd::hash<AssetTrackingId>, AZStd::equal_to<AssetTrackingId>, AZStdAssetTrackingAllocator>;
using PrimaryAssets = AZStd::unordered_map<AssetTrackingId, AssetPrimaryInfo, AZStd::hash<AssetTrackingId>, AZStd::equal_to<AssetTrackingId>, AZStdAssetTrackingAllocator>;
using ThreadData = ThreadData;
using mutex_type = AZStd::mutex;
using lock_type = AZStd::lock_guard<mutex_type>;
mutex_type m_mutex;
MasterAssets m_masterAssets;
PrimaryAssets m_primaryAssets;
AssetTreeNodeBase* m_assetRoot = nullptr;
AssetAllocationTableBase* m_allocationTable = nullptr;
bool m_performingAnalysis = false;
@@ -118,7 +118,7 @@ namespace AZ
auto& threadData = GetSharedThreadData();
AssetTreeNodeBase* parentAsset = threadData.m_currentAssetStack.empty() ? nullptr : threadData.m_currentAssetStack.back();
AssetTreeNodeBase* childAsset;
AssetMasterInfo* assetMasterInfo;
AssetPrimaryInfo* assetPrimaryInfo;
if (!parentAsset)
{
@@ -128,22 +128,22 @@ namespace AZ
{
lock_type lock(m_mutex);
// Locate or create the master record for this asset
auto masterItr = m_masterAssets.find(assetId);
// Locate or create the primary record for this asset
auto primaryItr = m_primaryAssets.find(assetId);
if (masterItr != m_masterAssets.end())
if (primaryItr != m_primaryAssets.end())
{
assetMasterInfo = &masterItr->second;
assetPrimaryInfo = &primaryItr->second;
}
else
{
auto insertResult = m_masterAssets.emplace(assetId, AssetMasterInfo());
assetMasterInfo = &insertResult.first->second;
assetMasterInfo->m_id = &insertResult.first->first;
auto insertResult = m_primaryAssets.emplace(assetId, AssetPrimaryInfo());
assetPrimaryInfo = &insertResult.first->second;
assetPrimaryInfo->m_id = &insertResult.first->first;
}
// Add this asset to the stack for this thread's context
childAsset = parentAsset->FindOrAddChild(assetId, assetMasterInfo);
childAsset = parentAsset->FindOrAddChild(assetId, assetPrimaryInfo);
}
threadData.m_currentAssetStack.push_back(childAsset);
@@ -304,7 +304,7 @@ namespace AZ
char* pos = buffer;
for (auto itr = assetStack.rbegin(); itr != assetStack.rend(); ++itr)
{
pos += azsnprintf(pos, BUFFER_SIZE - (pos - buffer), "%s\n", (*itr)->GetAssetMasterInfo()->m_id->m_id.c_str());
pos += azsnprintf(pos, BUFFER_SIZE - (pos - buffer), "%s\n", (*itr)->GetAssetPrimaryInfo()->m_id->m_id.c_str());
if (pos >= buffer + BUFFER_SIZE)
{
@@ -79,9 +79,9 @@ namespace AZ
AssetTrackingString m_id;
};
// Master information about an asset.
// Primary information about an asset.
// Currently just contains the ID of the asset, but in the future may carry additional information about that asset (such as where in code it was initialized).
struct AssetMasterInfo
struct AssetPrimaryInfo
{
const AssetTrackingId* m_id;
};
@@ -90,8 +90,8 @@ namespace AZ
class AssetTreeNodeBase
{
public:
virtual const AssetMasterInfo* GetAssetMasterInfo() const = 0;
virtual AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetMasterInfo* info) = 0;
virtual const AssetPrimaryInfo* GetAssetPrimaryInfo() const = 0;
virtual AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetPrimaryInfo* info) = 0;
};
// Base class for an asset tree. Implemented by the template AssetTree<>.
@@ -29,18 +29,18 @@ namespace AZ
class AssetTreeNode : public AssetTreeNodeBase
{
public:
AssetTreeNode(const AssetMasterInfo* masterInfo = nullptr, AssetTreeNode* parent = nullptr) :
m_masterInfo(masterInfo),
AssetTreeNode(const AssetPrimaryInfo* primaryInfo = nullptr, AssetTreeNode* parent = nullptr) :
m_primaryinfo(primaryInfo),
m_parent(parent)
{
}
const AssetMasterInfo* GetAssetMasterInfo() const override
const AssetPrimaryInfo* GetAssetPrimaryInfo() const override
{
return m_masterInfo;
return m_primaryinfo;
}
AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetMasterInfo* info) override
AssetTreeNodeBase* FindOrAddChild(const AssetTrackingId& id, const AssetPrimaryInfo* info) override
{
AssetTreeNodeBase* result = nullptr;
auto childItr = m_children.find(id);
@@ -61,7 +61,7 @@ namespace AZ
using AssetMap = AssetTrackingMap<AssetTrackingId, AssetTreeNode>;
const AssetMasterInfo* m_masterInfo;
const AssetPrimaryInfo* m_primaryinfo;
AssetTreeNode* m_parent;
AssetMap m_children;
AssetDataT m_data;
@@ -82,4 +82,4 @@ namespace AZ
#define AZ_TRACE_INSTANT_THREAD_CATEGORY(name, category) \
EBUS_QUEUE_EVENT(AZ::Debug::EventTraceDrillerBus, RecordInstantThread, name, category, AZStd::this_thread::get_id(), AZStd::GetTimeNowMicroSecond())
#define AZ_TRACE_INSTANT_THREAD(name) AZ_TRACE_INSTANT_THREAD_CATEGORY(name, "")
#define AZ_TRACE_INSTANT_THREAD(name) AZ_TRACE_INSTANT_THREAD_CATEGORY(name, "")
@@ -64,4 +64,4 @@ namespace AZ
} // namespace AZ
#endif // AZCORE_FRAME_PROFILER_H
#pragma once
#pragma once
@@ -39,4 +39,4 @@ namespace AZ
} // namespace AZ
#endif // AZCORE_FRAME_PROFILER_BUS_H
#pragma once
#pragma once
@@ -46,4 +46,4 @@ namespace AZ
}
#endif // AZCORE_PROFILER_DRILLER_BUS_H
#pragma once
#pragma once
+9 -2
View File
@@ -70,6 +70,7 @@ namespace AZ
static const char* logVerbosityUID = "sys_LogLevel";
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;
@@ -289,8 +290,8 @@ namespace AZ
}
#if AZ_ENABLE_TRACE_ASSERTS
//display native UI dialogs at verbosity level 2 or higher
if (currentLevel >= assertLevel_nativeUI)
//display native UI dialogs at verbosity level 2
if (currentLevel == assertLevel_nativeUI)
{
AZ::NativeUI::AssertAction buttonResult;
EBUS_EVENT_RESULT(buttonResult, AZ::NativeUI::NativeUIRequestBus, DisplayAssertDialog, dialogBoxText);
@@ -314,7 +315,13 @@ namespace AZ
break;
}
}
else
#endif //AZ_ENABLE_TRACE_ASSERTS
// Crash the application directly at assert level 3
if (currentLevel >= assertLevel_crash)
{
AZ_Crash();
}
}
g_alreadyHandlingAssertOrFatal = false;
}
@@ -194,4 +194,4 @@ namespace AZ
}
};
}
}
}
@@ -112,4 +112,4 @@ namespace AZ
return m_offsetEnd;
}
} // namespace IO
} // namesapce AZ
} // namesapce AZ
@@ -71,4 +71,4 @@ namespace AZ
u64 m_offsetEnd : 63;
};
} // namespace IO
} // namesapce AZ
} // namesapce AZ
+1 -1
View File
@@ -24,4 +24,4 @@
#if AZ_TRAIT_JSON_CLANG_IGNORE_UNKNOWN_WARNING && defined(AZ_COMPILER_CLANG)
#pragma clang diagnostic pop
#endif
#endif
@@ -46,4 +46,4 @@ namespace AZ
}
#endif
#pragma once
#pragma once
@@ -68,4 +68,4 @@ namespace AZ
}
#endif
#pragma once
#pragma once
@@ -70,4 +70,4 @@ namespace AZ
}
#endif
#pragma once
#pragma once
+1 -1
View File
@@ -36,4 +36,4 @@ namespace AZ
}
#endif
#pragma once
#pragma once
@@ -96,4 +96,4 @@ namespace AZ
}
#endif
#pragma once
#pragma once
@@ -135,4 +135,4 @@ namespace AZ
}
#endif
#pragma once
#pragma once
+29 -2
View File
@@ -146,8 +146,8 @@ namespace AZ
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Method("GetTranslated", &Aabb::GetTranslated)
->Method("GetSurfaceArea", &Aabb::GetSurfaceArea)
->Method("GetTransformedObb", &Aabb::GetTransformedObb)
->Method("GetTransformedAabb", &Aabb::GetTransformedAabb)
->Method("GetTransformedObb", static_cast<Obb(Aabb::*)(const Transform&) const>(&Aabb::GetTransformedObb))
->Method("GetTransformedAabb", static_cast<Aabb(Aabb::*)(const Transform&) const>(&Aabb::GetTransformedAabb))
->Method("ApplyTransform", &Aabb::ApplyTransform)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Method("Clone", [](const Aabb& rhs) -> Aabb { return rhs; })
@@ -195,6 +195,20 @@ namespace AZ
}
Obb Aabb::GetTransformedObb(const Matrix3x4& matrix3x4) const
{
Matrix3x4 matrixNoScale = matrix3x4;
const AZ::Vector3 scale = matrixNoScale.ExtractScale();
const AZ::Quaternion rotation = AZ::Quaternion::CreateFromMatrix3x4(matrixNoScale);
return Obb::CreateFromPositionRotationAndHalfLengths(
matrix3x4 * GetCenter(),
rotation,
0.5f * scale * GetExtents()
);
}
void Aabb::ApplyTransform(const Transform& transform)
{
Vector3 a, b, axisCoeffs;
@@ -224,4 +238,17 @@ namespace AZ
m_min = newMin;
m_max = newMax;
}
void Aabb::ApplyMatrix3x4(const Matrix3x4& matrix3x4)
{
const AZ::Vector3 extents = GetExtents();
const AZ::Vector3 center = matrix3x4 * GetCenter();
AZ::Vector3 newHalfExtents(
0.5f * matrix3x4.GetRowAsVector3(0).GetAbs().Dot(extents),
0.5f * matrix3x4.GetRowAsVector3(1).GetAbs().Dot(extents),
0.5f * matrix3x4.GetRowAsVector3(2).GetAbs().Dot(extents));
m_min = center - newHalfExtents;
m_max = center + newHalfExtents;
}
}
+12 -2
View File
@@ -129,11 +129,21 @@ namespace AZ
void ApplyTransform(const Transform& transform);
void ApplyMatrix3x4(const Matrix3x4& matrix3x4);
void MultiplyByScale(const Vector3& scale);
//! Transforms an Aabb and returns the resulting Obb.
class Obb GetTransformedObb(const Transform& transform) const;
[[nodiscard]] Obb GetTransformedObb(const Transform& transform) const;
//! Transforms an Aabb and returns the resulting Obb.
[[nodiscard]] Obb GetTransformedObb(const Matrix3x4& matrix3x4) const;
//! Returns a new AABB containing the transformed AABB.
Aabb GetTransformedAabb(const Transform& transform) const;
[[nodiscard]] Aabb GetTransformedAabb(const Transform& transform) const;
//! Returns a new AABB containing the transformed AABB.
[[nodiscard]] Aabb GetTransformedAabb(const Matrix3x4& matrix3x4) const;
//! Checks if this aabb is equal to another within a floating point tolerance.
bool IsClose(const Aabb& rhs, float tolerance = Constants::Tolerance) const;
@@ -292,6 +292,14 @@ namespace AZ
}
AZ_MATH_INLINE void Aabb::MultiplyByScale(const Vector3& scale)
{
m_min *= scale;
m_max *= scale;
AZ_MATH_ASSERT(IsValid(), "Min must be less than Max");
}
AZ_MATH_INLINE Aabb Aabb::GetTransformedAabb(const Transform& transform) const
{
Aabb aabb = Aabb::CreateFromMinMax(m_min, m_max);
@@ -300,6 +308,14 @@ namespace AZ
}
AZ_MATH_INLINE Aabb Aabb::GetTransformedAabb(const Matrix3x4& matrix3x4) const
{
Aabb aabb = Aabb::CreateFromMinMax(m_min, m_max);
aabb.ApplyMatrix3x4(matrix3x4);
return aabb;
}
AZ_MATH_INLINE bool Aabb::IsClose(const Aabb& rhs, float tolerance) const
{
return m_min.IsClose(rhs.m_min, tolerance) && m_max.IsClose(rhs.m_max, tolerance);
@@ -296,4 +296,4 @@ namespace AZ
m_updateCallback(index);
}
}
}
}
@@ -164,4 +164,4 @@ namespace AZ
return GetTargetValue();
}
};
}
}
@@ -67,4 +67,4 @@ namespace AZ
//! Transforms a position by a matrix. This function can be used with any generic cases which include projection matrices.
Vector3 MatrixTransformPosition(const Matrix4x4& matrix, const Vector3& inPosition);
} // namespace AZ
} // namespace AZ
@@ -258,7 +258,8 @@ namespace AZ
Method("CreateFromMatrix3x3", &Quaternion::CreateFromMatrix3x3)->
Method("CreateFromMatrix4x4", &Quaternion::CreateFromMatrix4x4)->
Method("CreateFromAxisAngle", &Quaternion::CreateFromAxisAngle)->
Method("CreateShortestArc", &Quaternion::CreateShortestArc)
Method("CreateShortestArc", &Quaternion::CreateShortestArc)->
Method("CreateFromEulerAnglesDegrees", &Quaternion::CreateFromEulerAnglesDegrees)
;
}
}
@@ -250,6 +250,7 @@ namespace AZ
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
Attribute(Script::Attributes::Storage, Script::Attributes::StorageType::Value)->
Attribute(Script::Attributes::GenericConstructorOverride, &Internal::TransformDefaultConstructor)->
Constructor<const Vector3&, const Quaternion&, const Vector3&>()->
Method("GetBasis", &Transform::GetBasis)->
Method("GetBasisX", &Transform::GetBasisX)->
Method("GetBasisY", &Transform::GetBasisY)->
@@ -110,4 +110,4 @@ namespace AZ
} // namespace AZ
#include <AzCore/Math/Internal/VertexContainer.inl>
#include <AzCore/Math/Internal/VertexContainer.inl>
@@ -172,4 +172,4 @@ namespace AZ
template<>
inline AZ::Vector3 AdaptVertexOut<AZ::Vector2>(const AZ::Vector2& vector) { return Vector2ToVector3(vector); }
} // namespace AZ
} // namespace AZ
@@ -31,4 +31,4 @@ namespace AZ
return modulePath;
}
} // namespace Internal
} // namespace AZ
} // namespace AZ
@@ -15,45 +15,49 @@
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/string/string.h>
namespace AZ
namespace AZ::NativeUI
{
namespace NativeUI
enum AssertAction
{
enum AssertAction
{
IGNORE_ASSERT = 0,
IGNORE_ALL_ASSERTS,
BREAK,
NONE,
};
IGNORE_ASSERT = 0,
IGNORE_ALL_ASSERTS,
BREAK,
NONE,
};
class NativeUIRequests
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
using MutexType = AZStd::recursive_mutex;
class NativeUIRequests
{
public:
AZ_RTTI(NativeUIRequests, "{48361EE6-C1E7-4965-A13A-7425B2691817}");
virtual ~NativeUIRequests() = default;
// Waits for user to select an option before execution continues
// Returns the option string selected by the user
virtual AZStd::string DisplayBlockingDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, const AZStd::vector<AZStd::string>& /*options*/) const { return ""; };
// Waits for user to select an option before execution continues
// Returns the option string selected by the user
virtual AZStd::string DisplayBlockingDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, const AZStd::vector<AZStd::string>& /*options*/) const { return ""; };
// Waits for user to select an option ('Ok' or optionally 'Cancel') before execution continues
// Returns the option string selected by the user
virtual AZStd::string DisplayOkDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, bool /*showCancel*/) const { return ""; };
// Waits for user to select an option ('Ok' or optionally 'Cancel') before execution continues
// Returns the option string selected by the user
virtual AZStd::string DisplayOkDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, bool /*showCancel*/) const { return ""; };
// Waits for user to select an option ('Yes', 'No' or optionally 'Cancel') before execution continues
// Returns the option string selected by the user
virtual AZStd::string DisplayYesNoDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, bool /*showCancel*/) const { return ""; };
// Waits for user to select an option ('Yes', 'No' or optionally 'Cancel') before execution continues
// Returns the option string selected by the user
virtual AZStd::string DisplayYesNoDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, bool /*showCancel*/) const { return ""; };
// Displays an assert dialog box
// Returns the action selected by the user
virtual AssertAction DisplayAssertDialog(const AZStd::string& /*message*/) const { return AssertAction::NONE; };
};
// Displays an assert dialog box
// Returns the action selected by the user
virtual AssertAction DisplayAssertDialog(const AZStd::string& /*message*/) const { return AssertAction::NONE; };
};
using NativeUIRequestBus = AZ::EBus<NativeUIRequests>;
}
}
class NativeUIEBusTraits
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
using MutexType = AZStd::recursive_mutex;
};
using NativeUIRequestBus = AZ::EBus<NativeUIRequests, NativeUIEBusTraits>;
} // namespace AZ::NativeUI
@@ -15,50 +15,19 @@
#include <AzCore/NativeUI/NativeUISystemComponent.h>
namespace AZ
namespace AZ::NativeUI
{
using namespace AZ::NativeUI;
void NativeUISystemComponent::Reflect(AZ::ReflectContext* context)
NativeUISystem::NativeUISystem()
{
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
serialize->Class<NativeUISystemComponent, AZ::Component>()
->Version(0)
;
if (AZ::EditContext* ec = serialize->GetEditContext())
{
ec->Class<NativeUISystemComponent>("NativeUI", "Adds basic support for native (platform specific) UI dialog boxes")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
;
}
}
NativeUIRequestBus::Handler::BusConnect();
}
void NativeUISystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
NativeUISystem::~NativeUISystem()
{
provided.push_back(AZ_CRC("NativeUIService", 0x8ec25f87));
NativeUIRequestBus::Handler::BusDisconnect();
}
void NativeUISystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("NativeUIService", 0x8ec25f87));
}
void NativeUISystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
(void)required;
}
void NativeUISystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
(void)dependent;
}
AssertAction NativeUISystemComponent::DisplayAssertDialog(const AZStd::string& message) const
AssertAction NativeUISystem::DisplayAssertDialog(const AZStd::string& message) const
{
static const char* buttonNames[3] = { "Ignore", "Ignore All", "Break" };
AZStd::vector<AZStd::string> options;
@@ -80,7 +49,7 @@ namespace AZ
return AssertAction::NONE;
}
AZStd::string NativeUISystemComponent::DisplayOkDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const
AZStd::string NativeUISystem::DisplayOkDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const
{
AZStd::vector<AZStd::string> options;
@@ -93,7 +62,7 @@ namespace AZ
return DisplayBlockingDialog(title, message, options);
}
AZStd::string NativeUISystemComponent::DisplayYesNoDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const
AZStd::string NativeUISystem::DisplayYesNoDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const
{
AZStd::vector<AZStd::string> options;
@@ -106,18 +75,4 @@ namespace AZ
return DisplayBlockingDialog(title, message, options);
}
void NativeUISystemComponent::Init()
{
}
void NativeUISystemComponent::Activate()
{
NativeUIRequestBus::Handler::BusConnect();
}
void NativeUISystemComponent::Deactivate()
{
NativeUIRequestBus::Handler::BusDisconnect();
}
}
} // namespace AZ::NativeUI
@@ -15,40 +15,24 @@
#include <AzCore/Component/Component.h>
#include <AzCore/NativeUI/NativeUIRequests.h>
namespace AZ
namespace AZ::NativeUI
{
namespace NativeUI
class NativeUISystem
: public NativeUIRequestBus::Handler
{
class NativeUISystemComponent
: public AZ::Component
, public NativeUIRequestBus::Handler
{
public:
AZ_COMPONENT(NativeUISystemComponent, "{E996C058-4AFE-4C8C-816F-98D864D8576D}");
public:
AZ_RTTI(NativeUISystem, "{FF534B2C-11BE-4DEA-A5B7-A4FA96FE1EDE}", NativeUIRequests);
AZ_CLASS_ALLOCATOR(NativeUISystem, AZ::OSAllocator, 0);
static void Reflect(AZ::ReflectContext* context);
NativeUISystem();
~NativeUISystem() override;
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
////////////////////////////////////////////////////////////////////////
// NativeUIRequestBus interface implementation
AZStd::string DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const override;
AZStd::string DisplayOkDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const override;
AZStd::string DisplayYesNoDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const override;
AssertAction DisplayAssertDialog(const AZStd::string& message) const override;
////////////////////////////////////////////////////////////////////////
protected:
////////////////////////////////////////////////////////////////////////
// AZ::Component interface implementation
void Init() override;
void Activate() override;
void Deactivate() override;
////////////////////////////////////////////////////////////////////////
};
}
}
////////////////////////////////////////////////////////////////////////
// NativeUIRequestBus interface implementation
AZStd::string DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const override;
AZStd::string DisplayOkDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const override;
AZStd::string DisplayYesNoDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const override;
AssertAction DisplayAssertDialog(const AZStd::string& message) const override;
////////////////////////////////////////////////////////////////////////
};
} // namespace AZ::NativeUI
@@ -113,4 +113,4 @@
#define AZCG_Unpack_98(x, ...) AZCG_Unpack_1(x) AZCG_Unpack_97(__VA_ARGS__)
#define AZCG_Unpack_99(x, ...) AZCG_Unpack_1(x) AZCG_Unpack_98(__VA_ARGS__)
#define AZCG_Unpack(...) AZ_MACRO_SPECIALIZE(AZCG_Unpack_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__))
#define AZCG_Paste(x) x
#define AZCG_Paste(x) x
@@ -26,4 +26,4 @@ namespace AZ
void Activate() override { }
void Deactivate() override { }
};
}
}
@@ -79,4 +79,4 @@ namespace AZ
AZ_TYPE_INFO_SPECIALIZE(Script::Attributes::OperatorType, "{26B98C03-7E07-4E3E-9E31-03DA2168E896}");
AZ_TYPE_INFO_SPECIALIZE(Script::Attributes::StorageType, "{57FED71F-B590-4002-9599-A48CB50B0F8E}");
}
}
@@ -32,4 +32,4 @@ namespace AZ
};
typedef AZ::EBus<BehaviorObjectSignalsInterface> BehaviorObjectSignals;
}
}
@@ -138,4 +138,4 @@ namespace AZ
m_currentlyProcessingTypeIds.pop_back();
}
}
}
}
@@ -208,4 +208,4 @@ namespace AZ
}
}
}
}
}
@@ -1411,4 +1411,4 @@ namespace AZ
m_value = entityProperty->m_value;
}
}
}
}
@@ -38,4 +38,4 @@ namespace AZ
};
typedef AZ::EBus<ScriptPropertyWatcherInterface> ScriptPropertyWatcherBus;
}
}
@@ -699,6 +699,10 @@ Data::AssetHandler::LoadResult ScriptSystemComponent::LoadAssetData(
script->m_scriptBuffer.resize(scriptDataLength);
stream->Read(scriptDataLength, script->m_scriptBuffer.data());
// Clear cached references in the event of a successful load. This function has to be queued on
// AssetBus where NotifyAssetReloaded is also queued, to ensure its execution before NotifyAssetReloaded
Data::AssetBus::QueueFunction(&ScriptSystemComponent::ClearAssetReferences, this, asset.GetId());
return Data::AssetHandler::LoadResult::LoadComplete;
}
@@ -853,7 +857,7 @@ const char* ScriptSystemComponent::GetGroup() const
const char* AZ::ScriptSystemComponent::GetBrowserIcon() const
{
return "Editor/Icons/Components/LuaScript.svg";
return "Icons/Components/LuaScript.svg";
}
AZ::Uuid AZ::ScriptSystemComponent::GetComponentTypeId() const
@@ -47,4 +47,4 @@ namespace AZ
}
}
#endif // #if !defined(AZCORE_EXCLUDE_LUA)
#endif // #if !defined(AZCORE_EXCLUDE_LUA)
@@ -287,4 +287,4 @@ namespace AZ
return nullptr;
}
}
}
@@ -118,6 +118,7 @@ namespace AZ
const static AZ::Crc32 StringLineEditingCompleteNotify = AZ_CRC("StringLineEditingCompleteNotify", 0x139e5fa9);
const static AZ::Crc32 NameLabelOverride = AZ_CRC("NameLabelOverride", 0x9ff79cab);
const static AZ::Crc32 AssetPickerTitle = AZ_CRC_CE("AssetPickerTitle");
const static AZ::Crc32 ChildNameLabelOverride = AZ_CRC("ChildNameLabelOverride", 0x73dd2909);
//! Container attribute that is used to override labels for its elements given the index of the element
const static AZ::Crc32 IndexedChildNameLabelOverride = AZ_CRC("IndexedChildNameLabelOverride", 0x5f313ac2);
@@ -10,91 +10,75 @@
*
*/
#include "ByteStreamSerializer.h"
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/Serialization/Json/ByteStreamSerializer.h>
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzCore/StringFunc/StringFunc.h>
namespace AZ
{
namespace ByteSerializerInternal
{
static JsonSerializationResult::Result Load(void* outputValue, const rapidjson::Value& inputValue, JsonDeserializerContext& context)
{
using JsonSerializationResult::Outcomes;
using JsonSerializationResult::Tasks;
AZ_Assert(outputValue, "Expected a valid pointer to load from json value.");
switch (inputValue.GetType())
{
case rapidjson::kStringType: {
JsonByteStream buffer;
if (AZ::StringFunc::Base64::Decode(buffer, inputValue.GetString(), inputValue.GetStringLength()))
{
JsonByteStream* valAsByteStream = static_cast<JsonByteStream*>(outputValue);
*valAsByteStream = AZStd::move(buffer);
return context.Report(Tasks::ReadField, Outcomes::Success, "Successfully read ByteStream.");
}
return context.Report(Tasks::ReadField, Outcomes::Invalid, "Decode of Base64 encoded ByteStream failed.");
}
case rapidjson::kArrayType:
case rapidjson::kObjectType:
case rapidjson::kNullType:
case rapidjson::kFalseType:
case rapidjson::kTrueType:
case rapidjson::kNumberType:
return context.Report(
Tasks::ReadField, Outcomes::Unsupported,
"Unsupported type. ByteStream values cannot be read from arrays, objects, nulls, booleans or numbers.");
default:
return context.Report(Tasks::ReadField, Outcomes::Unknown, "Unknown json type encountered for ByteStream value.");
}
}
static JsonSerializationResult::Result StoreWithDefault(
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, JsonSerializerContext& context)
{
using JsonSerializationResult::Outcomes;
using JsonSerializationResult::Tasks;
const JsonByteStream& valAsByteStream = *static_cast<const JsonByteStream*>(inputValue);
if (context.ShouldKeepDefaults() || !defaultValue || (valAsByteStream != *static_cast<const JsonByteStream*>(defaultValue)))
{
const auto base64ByteStream = AZ::StringFunc::Base64::Encode(valAsByteStream.data(), valAsByteStream.size());
outputValue.SetString(base64ByteStream.c_str(), base64ByteStream.size(), context.GetJsonAllocator());
return context.Report(Tasks::WriteValue, Outcomes::Success, "ByteStream successfully stored.");
}
return context.Report(Tasks::WriteValue, Outcomes::DefaultsUsed, "Default ByteStream used.");
}
} // namespace ByteSerializerInternal
AZ_CLASS_ALLOCATOR_IMPL(JsonByteStreamSerializer, SystemAllocator, 0);
JsonSerializationResult::Result JsonByteStreamSerializer::Load(
void* outputValue, [[maybe_unused]] const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context)
{
using JsonSerializationResult::Outcomes;
using JsonSerializationResult::Tasks;
AZ_Assert(
azrtti_typeid<JsonByteStream>() == outputValueTypeId,
"Unable to deserialize AZStd::vector<AZ::u8>> to json because the provided type is %s",
outputValueTypeId.ToString<AZStd::string>().c_str());
AZ_Assert(outputValue, "Expected a valid pointer to load from json value.");
return ByteSerializerInternal::Load(outputValue, inputValue, context);
switch (inputValue.GetType())
{
case rapidjson::kStringType: {
JsonByteStream buffer;
if (AZ::StringFunc::Base64::Decode(buffer, inputValue.GetString(), inputValue.GetStringLength()))
{
JsonByteStream* valAsByteStream = static_cast<JsonByteStream*>(outputValue);
*valAsByteStream = AZStd::move(buffer);
return context.Report(Tasks::ReadField, Outcomes::Success, "Successfully read ByteStream.");
}
return context.Report(Tasks::ReadField, Outcomes::Invalid, "Decode of Base64 encoded ByteStream failed.");
}
case rapidjson::kArrayType:
case rapidjson::kObjectType:
case rapidjson::kNullType:
case rapidjson::kFalseType:
case rapidjson::kTrueType:
case rapidjson::kNumberType:
return context.Report(
Tasks::ReadField, Outcomes::Unsupported,
"Unsupported type. ByteStream values cannot be read from arrays, objects, nulls, booleans or numbers.");
default:
return context.Report(Tasks::ReadField, Outcomes::Unknown, "Unknown json type encountered for ByteStream value.");
}
}
JsonSerializationResult::Result JsonByteStreamSerializer::Store(
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, [[maybe_unused]] const Uuid& valueTypeId,
JsonSerializerContext& context)
{
using JsonSerializationResult::Outcomes;
using JsonSerializationResult::Tasks;
AZ_Assert(
azrtti_typeid<JsonByteStream>() == valueTypeId,
"Unable to serialize AZStd::vector<AZ::u8> to json because the provided type is %s",
valueTypeId.ToString<AZStd::string>().c_str());
return ByteSerializerInternal::StoreWithDefault(outputValue, inputValue, defaultValue, context);
const JsonByteStream& valAsByteStream = *static_cast<const JsonByteStream*>(inputValue);
if (context.ShouldKeepDefaults() || !defaultValue || (valAsByteStream != *static_cast<const JsonByteStream*>(defaultValue)))
{
const auto base64ByteStream = AZ::StringFunc::Base64::Encode(valAsByteStream.data(), valAsByteStream.size());
outputValue.SetString(base64ByteStream.c_str(), base64ByteStream.size(), context.GetJsonAllocator());
return context.Report(Tasks::WriteValue, Outcomes::Success, "ByteStream successfully stored.");
}
return context.Report(Tasks::WriteValue, Outcomes::DefaultsUsed, "Default ByteStream used.");
}
} // namespace AZ
@@ -104,13 +104,12 @@ namespace AZ
auto serializer = context.GetRegistrationContext()->GetSerializerForType(classData.m_typeId);
if (serializer)
{
if (storeTypeId == StoreTypeId::Yes)
ResultCode result = serializer->Store(node, object, defaultObject, classData.m_typeId, context);
if (storeTypeId == StoreTypeId::Yes && result.GetProcessing() != Processing::Halted)
{
return context.Report(Tasks::WriteValue, Outcomes::Catastrophic,
"Unable to store type information in a JSON Serializer primitive.");
result.Combine(InsertTypeId(node, classData, context));
}
return serializer->Store(node, object, defaultObject, classData.m_typeId, context);
return result;
}
if (classData.m_azRtti && (classData.m_azRtti->GetTypeTraits() & AZ::TypeTraits::is_enum) == AZ::TypeTraits::is_enum)
@@ -128,13 +127,12 @@ namespace AZ
serializer = context.GetRegistrationContext()->GetSerializerForType(classData.m_azRtti->GetGenericTypeId());
if (serializer)
{
if (storeTypeId == StoreTypeId::Yes)
ResultCode result = serializer->Store(node, object, defaultObject, classData.m_typeId, context);
if (storeTypeId == StoreTypeId::Yes && result.GetProcessing() != Processing::Halted)
{
return context.Report(Tasks::WriteValue, Outcomes::Catastrophic,
"Unable to store type information in a JSON Serializer primitive.");
result.Combine(InsertTypeId(node, classData, context));
}
return serializer->Store(node, object, defaultObject, classData.m_typeId, context);
return result;
}
}
@@ -149,6 +147,7 @@ namespace AZ
ResultCode result(Tasks::WriteValue);
if (storeTypeId == StoreTypeId::Yes)
{
// Not using InsertTypeId here to avoid needing to create the temporary value and swap it in that call.
node.AddMember(rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier),
StoreTypeName(classData, context), context.GetJsonAllocator());
result = ResultCode(Tasks::WriteValue, Outcomes::Success);
@@ -569,6 +568,31 @@ namespace AZ
}
}
JsonSerializationResult::ResultCode JsonSerializer::InsertTypeId(
rapidjson::Value& output, const SerializeContext::ClassData& classData, JsonSerializerContext& context)
{
using namespace JsonSerializationResult;
if (output.IsObject())
{
rapidjson::Value insertedObject(rapidjson::kObjectType);
insertedObject.AddMember(
rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier), StoreTypeName(classData, context),
context.GetJsonAllocator());
for (auto& element : output.GetObject())
{
insertedObject.AddMember(AZStd::move(element.name), AZStd::move(element.value), context.GetJsonAllocator());
}
output = AZStd::move(insertedObject);
return ResultCode(Tasks::WriteValue, Outcomes::Success);
}
else
{
return context.Report(Tasks::WriteValue, Outcomes::Catastrophic, "Only able to store type information in a JSON Object.");
}
}
rapidjson::Value JsonSerializer::GetExplicitDefault()
{
return rapidjson::Value(rapidjson::kObjectType);
@@ -80,6 +80,9 @@ namespace AZ
static JsonSerializationResult::ResultCode StoreTypeName(rapidjson::Value& output,
const Uuid& typeId, JsonSerializerContext& context);
static JsonSerializationResult::ResultCode InsertTypeId(
rapidjson::Value& output, const SerializeContext::ClassData& classData, JsonSerializerContext& context);
static rapidjson::Value GetExplicitDefault();
};
} // namespace AZ
@@ -256,7 +256,7 @@ namespace AZ
//! Remove the value at the provided path
//! @param path The path to a value that should be removed
//! @return Whether or not the value was stored at the provided path. An invalid path will return false;
//! @return Whether or not the path was found and removed. An invalid path will return false;
virtual bool Remove(AZStd::string_view path) = 0;
//! Structure which contains configuration settings for how to parse a single command line argument
@@ -32,17 +32,12 @@
namespace AZ::Internal
{
AZ::SettingsRegistryInterface::FixedValueString GetEngineMonikerForProject(
SettingsRegistryInterface& settingsRegistry, const AZ::IO::FixedMaxPath& projectPath)
SettingsRegistryInterface& settingsRegistry, const AZ::IO::FixedMaxPath& projectJsonPath)
{
// projectPath needs to be an absolute path here.
using namespace AZ::SettingsRegistryMergeUtils;
bool projectJsonMerged = false;
auto projectJsonPath = projectPath / "project.json";
if (AZ::IO::SystemFile::Exists(projectJsonPath.c_str()))
{
projectJsonMerged = settingsRegistry.MergeSettingsFile(
projectJsonPath.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ProjectSettingsRootKey);
}
bool projectJsonMerged = settingsRegistry.MergeSettingsFile(
projectJsonPath.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ProjectSettingsRootKey);
AZ::SettingsRegistryInterface::FixedValueString engineMoniker;
if (projectJsonMerged)
@@ -105,12 +100,12 @@ namespace AZ::Internal
const auto engineMonikerKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/engine_name", EngineSettingsRootKey);
AZStd::set<AZ::IO::FixedMaxPath> projectPathsNotFound;
for (EngineInfo& engineInfo : pathVisitor.m_enginePaths)
{
AZ::IO::FixedMaxPath engineSettingsPath{engineInfo.m_path};
engineSettingsPath /= "engine.json";
if (AZ::IO::SystemFile::Exists(engineSettingsPath.c_str()))
if (auto engineSettingsPath = AZ::IO::FixedMaxPath{engineInfo.m_path} / "engine.json";
AZ::IO::SystemFile::Exists(engineSettingsPath.c_str()))
{
if (settingsRegistry.MergeSettingsFile(
engineSettingsPath.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, EngineSettingsRootKey))
@@ -119,12 +114,61 @@ namespace AZ::Internal
}
}
auto engineMoniker = Internal::GetEngineMonikerForProject(settingsRegistry, engineInfo.m_path / projectPath);
if (!engineMoniker.empty() && engineMoniker == engineInfo.m_moniker)
if (auto projectJsonPath = (engineInfo.m_path / projectPath / "project.json").LexicallyNormal();
AZ::IO::SystemFile::Exists(projectJsonPath.c_str()))
{
engineRoot = engineInfo.m_path;
break;
if (auto engineMoniker = Internal::GetEngineMonikerForProject(settingsRegistry, projectJsonPath);
!engineMoniker.empty() && engineMoniker == engineInfo.m_moniker)
{
engineRoot = engineInfo.m_path;
break;
}
}
else
{
projectPathsNotFound.insert(projectJsonPath);
}
// Continue looking for candidates, remove the previous engine and project settings that were merged above.
settingsRegistry.Remove(ProjectSettingsRootKey);
settingsRegistry.Remove(EngineSettingsRootKey);
}
if (engineRoot.empty())
{
AZStd::string errorStr;
if (!projectPathsNotFound.empty())
{
// This case is usually encountered when a project path is given as a relative path,
// which is assumed to be relative to an engine root.
// When no project.json files are found this way, dump this error message about
// which project paths were checked.
AZStd::string projectPathsTested;
for (const auto& path : projectPathsNotFound)
{
projectPathsTested.append(AZStd::string::format(" %s\n", path.c_str()));
}
errorStr = AZStd::string::format("No valid project was found at these locations:\n%s"
"Please supply a valid --project-path to the application.",
projectPathsTested.c_str());
}
else
{
// The other case is that a project.json was found, but after checking all the registered engines
// none of them matched the engine moniker.
AZStd::string enginePathsChecked;
for (const auto& engineInfo : pathVisitor.m_enginePaths)
{
enginePathsChecked.append(AZStd::string::format(" %s (%s)\n", engineInfo.m_path.c_str(), engineInfo.m_moniker.c_str()));
}
errorStr = AZStd::string::format(
"No engine was found in o3de_manifest.json with a name that matches the one set in the project.json.\n"
"Engines that were checked:\n%s"
"Please check that your engine and project have both been registered with scripts/o3de.py.", enginePathsChecked.c_str()
);
}
settingsRegistry.Set(FilePathKey_ErrorText, errorStr.c_str());
}
}
@@ -158,7 +202,7 @@ namespace AZ::Internal
return {};
}
void InjectSettingToCommandLineFront(AZ::SettingsRegistryInterface& settingsRegistry,
void InjectSettingToCommandLineBack(AZ::SettingsRegistryInterface& settingsRegistry,
AZStd::string_view path, AZStd::string_view value)
{
AZ::CommandLine commandLine;
@@ -168,7 +212,7 @@ namespace AZ::Internal
auto projectPathOverride = AZStd::string::format(R"(--regset="%.*s=%.*s")",
aznumeric_cast<int>(path.size()), path.data(), aznumeric_cast<int>(value.size()), value.data());
paramContainer.emplace(paramContainer.begin(), AZStd::move(projectPathOverride));
paramContainer.emplace(paramContainer.end(), AZStd::move(projectPathOverride));
commandLine.Parse(paramContainer);
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
}
@@ -197,8 +241,8 @@ namespace AZ::SettingsRegistryMergeUtils
if (!engineRoot.empty())
{
settingsRegistry.Set(engineRootKey, engineRoot.Native());
// Inject the engine root into the front of the command line settings
Internal::InjectSettingToCommandLineFront(settingsRegistry, engineRootKey, engineRoot.Native());
// Inject the engine root at the end of the command line settings
Internal::InjectSettingToCommandLineBack(settingsRegistry, engineRootKey, engineRoot.Native());
return engineRoot;
}
}
@@ -244,8 +288,8 @@ namespace AZ::SettingsRegistryMergeUtils
if (!projectRoot.empty())
{
settingsRegistry.Set(projectRootKey, projectRoot.c_str());
// Inject the project root into the front of the command line settings
Internal::InjectSettingToCommandLineFront(settingsRegistry, projectRootKey, projectRoot.Native());
// Inject the project root at the end of the command line settings
Internal::InjectSettingToCommandLineBack(settingsRegistry, projectRootKey, projectRoot.Native());
return projectRoot;
}
}
@@ -654,7 +698,6 @@ namespace AZ::SettingsRegistryMergeUtils
if (registry.Get(engineRootPath, FilePathKey_EngineRootFolder))
{
AZ::IO::FixedMaxPath mergePath{ AZStd::move(engineRootPath) };
mergePath /= "Engine";
mergePath /= SettingsRegistryInterface::RegistryFolder;
registry.MergeSettingsFolder(mergePath.Native(), specializations, platform, "", scratchBuffer);
}
@@ -875,6 +918,49 @@ namespace AZ::SettingsRegistryMergeUtils
return true;
}
void ParseCommandLine(AZ::CommandLine& commandLine)
{
struct OptionKeyToRegsetKey
{
AZStd::string_view m_optionKey;
AZStd::string m_regsetKey;
};
// Provide overrides for the engine root, the project root and the project cache root
AZStd::array commandOptions = {
OptionKeyToRegsetKey{
"engine-path", AZStd::string::format("%s/engine_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)},
OptionKeyToRegsetKey{
"project-path", AZStd::string::format("%s/project_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)},
OptionKeyToRegsetKey{
"project-cache-path",
AZStd::string::format("%s/project_cache_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)}};
AZStd::fixed_vector<AZStd::string, commandOptions.size()> overrideArgs;
for (auto&& [optionKey, regsetKey] : commandOptions)
{
if (size_t optionCount = commandLine.GetNumSwitchValues(optionKey); optionCount > 0)
{
// Use the last supplied command option value to override previous values
auto overrideArg = AZStd::string::format(
R"(--regset="%s=%s")", regsetKey.c_str(), commandLine.GetSwitchValue(optionKey, optionCount - 1).c_str());
overrideArgs.emplace_back(AZStd::move(overrideArg));
}
}
if (!overrideArgs.empty())
{
// Dump the input command line, add the additional option overrides
// and Parse the new command line args (write back) into the input command line.
AZ::CommandLine::ParamContainer commandLineArgs;
commandLine.Dump(commandLineArgs);
commandLineArgs.insert(
commandLineArgs.end(), AZStd::make_move_iterator(overrideArgs.begin()), AZStd::make_move_iterator(overrideArgs.end()));
commandLine.Parse(commandLineArgs);
}
}
bool DumpSettingsRegistryToStream(SettingsRegistryInterface& registry, AZStd::string_view key,
AZ::IO::GenericStream& stream, const DumperSettings& dumperSettings)
{
@@ -55,6 +55,9 @@ namespace AZ::SettingsRegistryMergeUtils
//! Development write storage path may be considered temporary or cache storage on some platforms
inline static constexpr char FilePathKey_DevWriteStorage[] = "/Amazon/AzCore/Runtime/FilePaths/DevWriteStorage";
//! Stores error text regarding engine boot sequence when engine and project roots cannot be determined
inline static constexpr char FilePathKey_ErrorText[] = "/Amazon/AzCore/Runtime/FilePaths/ErrorText";
//! Root key for where command line are stored at within the settings registry
inline static constexpr char CommandLineRootKey[] = "/Amazon/AzCore/Runtime/CommandLine";
//! Key set to trigger a notification that the CommandLine has been stored within the settings registry
@@ -219,6 +222,9 @@ namespace AZ::SettingsRegistryMergeUtils
//! into the AZ::CommandLine instance
bool GetCommandLineFromRegistry(SettingsRegistryInterface& registry, AZ::CommandLine& commandLine);
//! Parse a CommandLine and transform certain options into formal "regset" options
void ParseCommandLine(AZ::CommandLine& commandLine);
//! Structure for configuring how values should be dumped from the Settings Registry
struct DumperSettings
{
@@ -139,4 +139,4 @@ namespace AZ
/// @deprecated Use SliceBus.
using PrefabBus = SliceBus;
} // namespace AZ
} // namespace AZ
@@ -39,4 +39,4 @@ namespace AZ
SliceAssetHandler m_assetHandler;
};
} // namespace AZ
} // namespace AZ
+1 -1
View File
@@ -125,4 +125,4 @@ namespace AZ
bool DummyStateHandler(HSM& /*sm*/, const HSM::Event& /*e*/) { return handleEvent; }
}
#endif // AZCORE_HIERARCHIAL_STATE_MACHINE_H
#pragma once
#pragma once
+1 -1
View File
@@ -38,4 +38,4 @@ namespace AZStd
using std::is_placeholder;
template<class T>
constexpr size_t is_placeholder_v = is_placeholder<T>::value;
}
}
@@ -2024,4 +2024,4 @@ namespace AZStd
#endif // AZSTD_DELEGATE_H
#pragma once
#pragma once
@@ -228,4 +228,4 @@ namespace AZStd
}
#endif //AZSTD_DELEGATE_BIND_H
#pragma once
#pragma once
@@ -23,4 +23,4 @@ namespace AZStd
#endif // AZSTD_DELEGATE_H
#pragma once
#pragma once
@@ -194,4 +194,4 @@ namespace AZStd
}
#endif // AZSTD_PARALLEL_CONTAINERS_CONCURRENT_FIXED_UNORDERED_MAP_H
#pragma once
#pragma once
@@ -162,4 +162,4 @@ namespace AZStd
}
#endif // AZSTD_PARALLEL_CONTAINERS_CONCURRENT_FIXED_UNORDERED_SET_H
#pragma once
#pragma once
@@ -266,4 +266,4 @@ namespace AZStd
}
#endif // AZSTD_PARALLEL_CONTAINERS_CONCURRENT_UNORDERED_MAP_H
#pragma once
#pragma once
@@ -228,4 +228,4 @@ namespace AZStd
}
#endif // AZSTD_PARALLEL_CONTAINERS_CONCURRENT_UNORDERED_SET_H
#pragma once
#pragma once
@@ -159,4 +159,4 @@ namespace AZStd
}
#endif
#pragma once
#pragma once
@@ -23,4 +23,4 @@ namespace AZStd
*/
using intrusive_base = intrusive_refcount<atomic_uint>;
} // namespace AZStd
} // namespace AZStd
@@ -75,4 +75,4 @@ namespace AZStd
Deleter m_deleter;
};
} // namespace AZStd
} // namespace AZStd
@@ -62,4 +62,4 @@ namespace AZStd
}
}
#endif // AZSTD_MEMORYTOASCII_H
#endif // AZSTD_MEMORYTOASCII_H
@@ -16,4 +16,4 @@ namespace AZStd
{
using std::add_const;
using std::add_const_t;
}
}
@@ -17,4 +17,4 @@ namespace AZStd
using std::add_pointer;
template<class Type>
using add_pointer_t = std::add_pointer_t<Type>;
}
}
@@ -129,4 +129,4 @@ namespace AZStd
{
};
}
}
}
@@ -41,4 +41,4 @@ namespace AZStd
template <size_t index, typename ...Args>
using pack_traits_get_arg_t = typename pack_traits_get_arg<index, pack_traits_arg_sequence<Args...>>::type;
}
}
}
@@ -17,4 +17,4 @@ namespace AZStd
{
using std::is_member_object_pointer;
using std::is_member_object_pointer_v;
}
}

Some files were not shown because too many files have changed in this diff Show More