Merge branch 'main' into hasareej_LYN-2475_viewportui_switcher
This commit is contained in:
@@ -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
|
||||
)
|
||||
)
|
||||
|
||||
@@ -169,4 +169,4 @@ namespace UnitTest
|
||||
intintptr_cache.clear();
|
||||
EXPECT_EQ(p->use_count(), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -320,4 +320,4 @@ public class ObbDownloaderActivity extends Activity implements IDownloaderClient
|
||||
private int m_buttonPauseTextId;
|
||||
private int m_kbPerSecondTextId;
|
||||
private int m_timeRemainingTextId;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -37,4 +37,4 @@ public class ObbDownloaderAlarmReceiver extends BroadcastReceiver
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,10 +302,10 @@ def ProcessExpansionRule(sourceFiles, templateFiles, templateCache, outputDir, p
|
||||
# Due to the lack of wildcards in the output file, we've determined we'll glob all matching input files into the template conversion
|
||||
for filename in fnmatch.filter(sourceFiles, inputFiles):
|
||||
dataInputFiles = [os.path.abspath(file) for file in fnmatch.filter(sourceFiles, inputFiles)]
|
||||
outputFileAbsolute = outputFile.replace("$path", ComputeOutputPath(dataInputFiles, projectDir, outputDir))
|
||||
outputFileAbsolute = SanitizePath(outputFileAbsolute)
|
||||
ProcessTemplateConversion(dataInputSet, dataInputFiles, templateFile, outputFileAbsolute, templateCache, dryrun, verbose)
|
||||
outputFiles.append(outputFileAbsolute)
|
||||
outputFileAbsolute = outputFile.replace("$path", ComputeOutputPath(dataInputFiles, projectDir, outputDir))
|
||||
outputFileAbsolute = SanitizePath(outputFileAbsolute)
|
||||
ProcessTemplateConversion(dataInputSet, dataInputFiles, templateFile, outputFileAbsolute, templateCache, dryrun, verbose)
|
||||
outputFiles.append(outputFileAbsolute)
|
||||
except IOError as e:
|
||||
PrintError('%s : error I/O(%s) accessing %s : %s' % (expansionRule, e.errno, e.filename, e.strerror))
|
||||
except:
|
||||
@@ -357,8 +357,7 @@ if __name__ == '__main__':
|
||||
parser.add_argument("expansionRules", help="set of azcg expansion rules for matching data files to template files")
|
||||
parser.add_argument("-n", "--dryrun", action='store_true', help="does not execute autogen, only outputs the set of files that autogen would generate")
|
||||
parser.add_argument("-v", "--verbose", action='store_true', help="output only the set of files that would be generated by an expansion run")
|
||||
parser.add_argument("-p", "--pythonPaths", action='append', nargs='+', default=[""],
|
||||
help="set of additional python paths to use for module imports")
|
||||
parser.add_argument("-p", "--pythonPaths", action='append', nargs='+', default=[""], help="set of additional python paths to use for module imports")
|
||||
|
||||
args = parser.parse_args()
|
||||
pythonPaths = args.pythonPaths
|
||||
|
||||
@@ -11,4 +11,4 @@
|
||||
|
||||
set(FILES
|
||||
AzAutoGen.py
|
||||
)
|
||||
)
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace AZ
|
||||
bool loadFileToMemory = Get().ShouldLoadFileToMemory(filename);
|
||||
int assetMode = loadFileToMemory ? AASSET_MODE_BUFFER : AASSET_MODE_UNKNOWN;
|
||||
|
||||
asset = AAssetManager_open(Utils::GetAssetManager(), Utils::StripApkPrefix(filename), assetMode);
|
||||
asset = AAssetManager_open(Utils::GetAssetManager(), Utils::StripApkPrefix(filename).c_str(), assetMode);
|
||||
|
||||
if (asset != nullptr)
|
||||
{
|
||||
@@ -192,7 +192,7 @@ namespace AZ
|
||||
{
|
||||
buf->m_offset = buf->m_totalSize - offset;
|
||||
}
|
||||
|
||||
|
||||
if (buf->m_offset > buf->m_totalSize)
|
||||
{
|
||||
buf->m_offset = buf->m_totalSize;
|
||||
@@ -320,12 +320,19 @@ namespace AZ
|
||||
|
||||
bool APKFileHandler::DirectoryOrFileExists(const char* path)
|
||||
{
|
||||
ANDROID_IO_PROFILE_SECTION_ARGS("APK DirOrFileexists");
|
||||
ANDROID_IO_PROFILE_SECTION_ARGS("APK DirOrFileExists");
|
||||
|
||||
AZ::IO::PathView insideApkPathView(Utils::StripApkPrefix(path));
|
||||
AZ::IO::FixedMaxPath insideApkPath(Utils::StripApkPrefix(path));
|
||||
|
||||
AZ::IO::FixedMaxPathString filename{ insideApkPathView.Filename().Native() };
|
||||
AZ::IO::FixedMaxPathString pathToFile{ insideApkPathView.ParentPath().Native() };
|
||||
// Check for the case where the input path is equal to the APK Assets Prefix of /APK
|
||||
// In that case the directory is the "root" of APK assets in which case the directory exist
|
||||
if (insideApkPath.empty() && Utils::IsApkPath(path))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPathString filename{ insideApkPath.Filename().Native() };
|
||||
AZ::IO::FixedMaxPathString pathToFile{ insideApkPath.ParentPath().Native() };
|
||||
bool foundFile = false;
|
||||
|
||||
ParseDirectory(pathToFile.c_str(), [&](const char* name)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <AzCore/Debug/Trace.h>
|
||||
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -28,9 +28,9 @@ namespace AZ
|
||||
namespace
|
||||
{
|
||||
////////////////////////////////////////////////////////////////
|
||||
const char* GetApkAssetsPrefix()
|
||||
constexpr const char* GetApkAssetsPrefix()
|
||||
{
|
||||
return "/APK/";
|
||||
return "/APK";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,19 +104,14 @@ namespace AZ
|
||||
////////////////////////////////////////////////////////////////
|
||||
bool IsApkPath(const char* filePath)
|
||||
{
|
||||
return (strncmp(filePath, GetApkAssetsPrefix(), 4) == 0); // +3 for "APK", +1 for '/' starting slash
|
||||
return AZ::IO::PathView(filePath).IsRelativeTo(AZ::IO::PathView(GetApkAssetsPrefix()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
const char* StripApkPrefix(const char* filePath)
|
||||
AZ::IO::FixedMaxPath StripApkPrefix(const char* filePath)
|
||||
{
|
||||
const int prefixLength = 5; // +3 for "APK", +2 for '/' on either end
|
||||
if (!IsApkPath(filePath))
|
||||
{
|
||||
return filePath;
|
||||
}
|
||||
|
||||
return filePath + prefixLength;
|
||||
constexpr AZ::IO::PathView apkPrefixView = GetApkAssetsPrefix();
|
||||
return AZ::IO::PathView(filePath).LexicallyProximate(apkPrefixView);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
@@ -130,7 +125,7 @@ namespace AZ
|
||||
// first check to see if they are in public storage (application specific)
|
||||
const char* publicAppStorage = GetAppPublicStoragePath();
|
||||
|
||||
OSString path = OSString::format("%s/bootstrap.cfg", publicAppStorage);
|
||||
OSString path = OSString::format("%s/engine.json", publicAppStorage);
|
||||
AZ_TracePrintf("Android::Utils", "Searching for %s\n", path.c_str());
|
||||
|
||||
FILE* f = fopen(path.c_str(), "r");
|
||||
@@ -145,7 +140,7 @@ namespace AZ
|
||||
AAssetManager* mgr = GetAssetManager();
|
||||
if (mgr)
|
||||
{
|
||||
AAsset* asset = AAssetManager_open(mgr, "bootstrap.cfg", AASSET_MODE_UNKNOWN);
|
||||
AAsset* asset = AAssetManager_open(mgr, "engine.json", AASSET_MODE_UNKNOWN);
|
||||
if (asset)
|
||||
{
|
||||
AAsset_close(asset);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/IO/Path/Path_fwd.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
#include <jni.h>
|
||||
@@ -55,7 +56,7 @@ namespace AZ
|
||||
const char* GetObbStoragePath();
|
||||
|
||||
//! Get the dot separated package name for the current application.
|
||||
//! e.g. com.lumberyard.samples for SamplesProject
|
||||
//! e.g. com.o3de.samples for SamplesProject
|
||||
const char* GetPackageName();
|
||||
|
||||
//! Get the app version code (android:versionCode in the manifest).
|
||||
@@ -70,7 +71,7 @@ namespace AZ
|
||||
//! Will first check to verify the argument is an apk asset path and if so
|
||||
//! will strip the prefix from the path.
|
||||
//! \return The pointer position of the relative asset path
|
||||
const char* StripApkPrefix(const char* filePath);
|
||||
AZ::IO::FixedMaxPath StripApkPrefix(const char* filePath);
|
||||
|
||||
//! Searches application storage and the APK for bootstrap.cfg. Will return nullptr
|
||||
//! if bootstrap.cfg is not found.
|
||||
|
||||
@@ -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))
|
||||
@@ -418,16 +422,19 @@ namespace AZ
|
||||
|
||||
void AssetContainer::ListWaitingAssets() const
|
||||
{
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_readyMutex);
|
||||
AZ_TracePrintf("AssetContainer", "Waiting on assets:\n");
|
||||
for (auto& thisAsset : m_waitingAssets)
|
||||
{
|
||||
AZ_TracePrintf("AssetContainer", " %s\n",thisAsset.ToString<AZStd::string>().c_str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AssetContainer::ListWaitingPreloads(const AssetId& assetId) const
|
||||
void AssetContainer::ListWaitingPreloads([[maybe_unused]] const AssetId& assetId) const
|
||||
{
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> preloadGuard(m_preloadMutex);
|
||||
auto preloadEntry = m_preloadList.find(assetId);
|
||||
if (preloadEntry != m_preloadList.end())
|
||||
@@ -442,6 +449,7 @@ namespace AZ
|
||||
{
|
||||
AZ_TracePrintf("AssetContainer", "%s isn't waiting on any preloads:\n", assetId.ToString<AZStd::string>().c_str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AssetContainer::AddWaitingAssets(const AZStd::vector<AssetId>& assetList)
|
||||
@@ -606,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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,8 +90,8 @@ namespace AZ::Data
|
||||
// Get the results
|
||||
auto streamer = AZ::Interface<AZ::IO::IStreamer>::Get();
|
||||
AZ::u64 bytesRead = 0;
|
||||
bool result = streamer->GetReadRequestResult(fileHandle, m_buffer, bytesRead,
|
||||
AZ::IO::IStreamerTypes::ClaimMemory::Yes);
|
||||
streamer->GetReadRequestResult(fileHandle, m_buffer, bytesRead,
|
||||
AZ::IO::IStreamerTypes::ClaimMemory::Yes);
|
||||
auto status = streamer->GetRequestStatus(fileHandle);
|
||||
m_loadedSize = aznumeric_cast<size_t>(bytesRead);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetJsonSerializer.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
#include <AzCore/Serialization/Json/StackedString.h>
|
||||
@@ -107,7 +107,8 @@ namespace AZ
|
||||
result = ContinueLoading(&id, azrtti_typeid<AssetId>(), it->value, context);
|
||||
if (!id.m_guid.IsNull())
|
||||
{
|
||||
*instance = Asset<AssetData>(id, instance->GetType());
|
||||
*instance = AssetManager::Instance().FindOrCreateAsset(id, instance->GetType(), AssetLoadBehavior::NoLoad);
|
||||
|
||||
|
||||
result.Combine(context.Report(result, "Successfully created Asset<T> with id."));
|
||||
}
|
||||
|
||||
@@ -1117,7 +1117,7 @@ namespace AZ
|
||||
return asset;
|
||||
}
|
||||
|
||||
void AssetManager::UpdateDebugStatus(AZ::Data::Asset<AZ::Data::AssetData> asset)
|
||||
void AssetManager::UpdateDebugStatus(const AZ::Data::Asset<AZ::Data::AssetData>& asset)
|
||||
{
|
||||
if(!m_debugAssetEvents)
|
||||
{
|
||||
@@ -1750,7 +1750,6 @@ namespace AZ
|
||||
{
|
||||
AssetData* data = asset.Get();
|
||||
{
|
||||
const AZ::Data::AssetId& assetId = asset.GetId();
|
||||
|
||||
AZStd::scoped_lock<AZStd::recursive_mutex> assetLock(m_assetMutex);
|
||||
if (data)
|
||||
@@ -2145,7 +2144,7 @@ namespace AZ
|
||||
if (curIter != m_assetContainers.end())
|
||||
{
|
||||
auto newRef = curIter->second.lock();
|
||||
if (newRef)
|
||||
if (newRef && newRef->IsValid())
|
||||
{
|
||||
return newRef;
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@ namespace AZ
|
||||
|
||||
Asset<AssetData> GetAssetInternal(const AssetId& assetId, const AssetType& assetType, AssetLoadBehavior assetReferenceLoadBehavior, const AssetLoadParameters& loadParams = AssetLoadParameters{}, AssetInfo assetInfo = AssetInfo(), bool signalLoaded = false);
|
||||
|
||||
void UpdateDebugStatus(AZ::Data::Asset<AZ::Data::AssetData> asset);
|
||||
void UpdateDebugStatus(const AZ::Data::Asset<AZ::Data::AssetData>& asset);
|
||||
|
||||
/**
|
||||
* Gets a root asset and dependencies as individual async loads if necessary.
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
/** @file
|
||||
* Header file for the Component base class.
|
||||
* In Lumberyard's component entity system, each component defines a discrete
|
||||
* In Open 3D Engine's component entity system, each component defines a discrete
|
||||
* feature that can be attached to an entity.
|
||||
*/
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace AZ
|
||||
* practice to access other components through EBuses instead of accessing them directly.
|
||||
* For more information, see the
|
||||
* <a href="http://docs.aws.amazon.com/lumberyard/latest/developerguide/component-entity-system-pg-intro.html">Programmer's Guide to Entities and Components</a>
|
||||
* in the Lumberyard Developer Guide.
|
||||
* in the Open 3D Engine Developer Guide.
|
||||
* @return A pointer to the entity. If the component is not attached to any entity,
|
||||
* the return value is a null pointer.
|
||||
*/
|
||||
@@ -426,7 +426,7 @@ namespace AZ
|
||||
|
||||
/**
|
||||
* Describes the properties of the component descriptor event bus.
|
||||
* This bus uses AzTypeInfo::Uuid as the ID for the specific descriptor. Lumberyard allows only one
|
||||
* This bus uses AzTypeInfo::Uuid as the ID for the specific descriptor. Open 3D Engine allows only one
|
||||
* descriptor for each component type. When you call functions on the bus for a specific component
|
||||
* type, you can safely pass only one result variable because aggregating or overwriting results
|
||||
* is impossible.
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <AzCore/Memory/OverrunDetectionAllocator.h>
|
||||
#include <AzCore/Memory/AllocatorManager.h>
|
||||
#include <AzCore/Memory/MallocSchema.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/ObjectStream.h>
|
||||
@@ -174,78 +173,85 @@ namespace AZ
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
//! SettingsRegistry notifier handler which updates relevant registry settings based
|
||||
//! on an update to '/Amazon/AzCore/Bootstrap/project_path' key.
|
||||
struct UpdateProjectSettingsEventHandler
|
||||
{
|
||||
UpdateProjectSettingsEventHandler(AZ::SettingsRegistryInterface& registry)
|
||||
UpdateProjectSettingsEventHandler(AZ::SettingsRegistryInterface& registry, AZ::CommandLine& commandLine)
|
||||
: m_registry{ registry }
|
||||
, m_commandLine{ commandLine }
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(AZStd::string_view path, AZ::SettingsRegistryInterface::Type)
|
||||
{
|
||||
UpdateProjectSpecializationInRegistry(path);
|
||||
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
|
||||
// #1 Update the project settings when the project path is set
|
||||
const auto projectPathKey = FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
|
||||
AZ::IO::FixedMaxPath newProjectPath;
|
||||
if (SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual(projectPathKey, path)
|
||||
&& m_registry.Get(newProjectPath.Native(), projectPathKey) && newProjectPath != m_oldProjectPath)
|
||||
{
|
||||
UpdateProjectSettingsFromProjectPath(AZ::IO::PathView(newProjectPath));
|
||||
}
|
||||
|
||||
// #2 Update the project specialization when the project name is set
|
||||
const auto projectNameKey = FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey) + "/project_name";
|
||||
FixedValueString newProjectName;
|
||||
if (SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual(projectNameKey, path)
|
||||
&& m_registry.Get(newProjectName, projectNameKey) && newProjectName != m_oldProjectName)
|
||||
{
|
||||
UpdateProjectSpecializationFromProjectName(newProjectName);
|
||||
}
|
||||
|
||||
// #3 Update the ComponentApplication CommandLine instance when the command line settings are merged into the Settings Registry
|
||||
if (path == AZ::SettingsRegistryMergeUtils::CommandLineValueChangedKey)
|
||||
{
|
||||
UpdateCommandLine();
|
||||
}
|
||||
}
|
||||
|
||||
//! Add the project name as a specialization underneath the /Amazon/AzCore/Settings/Specializations path
|
||||
//! and remove the current project name specialization if one exists.
|
||||
void UpdateProjectSpecializationInRegistry(AZStd::string_view path)
|
||||
void UpdateProjectSpecializationFromProjectName(AZStd::string_view newProjectName)
|
||||
{
|
||||
auto projectPathKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)
|
||||
+ "/project_path";
|
||||
if (path == projectPathKey)
|
||||
{
|
||||
AZ::SettingsRegistryInterface::FixedValueString newProjectPath;
|
||||
if (m_registry.Get(newProjectPath, path) && !newProjectPath.empty())
|
||||
{
|
||||
// Make the path absolute by appending to app root, in case project path is relative.
|
||||
// If the project path is already absolute it will remain the same.
|
||||
// If we turn it from a relative path to an absolute path, write-back the absolute path to the registry.
|
||||
AZ::IO::FixedMaxPath projectPath = AZ::SettingsRegistryMergeUtils::FindEngineRoot(m_registry) / newProjectPath;
|
||||
if (projectPath.Compare(newProjectPath.c_str()))
|
||||
{
|
||||
m_registry.Set(path, projectPath.Native());
|
||||
}
|
||||
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
|
||||
// Add the project_name as a specialization for loading the build system dependency .setreg files
|
||||
auto newProjectNameSpecialization = FixedValueString::format("%s/%.*s", AZ::SettingsRegistryMergeUtils::SpecializationsRootKey,
|
||||
aznumeric_cast<int>(newProjectName.size()), newProjectName.data());
|
||||
auto oldProjectNameSpecialization = FixedValueString::format("%s/%s", AZ::SettingsRegistryMergeUtils::SpecializationsRootKey,
|
||||
m_oldProjectName.c_str());
|
||||
m_registry.Remove(oldProjectNameSpecialization);
|
||||
m_oldProjectName = newProjectName;
|
||||
m_registry.Set(newProjectNameSpecialization, true);
|
||||
}
|
||||
|
||||
// Merge the project.json file into settings registry under ProjectSettingsRootKey path.
|
||||
AZ::IO::FixedMaxPath projectMetadataFile{ projectPath };
|
||||
projectMetadataFile /= "project.json";
|
||||
m_registry.MergeSettingsFile(projectMetadataFile.Native(),
|
||||
AZ::SettingsRegistryInterface::Format::JsonMergePatch, AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey);
|
||||
void UpdateProjectSettingsFromProjectPath(AZ::IO::PathView newProjectPath)
|
||||
{
|
||||
// Update old Project path before attempting to merge in new Settings Registry values in order to prevent recursive calls
|
||||
m_oldProjectPath = newProjectPath;
|
||||
|
||||
// Get the 'project_name' value from what was in the 'project.json' file...
|
||||
auto projectNameKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey)
|
||||
+ "/project_name";
|
||||
// Merge the project.json file into settings registry under ProjectSettingsRootKey path.
|
||||
AZ::IO::FixedMaxPath projectMetadataFile{ AZ::SettingsRegistryMergeUtils::FindEngineRoot(m_registry) / newProjectPath };
|
||||
projectMetadataFile /= "project.json";
|
||||
m_registry.MergeSettingsFile(projectMetadataFile.Native(),
|
||||
AZ::SettingsRegistryInterface::Format::JsonMergePatch, AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey);
|
||||
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectSpecialization;
|
||||
if (m_registry.Get(projectSpecialization, projectNameKey))
|
||||
{
|
||||
auto specializationKey = AZ::SettingsRegistryInterface::FixedValueString::format(
|
||||
"%s/%s", AZ::SettingsRegistryMergeUtils::SpecializationsRootKey, projectSpecialization.c_str());
|
||||
if (m_currentSpecialization != specializationKey)
|
||||
{
|
||||
m_registry.Set(specializationKey, true);
|
||||
if (!m_currentSpecialization.empty())
|
||||
{
|
||||
// Remove the previous Project Name from the specialization path if it was set.
|
||||
m_registry.Remove(m_currentSpecialization);
|
||||
}
|
||||
m_currentSpecialization = specializationKey;
|
||||
// Update all the runtime file paths based on the new "project_path" value.
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(m_registry);
|
||||
}
|
||||
|
||||
// Update all the runtime file paths based on the new "project_path" value.
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(m_registry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void UpdateCommandLine()
|
||||
{
|
||||
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(m_registry, m_commandLine);
|
||||
}
|
||||
|
||||
private:
|
||||
AZ::SettingsRegistryInterface::FixedValueString m_currentSpecialization;
|
||||
AZ::IO::FixedMaxPath m_oldProjectPath;
|
||||
AZ::SettingsRegistryInterface::FixedValueString m_oldProjectName;
|
||||
AZ::SettingsRegistryInterface& m_registry;
|
||||
AZ::CommandLine& m_commandLine;
|
||||
};
|
||||
|
||||
void ComponentApplication::Descriptor::AllocatorRemapping::Reflect(ReflectContext* context, ComponentApplication* app)
|
||||
@@ -335,6 +341,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);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -362,11 +378,20 @@ namespace AZ
|
||||
ComponentApplication::ComponentApplication()
|
||||
: ComponentApplication(0, nullptr)
|
||||
{
|
||||
if (Interface<ComponentApplicationRequests>::Get() == nullptr)
|
||||
{
|
||||
Interface<ComponentApplicationRequests>::Register(this);
|
||||
}
|
||||
}
|
||||
|
||||
ComponentApplication::ComponentApplication(int argC, char** argV)
|
||||
: m_eventLogger{}
|
||||
{
|
||||
if (Interface<ComponentApplicationRequests>::Get() == nullptr)
|
||||
{
|
||||
Interface<ComponentApplicationRequests>::Register(this);
|
||||
}
|
||||
|
||||
if (argV)
|
||||
{
|
||||
m_argC = argC;
|
||||
@@ -415,7 +440,13 @@ namespace AZ
|
||||
// Add the Command Line arguments into the SettingsRegistry
|
||||
SettingsRegistryMergeUtils::StoreCommandLineToRegistry(*m_settingsRegistry, m_commandLine);
|
||||
|
||||
// Merge Command Line arguments
|
||||
// Add a notifier to update the project_settings when
|
||||
// 1. The 'project_path' key changes
|
||||
// 2. The project specialization when the 'project-name' key changes
|
||||
// 3. The ComponentApplication command line when the command line is stored to the registry
|
||||
m_projectChangedHandler = m_settingsRegistry->RegisterNotifier(UpdateProjectSettingsEventHandler{ *m_settingsRegistry, m_commandLine });
|
||||
|
||||
// Merge Command Line arguments
|
||||
constexpr bool executeRegDumpCommands = false;
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
|
||||
|
||||
@@ -429,10 +460,6 @@ namespace AZ
|
||||
// for the application root.
|
||||
CalculateAppRoot();
|
||||
|
||||
// Add a notifier to update the /Amazon/AzCore/Settings/Specializations
|
||||
// when the 'project_path' property changes within the SettingsRegistry
|
||||
m_projectChangedHandler = m_settingsRegistry->RegisterNotifier(UpdateProjectSettingsEventHandler{ *m_settingsRegistry });
|
||||
|
||||
// Merge the bootstrap.cfg file into the Settings Registry as soon as the OSAllocator has been created.
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(*m_settingsRegistry);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(*m_settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
|
||||
@@ -462,6 +489,11 @@ namespace AZ
|
||||
//=========================================================================
|
||||
ComponentApplication::~ComponentApplication()
|
||||
{
|
||||
if (Interface<ComponentApplicationRequests>::Get() == this)
|
||||
{
|
||||
Interface<ComponentApplicationRequests>::Unregister(this);
|
||||
}
|
||||
|
||||
if (m_isStarted)
|
||||
{
|
||||
Destroy();
|
||||
@@ -495,8 +527,7 @@ namespace AZ
|
||||
DestroyAllocator();
|
||||
}
|
||||
|
||||
Entity* ComponentApplication::Create(const Descriptor& descriptor,
|
||||
const StartupParameters& startupParameters)
|
||||
Entity* ComponentApplication::Create(const Descriptor& descriptor, const StartupParameters& startupParameters)
|
||||
{
|
||||
AZ_Assert(!m_isStarted, "Component application already started!");
|
||||
|
||||
@@ -905,6 +936,8 @@ namespace AZ
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true);
|
||||
#endif
|
||||
// Update the Runtime file paths in case the "{BootstrapSettingsRootKey}/assets" key was overriden by a setting registry
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry);
|
||||
}
|
||||
|
||||
void ComponentApplication::SetSettingsRegistrySpecializations(SettingsRegistryInterface::Specializations& specializations)
|
||||
@@ -943,6 +976,16 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentApplication::RegisterEntityAddedEventHandler(EntityAddedEvent::Handler& handler)
|
||||
{
|
||||
handler.Connect(m_entityAddedEvent);
|
||||
}
|
||||
|
||||
void ComponentApplication::RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler& handler)
|
||||
{
|
||||
handler.Connect(m_entityRemovedEvent);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// AddEntity
|
||||
// [5/30/2012]
|
||||
@@ -954,7 +997,7 @@ namespace AZ
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_entityAddedEvent.Signal(entity);
|
||||
return m_entities.insert(AZStd::make_pair(entity->GetId(), entity)).second;
|
||||
}
|
||||
|
||||
@@ -969,7 +1012,7 @@ namespace AZ
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_entityRemovedEvent.Signal(entity);
|
||||
return (m_entities.erase(entity->GetId()) == 1);
|
||||
}
|
||||
|
||||
@@ -982,6 +1025,7 @@ namespace AZ
|
||||
Entity* entity = FindEntity(id);
|
||||
if (entity)
|
||||
{
|
||||
m_entityRemovedEvent.Signal(entity);
|
||||
delete entity;
|
||||
return true;
|
||||
}
|
||||
@@ -1016,6 +1060,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
|
||||
//=========================================================================
|
||||
@@ -1371,10 +1429,7 @@ namespace AZ
|
||||
//=========================================================================
|
||||
void ComponentApplication::CalculateExecutablePath()
|
||||
{
|
||||
Utils::GetExecutableDirectory(m_exeDirectory.data(), m_exeDirectory.capacity());
|
||||
// Update the size value of the executable directory fixed string to correctly be the length of the null-terminated string stored within it
|
||||
m_exeDirectory.resize_no_construct(AZStd::char_traits<char>::length(m_exeDirectory.data()));
|
||||
m_exeDirectory.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
|
||||
m_exeDirectory = Utils::GetExecutableDirectory();
|
||||
}
|
||||
|
||||
void ComponentApplication::CalculateAppRoot()
|
||||
@@ -1382,19 +1437,12 @@ namespace AZ
|
||||
if (AZStd::optional<AZ::StringFunc::Path::FixedString> appRootPath = Utils::GetDefaultAppRootPath(); appRootPath)
|
||||
{
|
||||
m_appRoot = AZStd::move(*appRootPath);
|
||||
if (!m_appRoot.empty() && !m_appRoot.ends_with(AZ_CORRECT_FILESYSTEM_SEPARATOR))
|
||||
{
|
||||
m_appRoot.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentApplication::CalculateEngineRoot()
|
||||
{
|
||||
if (m_engineRoot = AZ::SettingsRegistryMergeUtils::FindEngineRoot(*m_settingsRegistry).Native(); !m_engineRoot.empty())
|
||||
{
|
||||
m_engineRoot.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
|
||||
}
|
||||
m_engineRoot = AZ::SettingsRegistryMergeUtils::FindEngineRoot(*m_settingsRegistry).Native();
|
||||
}
|
||||
|
||||
void ComponentApplication::ResolveModulePath([[maybe_unused]] AZ::OSString& modulePath)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <AzCore/Module/DynamicModuleHandle.h>
|
||||
#include <AzCore/Module/ModuleManager.h>
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/RTTI/ReflectionManager.h>
|
||||
@@ -193,8 +194,7 @@ namespace AZ
|
||||
* You will need to setup all system components manually.
|
||||
* \returns pointer to the system entity.
|
||||
*/
|
||||
virtual Entity* Create(const Descriptor& descriptor,
|
||||
const StartupParameters& startupParameters = StartupParameters());
|
||||
virtual Entity* Create(const Descriptor& descriptor, const StartupParameters& startupParameters = StartupParameters());
|
||||
virtual void Destroy();
|
||||
virtual void DestroyAllocator(); // Called at the end of Destroy(). Applications can override to do tear down work right before allocator is destroyed.
|
||||
|
||||
@@ -202,11 +202,14 @@ namespace AZ
|
||||
// ComponentApplicationRequests
|
||||
void RegisterComponentDescriptor(const ComponentDescriptor* descriptor) override final;
|
||||
void UnregisterComponentDescriptor(const ComponentDescriptor* descriptor) override final;
|
||||
void RegisterEntityAddedEventHandler(EntityAddedEvent::Handler& handler) override final;
|
||||
void RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler& handler) override final;
|
||||
bool AddEntity(Entity* entity) override;
|
||||
bool RemoveEntity(Entity* entity) override;
|
||||
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.
|
||||
@@ -380,6 +383,8 @@ namespace AZ
|
||||
float m_deltaTime{ 0.0f };
|
||||
AZStd::unique_ptr<ModuleManager> m_moduleManager;
|
||||
AZStd::unique_ptr<SettingsRegistryInterface> m_settingsRegistry;
|
||||
EntityAddedEvent m_entityAddedEvent;
|
||||
EntityRemovedEvent m_entityRemovedEvent;
|
||||
AZ::IConsole* m_console{};
|
||||
Descriptor m_descriptor;
|
||||
bool m_isStarted{ false };
|
||||
@@ -389,9 +394,9 @@ namespace AZ
|
||||
void* m_fixedMemoryBlock{ nullptr }; //!< Pointer to the memory block allocator, so we can free it OnDestroy.
|
||||
IAllocatorAllocate* m_osAllocator{ nullptr };
|
||||
EntitySetType m_entities;
|
||||
AZ::IO::FixedMaxPathString m_exeDirectory;
|
||||
AZ::IO::FixedMaxPathString m_engineRoot;
|
||||
AZ::IO::FixedMaxPathString m_appRoot;
|
||||
AZ::IO::FixedMaxPath m_exeDirectory;
|
||||
AZ::IO::FixedMaxPath m_engineRoot;
|
||||
AZ::IO::FixedMaxPath m_appRoot;
|
||||
|
||||
AZ::SettingsRegistryInterface::NotifyEventHandler m_projectChangedHandler;
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/EBus/Event.h>
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
#include <AzCore/std/string/osstring.h>
|
||||
@@ -69,160 +70,144 @@ namespace AZ
|
||||
inline bool ApplicationTypeQuery::IsGame() const { return (m_maskValue & Masks::Game) == Masks::Game; }
|
||||
inline bool ApplicationTypeQuery::IsValid() const { return m_maskValue != Masks::Invalid; }
|
||||
|
||||
/**
|
||||
* Event bus that components use to make requests of the main application.
|
||||
* Only one application can exist at a time, which is why this bus
|
||||
* supports only one listener.
|
||||
*/
|
||||
using EntityAddedEvent = AZ::Event<AZ::Entity*>;
|
||||
using EntityRemovedEvent = AZ::Event<AZ::Entity*>;
|
||||
|
||||
//! Interface that components can use to make requests of the main application.
|
||||
class ComponentApplicationRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(ComponentApplicationRequests, "{E8BE41B7-615F-4FE8-B611-8A9E441290A8}");
|
||||
|
||||
/**
|
||||
* Destroys the event bus that components use to make requests of the main application.
|
||||
*/
|
||||
virtual ~ComponentApplicationRequests() {}
|
||||
//! Destroys the event bus that components use to make requests of the main application.
|
||||
virtual ~ComponentApplicationRequests() = default;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides - application is a singleton
|
||||
/**
|
||||
* Overrides the default AZ::EBusTraits handler policy to allow one
|
||||
* listener only, because only one application can exist at a time.
|
||||
*/
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Single; // We sort components on m_initOrder.
|
||||
/**
|
||||
* Overrides the default AZ::EBusTraits mutex type to the AZStd implementation of
|
||||
* a recursive mutex with exclusive ownership semantics. A mutex prevents multiple
|
||||
* threads from accessing shared data simultaneously.
|
||||
*/
|
||||
typedef AZStd::recursive_mutex MutexType;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Registers a component descriptor with the application.
|
||||
* @param descriptor A component descriptor.
|
||||
*/
|
||||
//! Registers a component descriptor with the application.
|
||||
//! @param descriptor A component descriptor.
|
||||
virtual void RegisterComponentDescriptor(const ComponentDescriptor* descriptor) = 0;
|
||||
/**
|
||||
* Unregisters a component descriptor with the application.
|
||||
* @param descriptor A component descriptor.
|
||||
*/
|
||||
|
||||
//! Unregisters a component descriptor with the application.
|
||||
//! @param descriptor A component descriptor.
|
||||
virtual void UnregisterComponentDescriptor(const ComponentDescriptor* descriptor) = 0;
|
||||
/**
|
||||
* Gets a pointer to the application.
|
||||
* @return A pointer to the application.
|
||||
*/
|
||||
virtual ComponentApplication* GetApplication() = 0;
|
||||
|
||||
/**
|
||||
* Adds an entity to the application's registry.
|
||||
* Calling Init() on an entity automatically performs this operation.
|
||||
* @param entity A pointer to the entity to add to the application's registry.
|
||||
* @return True if the operation succeeded. False if the operation failed.
|
||||
*/
|
||||
virtual bool AddEntity(Entity* entity) = 0;
|
||||
/**
|
||||
* Removes the specified entity from the application's registry.
|
||||
* Deleting an entity automatically performs this operation.
|
||||
* @param entity A pointer to the entity that will be removed from the application's registry.
|
||||
* @return True if the operation succeeded. False if the operation failed.
|
||||
*/
|
||||
virtual bool RemoveEntity(Entity* entity) = 0;
|
||||
/**
|
||||
* Unregisters and deletes the specified entity.
|
||||
* @param entity A reference to the entity that will be unregistered and deleted.
|
||||
* @return True if the operation succeeded. False if the operation failed.
|
||||
*/
|
||||
virtual bool DeleteEntity(const EntityId& id) = 0;
|
||||
/**
|
||||
* Returns the entity with the matching ID, if the entity is registered with the application.
|
||||
* @param entity A reference to the entity that you are searching for.
|
||||
* @return A pointer to the entity with the specified entity ID.
|
||||
*/
|
||||
virtual Entity* FindEntity(const EntityId& id) = 0;
|
||||
/**
|
||||
* Returns the name of the entity that has the specified entity ID.
|
||||
* Entity names are not unique.
|
||||
* This method exists to facilitate better debugging messages.
|
||||
* @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(); };
|
||||
//! Gets a pointer to the application.
|
||||
//! @return A pointer to the application.
|
||||
virtual ComponentApplication* GetApplication() = 0;
|
||||
|
||||
/**
|
||||
* The type that AZ::ComponentApplicationRequests::EnumerateEntities uses to
|
||||
* pass entity callbacks to the application for enumeration.
|
||||
*/
|
||||
//! Registers an event handler that will be signalled whenever an entity is added.
|
||||
//! @param handler the event handler to signal.
|
||||
virtual void RegisterEntityAddedEventHandler(EntityAddedEvent::Handler& handler) = 0;
|
||||
|
||||
//! Registers an event handler that will be signalled whenever an entity is removed.
|
||||
//! @param handler the event handler to signal.
|
||||
virtual void RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler& handler) = 0;
|
||||
|
||||
//! Adds an entity to the application's registry.
|
||||
//! Calling Init() on an entity automatically performs this operation.
|
||||
//! @param entity A pointer to the entity to add to the application's registry.
|
||||
//! @return True if the operation succeeded. False if the operation failed.
|
||||
virtual bool AddEntity(Entity* entity) = 0;
|
||||
|
||||
//! Removes the specified entity from the application's registry.
|
||||
//! Deleting an entity automatically performs this operation.
|
||||
//! @param entity A pointer to the entity that will be removed from the application's registry.
|
||||
//! @return True if the operation succeeded. False if the operation failed.
|
||||
virtual bool RemoveEntity(Entity* entity) = 0;
|
||||
|
||||
//! Unregisters and deletes the specified entity.
|
||||
//! @param entity A reference to the entity that will be unregistered and deleted.
|
||||
//! @return True if the operation succeeded. False if the operation failed.
|
||||
virtual bool DeleteEntity(const EntityId& id) = 0;
|
||||
|
||||
//! Returns the entity with the matching ID, if the entity is registered with the application.
|
||||
//! @param entity A reference to the entity that you are searching for.
|
||||
//! @return A pointer to the entity with the specified entity ID.
|
||||
virtual Entity* FindEntity(const EntityId& id) = 0;
|
||||
|
||||
//! Returns the name of the entity that has the specified entity ID.
|
||||
//! Entity names are not unique.
|
||||
//! This method exists to facilitate better debugging messages.
|
||||
//! @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(); }
|
||||
|
||||
//! 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.
|
||||
using EntityCallback = AZStd::function<void(Entity*)>;
|
||||
/**
|
||||
* Enumerates all registered entities and invokes the specified callback for each entity.
|
||||
* @param callback A reference to the callback that is invoked for each entity.
|
||||
*/
|
||||
virtual void EnumerateEntities(const EntityCallback& callback) = 0;
|
||||
/**
|
||||
* Returns the serialize context that was registered with the app.
|
||||
* @return The serialize context, if there is one. SerializeContext is a class that contains reflection data
|
||||
* for serialization and construction of objects.
|
||||
*/
|
||||
|
||||
//! Enumerates all registered entities and invokes the specified callback for each entity.
|
||||
//! @param callback A reference to the callback that is invoked for each entity.
|
||||
virtual void EnumerateEntities(const EntityCallback& callback) = 0;
|
||||
|
||||
//! Returns the serialize context that was registered with the app.
|
||||
//! @return The serialize context, if there is one. SerializeContext is a class that contains reflection data
|
||||
//! for serialization and construction of objects.
|
||||
virtual class SerializeContext* GetSerializeContext() = 0;
|
||||
/**
|
||||
* Returns the behavior context that was registered with the app.
|
||||
* @return The behavior context, if there is one. BehaviorContext is a class that reflects classes, methods,
|
||||
* and EBuses for runtime interaction.
|
||||
*/
|
||||
|
||||
//! Returns the behavior context that was registered with the app.
|
||||
//! @return The behavior context, if there is one. BehaviorContext is a class that reflects classes, methods,
|
||||
//! and EBuses for runtime interaction.
|
||||
virtual class BehaviorContext* GetBehaviorContext() = 0;
|
||||
/**
|
||||
* Returns the Json Registration context that was registered with the app.
|
||||
* @return The Json Registration context, if there is one. JsonRegistrationContext is a class that contains
|
||||
* the serializers used by the best-effort json serialization.
|
||||
*/
|
||||
|
||||
//! Returns the Json Registration context that was registered with the app.
|
||||
//! @return The Json Registration context, if there is one. JsonRegistrationContext is a class that contains
|
||||
//! the serializers used by the best-effort json serialization.
|
||||
virtual class JsonRegistrationContext* GetJsonRegistrationContext() = 0;
|
||||
/**
|
||||
* Gets the name of the working root folder that was registered with the app.
|
||||
* @return A pointer to the name of the app's root folder, if a root folder was registered.
|
||||
*/
|
||||
virtual const char* GetAppRoot() const = 0;
|
||||
/**
|
||||
* Gets the path of the working engine folder that the app is a part of.
|
||||
* @return A pointer to the engine path.
|
||||
*/
|
||||
virtual const char* GetEngineRoot() const = 0;
|
||||
/**
|
||||
* Gets the path to the directory that contains the application's executable.
|
||||
* @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;
|
||||
//! Gets the name of the working root folder that was registered with the app.
|
||||
//! @return a pointer to the name of the app's root folder, if a root folder was registered.
|
||||
virtual const char* GetAppRoot() const = 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.
|
||||
* The default implantation prepends the path to the executable to the module path, but you can override this behavior
|
||||
* (Call the base class if you want this behavior to persist in overrides)
|
||||
*/
|
||||
virtual void ResolveModulePath(AZ::OSString& /*modulePath*/) { }
|
||||
//! Gets the path of the working engine folder that the app is a part of.
|
||||
//! @return a pointer to the engine path.
|
||||
virtual const char* GetEngineRoot() const = 0;
|
||||
|
||||
/**
|
||||
* Returns AZ parsed command line structure.
|
||||
* Command Line structure can be queried for switches (-<switch> /<switch>) or positional parameter (<value>)
|
||||
*/
|
||||
//! Gets the path to the directory that contains the application's executable.
|
||||
//! @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.
|
||||
//! The default implantation prepends the path to the executable to the module path, but you can override this behavior
|
||||
//! (Call the base class if you want this behavior to persist in overrides)
|
||||
virtual void ResolveModulePath([[maybe_unused]] AZ::OSString& modulePath) { }
|
||||
|
||||
//! Returns AZ parsed command line structure.
|
||||
//! Command Line structure can be queried for switches (-<switch> /<switch>) or positional parameter (<value>)
|
||||
virtual AZ::CommandLine* GetAzCommandLine() { return{}; }
|
||||
|
||||
//! Returns all the flags that are true for the current application.
|
||||
virtual void QueryApplicationType(ApplicationTypeQuery& appType) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used by components to make requests of the component application.
|
||||
*/
|
||||
typedef AZ::EBus<ComponentApplicationRequests> ComponentApplicationBus;
|
||||
class ComponentApplicationRequestsEBusTraits
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//! EBusTraits overrides - application is a singleton
|
||||
//! Overrides the default AZ::EBusTraits handler policy to allow one
|
||||
//! listener only, because only one application can exist at a time.
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Single; // We sort components on m_initOrder.
|
||||
|
||||
//! Overrides the default AZ::EBusTraits mutex type to the AZStd implementation of
|
||||
//! a recursive mutex with exclusive ownership semantics. A mutex prevents multiple
|
||||
//! threads from accessing shared data simultaneously.
|
||||
using MutexType = AZStd::recursive_mutex;
|
||||
};
|
||||
|
||||
//! Used by components to make requests of the component application.
|
||||
using ComponentApplicationBus = AZ::EBus<ComponentApplicationRequests, ComponentApplicationRequestsEBusTraits>;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Component/NamedEntityId.h>
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Casting/lossy_cast.h>
|
||||
|
||||
#include <AzCore/Serialization/Json/RegistrationContext.h>
|
||||
@@ -159,10 +159,11 @@ namespace AZ
|
||||
AZ_Assert(m_state == State::Constructed, "Component should be in Constructed state to be Initialized!");
|
||||
SetState(State::Initializing);
|
||||
|
||||
bool result = true;
|
||||
EBUS_EVENT_RESULT(result, ComponentApplicationBus, AddEntity, this);
|
||||
(void)result;
|
||||
AZ_Assert(result, "Failed to add entity '%s' [0x%llx]! Did you already register an entity with this ID?", m_name.c_str(), m_id);
|
||||
if (AZ::Interface<ComponentApplicationRequests>::Get() != nullptr)
|
||||
{
|
||||
[[maybe_unused]] const bool result = AZ::Interface<ComponentApplicationRequests>::Get()->AddEntity(this);
|
||||
AZ_Assert(result, "Failed to add entity '%s' [0x%llx]! Did you already register an entity with this ID?", m_name.c_str(), m_id);
|
||||
}
|
||||
|
||||
for (ComponentArrayType::iterator it = m_components.begin(); it != m_components.end();)
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
/** @file
|
||||
* Header file for the Entity class.
|
||||
* In Lumberyard's component entity system, an entity is an addressable container for
|
||||
* In Open 3D Engine's component entity system, an entity is an addressable container for
|
||||
* a group of components. The entity represents the functionality and properties of an
|
||||
* object within your game.
|
||||
*/
|
||||
|
||||
@@ -40,10 +40,26 @@ namespace AZ
|
||||
(*idMapper)->SetIsEntityReference(false);
|
||||
}
|
||||
|
||||
JSR::ResultCode idLoadResult =
|
||||
ContinueLoadingFromJsonObjectField(&entityInstance->m_id,
|
||||
azrtti_typeid<decltype(entityInstance->m_id)>(),
|
||||
inputValue, "Id", context);
|
||||
JSR::ResultCode idLoadResult = ContinueLoadingFromJsonObjectField(
|
||||
&entityInstance->m_id, azrtti_typeid<decltype(entityInstance->m_id)>(), inputValue, "Id", context);
|
||||
|
||||
// If the entity has an invalid ID, there's no point in deserializing, the entity will be unusable.
|
||||
// It's also dangerous to generate new IDs here:
|
||||
// - They need to be globally unique
|
||||
// - We don't know *why* it's invalid (maybe just a typo on the name "Id" for example), so we don't know the ramifications
|
||||
// of changing it. There might be many other entities that have references to this one that would become invalid as well
|
||||
// if we try to silently fix it up.
|
||||
// - Unless we save the ID immediately, it will change every time we serialize the data in, which can happen multiple times
|
||||
// during the serialization pipeline. So it either needs to be saved back immediately, or we need a deterministic way
|
||||
// to generate a globally unique ID for the entity.
|
||||
if (!entityInstance->GetId().IsValid())
|
||||
{
|
||||
// Since we're going to halt processing anyways, we just return the error here immediately.
|
||||
return context.Report(
|
||||
JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Invalid),
|
||||
"Invalid or missing entity ID - please add an 'Id' field to this entity with a globally unique id. \n"
|
||||
"Failed to load entity information.");
|
||||
}
|
||||
|
||||
if (hasValidIdMapper)
|
||||
{
|
||||
@@ -93,9 +109,10 @@ namespace AZ
|
||||
inputValue, "IsRuntimeActive", context);
|
||||
}
|
||||
|
||||
return context.Report(result,
|
||||
result.GetProcessing() == JSR::Processing::Halted ? "Succesfully loaded entity information." :
|
||||
"Failed to load entity information.");
|
||||
return context.Report(
|
||||
result,
|
||||
result.GetProcessing() != JSR::Processing::Halted ? "Succesfully loaded entity information."
|
||||
: "Failed to load entity information.");
|
||||
}
|
||||
|
||||
JsonSerializationResult::Result JsonEntitySerializer::Store(rapidjson::Value& outputValue,
|
||||
@@ -199,7 +216,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
return context.Report(result,
|
||||
result.GetProcessing() == JSR::Processing::Halted ? "Successfully stored Entity information." :
|
||||
result.GetProcessing() != JSR::Processing::Halted ? "Successfully stored Entity information." :
|
||||
"Failed to store Entity information.");
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,6 @@ namespace AZ
|
||||
{
|
||||
class Vector3;
|
||||
|
||||
//! Do not allow the scale to be zero to avoid problems with inverting scale.
|
||||
static constexpr float MinNonUniformScale = 1e-3f;
|
||||
|
||||
using NonUniformScaleChangedEvent = AZ::Event<const AZ::Vector3&>;
|
||||
|
||||
//! Requests for working with non-uniform scale.
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace AZ
|
||||
{
|
||||
class Transform;
|
||||
|
||||
using TransformChangedEvent = Event<Transform, Transform>;
|
||||
using TransformChangedEvent = Event<const Transform&, const Transform&>;
|
||||
|
||||
using ParentChangedEvent = Event<EntityId, EntityId>;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -42,9 +42,8 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
#define AZ_TRACE_METHOD_NAME_CATEGORY(name, category) AZ::Debug::EventTrace::ScopedSlice AZ_JOIN(ScopedSlice__, __LINE__)(name, category);
|
||||
|
||||
#ifdef AZ_PROFILE_TELEMETRY
|
||||
# define AZ_TRACE_METHOD_NAME_CATEGORY(name, category) AZ::Debug::EventTrace::ScopedSlice AZ_JOIN(ScopedSlice__, __LINE__)(name, category);
|
||||
# define AZ_TRACE_METHOD_NAME(name) \
|
||||
AZ_TRACE_METHOD_NAME_CATEGORY(name, "") \
|
||||
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzTrace, name)
|
||||
@@ -53,6 +52,7 @@ namespace AZ
|
||||
AZ_TRACE_METHOD_NAME_CATEGORY(AZ_FUNCTION_SIGNATURE, "") \
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzTrace)
|
||||
#else
|
||||
# define AZ_TRACE_METHOD_NAME_CATEGORY(name, category)
|
||||
# define AZ_TRACE_METHOD_NAME(name) AZ_TRACE_METHOD_NAME_CATEGORY(name, "")
|
||||
# define AZ_TRACE_METHOD() AZ_TRACE_METHOD_NAME(AZ_FUNCTION_SIGNATURE)
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* Header file for internal EBus classes.
|
||||
* For more information about EBuses, see AZ::EBus and AZ::EBusTraits in this guide and
|
||||
* [Event Bus](http://docs.aws.amazon.com/lumberyard/latest/developerguide/asset-pipeline-ebus.html)
|
||||
* in the *Lumberyard Developer Guide*.
|
||||
* in the *Open 3D Engine Developer Guide*.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
/**
|
||||
* @file
|
||||
* Header file for event bus (EBus), a general-purpose communication system
|
||||
* that Lumberyard uses to dispatch notifications and receive requests.
|
||||
* that Open 3D Engine uses to dispatch notifications and receive requests.
|
||||
* EBuses are configurable and support many different use cases.
|
||||
* For more information about %EBuses, see AZ::EBus in this guide and
|
||||
* [Event Bus](http://docs.aws.amazon.com/lumberyard/latest/developerguide/asset-pipeline-ebus.html)
|
||||
* in the *Lumberyard Developer Guide*.
|
||||
* in the *Open 3D Engine Developer Guide*.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -70,7 +70,7 @@ namespace AZ
|
||||
*
|
||||
* For more information about %EBuses, see EBus in this guide and
|
||||
* [Event Bus](http://docs.aws.amazon.com/lumberyard/latest/developerguide/asset-pipeline-ebus.html)
|
||||
* in the *Lumberyard Developer Guide*.
|
||||
* in the *Open 3D Engine Developer Guide*.
|
||||
*/
|
||||
struct EBusTraits
|
||||
{
|
||||
@@ -256,7 +256,7 @@ namespace AZ
|
||||
|
||||
/**
|
||||
* Event buses (EBuses) are a general-purpose communication system
|
||||
* that Lumberyard uses to dispatch notifications and receive requests.
|
||||
* that Open 3D Engine uses to dispatch notifications and receive requests.
|
||||
*
|
||||
* @tparam Interface A class whose virtual functions define the events
|
||||
* dispatched or received by the %EBus.
|
||||
@@ -268,7 +268,7 @@ namespace AZ
|
||||
* For more information about EBuses, see
|
||||
* [Event Bus](http://docs.aws.amazon.com/lumberyard/latest/developerguide/asset-pipeline-ebus.html)
|
||||
* and [Components and EBuses: Best Practices ](http://docs.aws.amazon.com/lumberyard/latest/developerguide/component-entity-system-pg-components-ebuses-best-practices.html)
|
||||
* in the *Lumberyard Developer Guide*.
|
||||
* in the *Open 3D Engine Developer Guide*.
|
||||
*
|
||||
* ## How Components Use EBuses
|
||||
* Components commonly use EBuses in two ways: to dispatch events or to handle requests.
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/EBus/EventSchedulerSystemComponent.h>
|
||||
#include <AzCore/EBus/ScheduledEvent.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Console/ILogger.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
@@ -111,8 +110,10 @@ namespace AZ
|
||||
TimeMs currentMilliseconds = GetElapsedTimeMs();
|
||||
if (timedEvent->m_handle == nullptr)
|
||||
{
|
||||
timedEvent->m_handle = AllocateHandle(TimeMs(currentMilliseconds + durationMs), durationMs, timedEvent);
|
||||
timedEvent->m_handle = AllocateHandle();
|
||||
}
|
||||
const bool ownsScheduledEvent = false;
|
||||
*(timedEvent->m_handle) = ScheduledEventHandle(TimeMs(currentMilliseconds + durationMs), durationMs, timedEvent, ownsScheduledEvent);
|
||||
timedEvent->m_timeInserted = currentMilliseconds;
|
||||
m_queue.push(timedEvent->m_handle);
|
||||
return timedEvent->m_handle;
|
||||
@@ -126,7 +127,9 @@ namespace AZ
|
||||
}
|
||||
|
||||
TimeMs currentMilliseconds = GetElapsedTimeMs();
|
||||
ScheduledEvent* timedEvent = AllocateManagedEvent(TimeMs(currentMilliseconds + durationMs), durationMs, callback, eventName);
|
||||
ScheduledEvent* timedEvent = AllocateManagedEvent(callback, eventName);
|
||||
const bool ownsScheduledEvent = true;
|
||||
*(timedEvent->m_handle) = ScheduledEventHandle(TimeMs(currentMilliseconds + durationMs), durationMs, timedEvent, ownsScheduledEvent);
|
||||
timedEvent->m_timeInserted = currentMilliseconds;
|
||||
m_queue.push(timedEvent->m_handle);
|
||||
}
|
||||
@@ -150,10 +153,12 @@ namespace AZ
|
||||
{
|
||||
AZLOG_INFO("EventSchedulerSystemComponent::HandleCount = %u", aznumeric_cast<uint32_t>(GetHandleCount()));
|
||||
AZLOG_INFO("EventSchedulerSystemComponent::FreeHandleCount = %u", aznumeric_cast<uint32_t>(GetFreeHandleCount()));
|
||||
AZLOG_INFO("EventSchedulerSystemComponent::OwnedEventCount = %u", aznumeric_cast<uint32_t>(m_ownedEvents.size()));
|
||||
AZLOG_INFO("EventSchedulerSystemComponent::FreeEventCount = %u", aznumeric_cast<uint32_t>(m_freeEvents.size()));
|
||||
AZLOG_INFO("EventSchedulerSystemComponent::QueueSize = %u", aznumeric_cast<uint32_t>(GetQueueSize()));
|
||||
}
|
||||
|
||||
ScheduledEventHandle* EventSchedulerSystemComponent::AllocateHandle(TimeMs executeTimeMs, TimeMs durationTimeMs, ScheduledEvent* scheduledEvent)
|
||||
ScheduledEventHandle* EventSchedulerSystemComponent::AllocateHandle()
|
||||
{
|
||||
ScheduledEventHandle* result = nullptr;
|
||||
if (!m_freeHandles.empty())
|
||||
@@ -166,31 +171,34 @@ namespace AZ
|
||||
m_handles.resize(m_handles.size() + 1);
|
||||
result = &(m_handles.back());
|
||||
}
|
||||
*result = ScheduledEventHandle(executeTimeMs, durationTimeMs, scheduledEvent, false);
|
||||
return result;
|
||||
}
|
||||
|
||||
ScheduledEvent* EventSchedulerSystemComponent::AllocateManagedEvent(TimeMs executeTimeMs, TimeMs durationTimeMs, const AZStd::function<void()>& callback, const Name& eventName)
|
||||
ScheduledEvent* EventSchedulerSystemComponent::AllocateManagedEvent(const AZStd::function<void()>& callback, const Name& eventName)
|
||||
{
|
||||
ScheduledEvent* result = new ScheduledEvent(callback, eventName);
|
||||
ScheduledEventHandle* handle = nullptr;
|
||||
if (!m_freeHandles.empty())
|
||||
ScheduledEvent* scheduledEvent = nullptr;
|
||||
if (!m_freeEvents.empty())
|
||||
{
|
||||
handle = m_freeHandles.back();
|
||||
m_freeHandles.pop_back();
|
||||
scheduledEvent = m_freeEvents.back();
|
||||
m_freeEvents.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_handles.resize(m_handles.size() + 1);
|
||||
handle = &(m_handles.back());
|
||||
m_ownedEvents.resize(m_ownedEvents.size() + 1);
|
||||
scheduledEvent = &(m_ownedEvents.back());
|
||||
}
|
||||
*handle = ScheduledEventHandle(executeTimeMs, durationTimeMs, result, true);
|
||||
result->m_handle = handle;
|
||||
return result;
|
||||
scheduledEvent->m_eventName = eventName;
|
||||
scheduledEvent->m_callback = callback;
|
||||
scheduledEvent->m_handle = AllocateHandle();
|
||||
return scheduledEvent;
|
||||
}
|
||||
|
||||
void EventSchedulerSystemComponent::FreeHandle(ScheduledEventHandle* handle)
|
||||
{
|
||||
if (handle->GetOwnsScheduledEvent())
|
||||
{
|
||||
m_freeEvents.push_back(handle->GetScheduledEvent());
|
||||
}
|
||||
m_freeHandles.push_back(handle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/EBus/ScheduledEventHandle.h>
|
||||
#include <AzCore/EBus/ScheduledEvent.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/containers/queue.h>
|
||||
@@ -89,9 +90,11 @@ namespace AZ
|
||||
//! @}
|
||||
|
||||
private:
|
||||
ScheduledEventHandle* AllocateHandle(TimeMs executeTimeMs, TimeMs durationTimeMs, ScheduledEvent* scheduledEvent);
|
||||
// Allocates a single use event to capture the passed in callback. Event is cleaned up on completion.
|
||||
ScheduledEvent* AllocateManagedEvent(TimeMs executeTimeMs, TimeMs durationTimeMs, const AZStd::function<void()>& callback, const Name& eventName);
|
||||
ScheduledEventHandle* AllocateHandle();
|
||||
|
||||
//! Allocates a single use event to capture the passed in callback. Event is cleaned up on completion.
|
||||
ScheduledEvent* AllocateManagedEvent(const AZStd::function<void()>& callback, const Name& eventName);
|
||||
|
||||
void FreeHandle(ScheduledEventHandle* handle);
|
||||
|
||||
// Bind the DumpStats member function to the console as 'EventSchedulerSystemComponent.DumpStats'
|
||||
@@ -100,6 +103,8 @@ namespace AZ
|
||||
// Priority queues of scheduled events sorted by execution time
|
||||
AZStd::priority_queue<ScheduledEventHandle*, AZStd::vector<ScheduledEventHandle*>, CompareScheduledEventPtrs> m_queue;
|
||||
AZStd::priority_queue<ScheduledEventHandle*, AZStd::vector<ScheduledEventHandle*>, PrioritizeScheduledEventPtrs> m_pendingQueue;
|
||||
AZStd::deque<ScheduledEvent> m_ownedEvents;
|
||||
AZStd::vector<ScheduledEvent*> m_freeEvents;
|
||||
AZStd::deque<ScheduledEventHandle> m_handles;
|
||||
AZStd::vector<ScheduledEventHandle*> m_freeHandles;
|
||||
};
|
||||
|
||||
@@ -194,4 +194,4 @@ namespace AZ
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,7 +359,7 @@ namespace AZ
|
||||
|
||||
//insert the new handler
|
||||
handler.m_index = aznumeric_cast<int32_t>(AZStd::distance(m_handlers.begin(), insertLocation));
|
||||
auto insertedItr = m_handlers.insert(insertLocation, &handler);
|
||||
m_handlers.insert(insertLocation, &handler);
|
||||
return handler.m_index;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ namespace AZ
|
||||
void ScheduledEvent::Requeue(TimeMs durationMs)
|
||||
{
|
||||
m_durationMs = durationMs;
|
||||
ClearHandle();
|
||||
IEventScheduler* eventScheduler = Interface<IEventScheduler>::Get();
|
||||
if (eventScheduler)
|
||||
{
|
||||
@@ -120,10 +119,6 @@ namespace AZ
|
||||
|
||||
void ScheduledEvent::ClearHandle()
|
||||
{
|
||||
if (m_handle)
|
||||
{
|
||||
m_handle->Clear();
|
||||
m_handle = nullptr;
|
||||
}
|
||||
m_handle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ namespace AZ
|
||||
class ScheduledEvent
|
||||
{
|
||||
public:
|
||||
//! Default constructor only for AZStd::deque compatibility.
|
||||
ScheduledEvent() = default;
|
||||
|
||||
//! Constructor of ScheduledEvent class.
|
||||
//! @param callback a call back function to be executed when the event triggers
|
||||
//! @param eventName name of the scheduled event for easier debugging
|
||||
@@ -82,8 +85,6 @@ namespace AZ
|
||||
//! Clears any currently set handle pointer.
|
||||
void ClearHandle();
|
||||
|
||||
AZ_DISABLE_COPY_MOVE(ScheduledEvent);
|
||||
|
||||
Name m_eventName; //< Scheduled event name
|
||||
AZStd::function<void()> m_callback; //< A callback function to run when the scheduled event triggers
|
||||
ScheduledEventHandle* m_handle = nullptr; //< Handle pointer to protect running a deleted event callback function
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
ScheduledEventHandle::ScheduledEventHandle(TimeMs executeTimeMs, TimeMs durationTimeMs, ScheduledEvent* scheduledEvent, bool isAutoDelete)
|
||||
ScheduledEventHandle::ScheduledEventHandle(TimeMs executeTimeMs, TimeMs durationTimeMs, ScheduledEvent* scheduledEvent, bool ownsScheduledEvent)
|
||||
: m_executeTimeMs(executeTimeMs)
|
||||
, m_durationMs(durationTimeMs)
|
||||
, m_event(scheduledEvent)
|
||||
, m_autoDelete(isAutoDelete)
|
||||
, m_ownsScheduledEvent(ownsScheduledEvent)
|
||||
{
|
||||
;
|
||||
}
|
||||
@@ -49,11 +49,6 @@ namespace AZ
|
||||
else // Not configured to auto-requeue, so remove the handle
|
||||
{
|
||||
m_event->ClearHandle();
|
||||
if (m_autoDelete)
|
||||
{
|
||||
delete m_event;
|
||||
}
|
||||
m_event = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,11 +60,6 @@ namespace AZ
|
||||
return false; // Event has been deleted, so the handle class must be deleted after this function.
|
||||
}
|
||||
|
||||
void ScheduledEventHandle::Clear()
|
||||
{
|
||||
m_event = nullptr;
|
||||
}
|
||||
|
||||
TimeMs ScheduledEventHandle::GetExecuteTimeMs() const
|
||||
{
|
||||
return m_executeTimeMs;
|
||||
@@ -79,4 +69,14 @@ namespace AZ
|
||||
{
|
||||
return m_durationMs;
|
||||
}
|
||||
|
||||
bool ScheduledEventHandle::GetOwnsScheduledEvent() const
|
||||
{
|
||||
return m_ownsScheduledEvent;
|
||||
}
|
||||
|
||||
ScheduledEvent* ScheduledEventHandle::GetScheduledEvent() const
|
||||
{
|
||||
return m_event;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ namespace AZ
|
||||
//! @param executeTimeMs an absolute time in ms at which point the scheduled event should trigger
|
||||
//! @param durationTimeMs the interval time in ms used for prioritization as well as re-queueing
|
||||
//! @param scheduledEvent a scheduled event to run
|
||||
//! @param autoDelete if the event handle will be automatically deleted after execution completes
|
||||
ScheduledEventHandle(TimeMs executeTimeMs, TimeMs durationTimeMs, ScheduledEvent* scheduledEvent, bool isAutoDelete);
|
||||
//! @param ownsScheduledEvent true if the event handle owns its own scheduled event instance
|
||||
ScheduledEventHandle(TimeMs executeTimeMs, TimeMs durationTimeMs, ScheduledEvent* scheduledEvent, bool ownsScheduledEvent = false);
|
||||
|
||||
//! operator of comparing a scheduled event by execute time.
|
||||
//! @param a_Rhs a scheduled event handle to compare
|
||||
@@ -42,9 +42,6 @@ namespace AZ
|
||||
//! @return true for re-queuing a scheduled event or false for deleting this class.
|
||||
bool Notify();
|
||||
|
||||
//! Set nullptr for a scheduled event pointer.
|
||||
void Clear();
|
||||
|
||||
//! Get the execution time in ms for this scheduled event.
|
||||
//! @return the execution time in ms for this scheduled event
|
||||
TimeMs GetExecuteTimeMs() const;
|
||||
@@ -54,12 +51,20 @@ namespace AZ
|
||||
//! @return the duration time in ms for this scheduled event
|
||||
TimeMs GetDurationTimeMs() const;
|
||||
|
||||
//! Gets whether or not the event handle owns its own scheduled event.
|
||||
//! @return true if the event handle owns
|
||||
bool GetOwnsScheduledEvent() const;
|
||||
|
||||
//! Gets the scheduled event instance bound to this event handle.
|
||||
//! @return the scheduled event instance bound to this event handle
|
||||
ScheduledEvent* GetScheduledEvent() const;
|
||||
|
||||
private:
|
||||
|
||||
TimeMs m_executeTimeMs = TimeMs{ 0 }; //< execution time of the scheduled event
|
||||
TimeMs m_durationMs = TimeMs{ 0 }; //< interval time of the scheduled event
|
||||
ScheduledEvent* m_event = nullptr; //< pointer to the scheduled event
|
||||
bool m_autoDelete = false; //< if the handle manages the memory of its own event
|
||||
bool m_ownsScheduledEvent = false; //< if the handle manages the memory of its own event
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -96,8 +96,8 @@ namespace AZ::IO
|
||||
constexpr int Compare(const value_type* pathString) const noexcept;
|
||||
|
||||
// decomposition
|
||||
//! Given a windows path of "C:\lumberyard\foo\bar\name.txt" and a posix path of
|
||||
//! "/lumberyard/foo/bar/name.txt"
|
||||
//! Given a windows path of "C:\O3DE\foo\bar\name.txt" and a posix path of
|
||||
//! "/O3DE/foo/bar/name.txt"
|
||||
//! The following functions return the following
|
||||
|
||||
//! Returns the root name part of the path. if it has one.
|
||||
@@ -114,10 +114,10 @@ namespace AZ::IO
|
||||
constexpr PathView RootPath() const;
|
||||
//! Returns the relative path portion of the path.
|
||||
//! This contains the path parts after the root path
|
||||
//! windows = "lumberyard\foo\bar\name.txt", posix = "lumberyard/foo/bar/name.txt"
|
||||
//! windows = "O3DE\foo\bar\name.txt", posix = "O3DE/foo/bar/name.txt"
|
||||
constexpr PathView RelativePath() const;
|
||||
//! Returns the parent directory of filename contained within the path
|
||||
//! windows = "C:\lumberyard\foo\bar", posix = "/lumberyard/foo/bar"
|
||||
//! windows = "C:\O3DE\foo\bar", posix = "/O3DE/foo/bar"
|
||||
//! NOTE: If the path ends with a trailing separator "test/foo/" it is treated as being a path of
|
||||
//! "test/foo" as if the filename of the path is "foo" and the parent directory is "test"
|
||||
constexpr PathView ParentPath() const;
|
||||
@@ -150,7 +150,7 @@ namespace AZ::IO
|
||||
//! The root portion of the path is made up of root_name() / root_directory()
|
||||
[[nodiscard]] constexpr bool HasRootPath() const;
|
||||
//! checks whether the relative part of path is empty
|
||||
//! (C:\\ lumberyard\dev\)
|
||||
//! (C:\\ O3DE\dev\)
|
||||
//! ^ ^
|
||||
//! root part relative part
|
||||
[[nodiscard]] constexpr bool HasRelativePath() const;
|
||||
@@ -485,10 +485,10 @@ namespace AZ::IO
|
||||
constexpr PathView RootPath() const;
|
||||
//! Returns the relative path portion of the path.
|
||||
//! This contains the path parts after the root path
|
||||
//! windows = "lumberyard\foo\bar\name.txt", posix = "lumberyard/foo/bar/name.txt"
|
||||
//! windows = "O3DE\foo\bar\name.txt", posix = "O3DE/foo/bar/name.txt"
|
||||
constexpr PathView RelativePath() const;
|
||||
//! Returns the parent directory of filename contained within the path
|
||||
//! windows = "C:\lumberyard\foo\bar", posix = "/lumberyard/foo/bar"
|
||||
//! windows = "C:\O3DE\foo\bar", posix = "/O3DE/foo/bar"
|
||||
//! NOTE: If the path ends with a trailing separator "test/foo/" it is treated as being a path of
|
||||
//! "test/foo" as if the filename of the path is "foo" and the parent directory is "test"
|
||||
constexpr PathView ParentPath() const;
|
||||
@@ -521,8 +521,8 @@ namespace AZ::IO
|
||||
//! The root portion of the path is made up of root_name() / root_directory()
|
||||
[[nodiscard]] constexpr bool HasRootPath() const;
|
||||
//! checks whether the relative part of path is empty
|
||||
//! (C:\\ lumberyard\dev\)
|
||||
//! ^ ^
|
||||
//! (C:\\ O3DE\dev\)
|
||||
//! ^ ^
|
||||
//! root part relative part
|
||||
[[nodiscard]] constexpr bool HasRelativePath() const;
|
||||
//! checks whether the path has a parent path that empty
|
||||
@@ -544,8 +544,8 @@ namespace AZ::IO
|
||||
[[nodiscard]] constexpr bool IsRelativeTo(const PathView& base) const;
|
||||
|
||||
// decomposition
|
||||
//! Given a windows path of "C:\lumberyard\foo\bar\name.txt" and a posix path of
|
||||
//! "/lumberyard/foo/bar/name.txt"
|
||||
//! Given a windows path of "C:\O3DE\foo\bar\name.txt" and a posix path of
|
||||
//! "/O3DE/foo/bar/name.txt"
|
||||
//! The following functions return the following
|
||||
|
||||
// query
|
||||
|
||||
@@ -214,6 +214,20 @@ namespace AZ::IO::Internal
|
||||
// logic
|
||||
return IsAbsolute(pathView.begin(), pathView.end(), preferredSeparator);
|
||||
}
|
||||
|
||||
// Compares path segments using either Posix or Windows path rules based on the path separator in use
|
||||
// Posix paths perform a case-sensitive comparison, while Windows paths perform a case-insensitive comparison
|
||||
static int ComparePathSegment(AZStd::string_view left, AZStd::string_view right, char pathSeparator)
|
||||
{
|
||||
const size_t maxCharsToCompare = (AZStd::min)(left.size(), right.size());
|
||||
|
||||
int charCompareResult = pathSeparator == PosixPathSeparator
|
||||
? strncmp(left.data(), right.data(), maxCharsToCompare)
|
||||
: azstrnicmp(left.data(), right.data(), maxCharsToCompare);
|
||||
return charCompareResult == 0
|
||||
? aznumeric_cast<ptrdiff_t>(left.size()) - aznumeric_cast<ptrdiff_t>(right.size())
|
||||
: charCompareResult;
|
||||
}
|
||||
}
|
||||
|
||||
//! PathParser implementation
|
||||
@@ -351,7 +365,6 @@ namespace AZ::IO::parser
|
||||
constexpr void Decrement() noexcept
|
||||
{
|
||||
auto pathStart = m_path_view.begin();
|
||||
auto pathEnd = m_path_view.end();
|
||||
auto currentPathEntry = getCurrentTokenStartPos();
|
||||
|
||||
if (currentPathEntry == pathStart)
|
||||
@@ -613,7 +626,7 @@ namespace AZ::IO::parser
|
||||
{
|
||||
return pathParser->InRootName() ? **pathParser : "";
|
||||
};
|
||||
int res = GetRootName(lhsPathParser).compare(GetRootName(rhsPathParser));
|
||||
int res = Internal::ComparePathSegment(GetRootName(lhsPathParser), GetRootName(rhsPathParser), lhsPathParser->m_preferred_separator);
|
||||
ConsumeRootName(lhsPathParser);
|
||||
ConsumeRootName(rhsPathParser);
|
||||
return res;
|
||||
@@ -642,7 +655,8 @@ namespace AZ::IO::parser
|
||||
|
||||
while (lhsPathParser && rhsPathParser)
|
||||
{
|
||||
if (int res = (*lhsPathParser).compare(*rhsPathParser); res != 0)
|
||||
if (int res = Internal::ComparePathSegment(*lhsPathParser, *rhsPathParser, lhsPathParser.m_preferred_separator);
|
||||
res != 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@@ -1033,11 +1047,25 @@ namespace AZ::IO
|
||||
parser::PathParser patternParserEnd(pathPatternView.relative_path_view(), parser::ParserState::PS_AtEnd, pathPatternView.m_preferred_separator);
|
||||
|
||||
// move the parser from the end to a valid filename by decrementing
|
||||
for(--pathParserEnd, --patternParserEnd; pathParserEnd && patternParserEnd; --pathParserEnd, --patternParserEnd)
|
||||
// Windows Paths are case-insensitive, while Posix paths are case-sensitive
|
||||
if (m_preferred_separator == PosixPathSeparator)
|
||||
{
|
||||
if (!AZStd::wildcard_match_case(*patternParserEnd, *pathParserEnd))
|
||||
for (--pathParserEnd, --patternParserEnd; pathParserEnd && patternParserEnd; --pathParserEnd, --patternParserEnd)
|
||||
{
|
||||
return false;
|
||||
if (!AZStd::wildcard_match_case(*patternParserEnd, *pathParserEnd))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (--pathParserEnd, --patternParserEnd; pathParserEnd && patternParserEnd; --pathParserEnd, --patternParserEnd)
|
||||
{
|
||||
if (!AZStd::wildcard_match(*patternParserEnd, *pathParserEnd))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -147,15 +147,18 @@ namespace AZ
|
||||
ReadFile(request, args);
|
||||
return;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
|
||||
else
|
||||
{
|
||||
FlushCache(args.m_path);
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
|
||||
{
|
||||
FlushCache(args.m_path);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
|
||||
{
|
||||
FlushEntireCache();
|
||||
}
|
||||
StreamStackEntry::QueueRequest(request);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
|
||||
{
|
||||
FlushEntireCache();
|
||||
}
|
||||
StreamStackEntry::QueueRequest(request);
|
||||
}, request->GetCommand());
|
||||
}
|
||||
|
||||
|
||||
@@ -146,15 +146,18 @@ namespace AZ
|
||||
DestroyDedicatedCache(request, args);
|
||||
return;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
|
||||
else
|
||||
{
|
||||
FlushCache(args.m_path);
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
|
||||
{
|
||||
FlushCache(args.m_path);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
|
||||
{
|
||||
FlushEntireCache();
|
||||
}
|
||||
StreamStackEntry::QueueRequest(request);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
|
||||
{
|
||||
FlushEntireCache();
|
||||
}
|
||||
StreamStackEntry::QueueRequest(request);
|
||||
}, request->GetCommand());
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -97,19 +97,22 @@ namespace AZ
|
||||
CancelRequest(request, args.m_target);
|
||||
return;
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
|
||||
else
|
||||
{
|
||||
FlushCache(args.m_path);
|
||||
if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData>)
|
||||
{
|
||||
FlushCache(args.m_path);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
|
||||
{
|
||||
FlushEntireCache();
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::ReportData>)
|
||||
{
|
||||
Report(args);
|
||||
}
|
||||
StreamStackEntry::QueueRequest(request);
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushAllData>)
|
||||
{
|
||||
FlushEntireCache();
|
||||
}
|
||||
else if constexpr (AZStd::is_same_v<Command, FileRequest::ReportData>)
|
||||
{
|
||||
Report(args);
|
||||
}
|
||||
StreamStackEntry::QueueRequest(request);
|
||||
}, request->GetCommand());
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +300,6 @@ namespace AZ
|
||||
context.Class<Uuid>("Uuid")->
|
||||
Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)->
|
||||
Attribute(AZ::Script::Attributes::Module, "math")->
|
||||
Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)->
|
||||
Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)->
|
||||
Attribute(AZ::Script::Attributes::ConstructorOverride, &Internal::ScriptUuidConstructor)->
|
||||
Attribute(AZ::Script::Attributes::GenericConstructorOverride, &Internal::UuidDefaultConstructor)->
|
||||
|
||||
@@ -18,11 +18,8 @@ namespace AZ
|
||||
{
|
||||
Quaternion CreateRandomQuaternion(SimpleLcgRandom& rng)
|
||||
{
|
||||
float u1 = rng.GetRandomFloat();
|
||||
float u2 = rng.GetRandomFloat();
|
||||
float u3 = rng.GetRandomFloat();
|
||||
float c1 = Sqrt(1.0f - u1);
|
||||
float c2 = Sqrt(u1);
|
||||
float x, y, z, w;
|
||||
SinCos(Constants::TwoPi * u2, x, y);
|
||||
SinCos(Constants::TwoPi * u3, z, w);
|
||||
|
||||
@@ -374,7 +374,7 @@ namespace AZ
|
||||
|
||||
targetForward.Normalize();
|
||||
|
||||
// Lumberyard is Z-up and is right-handed.
|
||||
// Open 3D Engine is Z-up and is right-handed.
|
||||
Vector3 up = Vector3::CreateAxisZ();
|
||||
|
||||
// We have a degenerate case if target forward is parallel to the up axis,
|
||||
@@ -391,7 +391,7 @@ namespace AZ
|
||||
up.Normalize();
|
||||
|
||||
// Passing in forwardAxis allows you to force a particular local-space axis to look
|
||||
// at the target point. In Lumberyard, the default is forward is along Y+.
|
||||
// at the target point. In Open 3D Engine, the default is forward is along Y+.
|
||||
switch (forwardAxis)
|
||||
{
|
||||
case Axis::XPositive:
|
||||
|
||||
@@ -426,7 +426,7 @@ namespace AZ
|
||||
Matrix4x4 Matrix4x4::CreateProjection(float fovY, float aspectRatio, float nearDist, float farDist)
|
||||
{
|
||||
// This section contains some notes about camera matrices and field of view, because there are some subtle differences
|
||||
// between the convention Lumberyard uses and what you might be used to from other software packages.
|
||||
// between the convention Open 3D Engine uses and what you might be used to from other software packages.
|
||||
// Our camera space has the camera looking down the *positive* z-axis, the x-axis points towards the left of the screen,
|
||||
// and the y-axis points towards the top of the screen.
|
||||
//
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -74,7 +74,6 @@ namespace AZ
|
||||
{
|
||||
behaviorContext->Class<Obb>()->
|
||||
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
|
||||
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::Preview)->
|
||||
Attribute(Script::Attributes::Storage, Script::Attributes::StorageType::Value)->
|
||||
Attribute(Script::Attributes::GenericConstructorOverride, &Internal::ObbDefaultConstructor)->
|
||||
Property("position", &Obb::GetPosition, &Obb::SetPosition)->
|
||||
@@ -155,7 +154,7 @@ namespace AZ
|
||||
return Obb::CreateFromPositionRotationAndHalfLengths(
|
||||
transform.TransformPoint(obb.GetPosition()),
|
||||
transform.GetRotation() * obb.GetRotation(),
|
||||
obb.GetHalfLengths()
|
||||
transform.GetScale() * obb.GetHalfLengths()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,9 +104,9 @@ namespace AZ
|
||||
// As one return value (hit point) is based on the other (hit time), for simplicity, the Lua implementation
|
||||
// just returns all three values: does the ray hit? When does it hit? Where does it hit?
|
||||
|
||||
if (!dc.IsClass<Vector3>(0) || !dc.IsClass<Vector3>(0))
|
||||
if (!dc.IsClass<Vector3>(0) || !dc.IsClass<Vector3>(1))
|
||||
{
|
||||
AZ_Error("Script", false, "ScriptPlane CastRay requires two ScriptVector3s as arguments.");
|
||||
AZ_Error("Script", false, "ScriptPlane IntersectSegment requires two ScriptVector3s as arguments.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -147,7 +147,6 @@ namespace AZ
|
||||
{
|
||||
behaviorContext->Class<Plane>()->
|
||||
Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)->
|
||||
Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)->
|
||||
Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)->
|
||||
Attribute(AZ::Script::Attributes::GenericConstructorOverride, &Internal::PlaneDefaultConstructor)->
|
||||
Method("ToString", &Internal::PlaneToString)->
|
||||
|
||||
@@ -53,7 +53,6 @@ namespace AZ
|
||||
if (auto behaviorContext = azrtti_cast<BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<PolygonPrism>()
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(Script::Attributes::Storage, Script::Attributes::StorageType::RuntimeOwn)
|
||||
->Property("height", BehaviorValueGetter(&PolygonPrism::m_height), nullptr)
|
||||
->Property("vertexContainer", BehaviorValueGetter(&PolygonPrism::m_vertexContainer), nullptr)
|
||||
|
||||
@@ -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)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,13 +111,11 @@ namespace AZ
|
||||
Property("segmentFraction", BehaviorValueProperty(&SplineAddress::m_segmentFraction));
|
||||
|
||||
behaviorContext->Class<PositionSplineQueryResult>()->
|
||||
Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)->
|
||||
Attribute(Script::Attributes::Storage, Script::Attributes::StorageType::Value)->
|
||||
Property("splineAddress", [](PositionSplineQueryResult* thisPtr) { return thisPtr->m_splineAddress; }, nullptr)->
|
||||
Property("distanceSq", [](PositionSplineQueryResult* thisPtr) { return thisPtr->m_distanceSq; }, nullptr);
|
||||
|
||||
behaviorContext->Class<RaySplineQueryResult>()->
|
||||
Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)->
|
||||
Attribute(Script::Attributes::Storage, Script::Attributes::StorageType::Value)->
|
||||
Property("splineAddress", [](RaySplineQueryResult* thisPtr) { return thisPtr->m_splineAddress; }, nullptr)->
|
||||
Property("distanceSq", [](RaySplineQueryResult* thisPtr) { return thisPtr->m_distanceSq; }, nullptr)->
|
||||
|
||||
@@ -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)->
|
||||
@@ -354,7 +355,7 @@ namespace AZ
|
||||
|
||||
targetForward.Normalize();
|
||||
|
||||
// Lumberyard is Z-up and is right-handed.
|
||||
// Open 3D Engine is Z-up and is right-handed.
|
||||
Vector3 up = Vector3::CreateAxisZ();
|
||||
|
||||
// We have a degenerate case if target forward is parallel to the up axis,
|
||||
@@ -371,7 +372,7 @@ namespace AZ
|
||||
up.Normalize();
|
||||
|
||||
// Passing in forwardAxis allows you to force a particular local-space axis to look
|
||||
// at the target point. In Lumberyard, the default is forward is along Y+.
|
||||
// at the target point. In Open 3D Engine, the default is forward is along Y+.
|
||||
switch (forwardAxis)
|
||||
{
|
||||
case Axis::XPositive:
|
||||
|
||||
@@ -38,6 +38,13 @@ namespace AZ
|
||||
bool CompareValueData(const void* lhs, const void* rhs) override;
|
||||
};
|
||||
|
||||
//! Limits for transform scale values.
|
||||
//! The scale should not be zero to avoid problems with inverting.
|
||||
//! @{
|
||||
static constexpr float MinTransformScale = 1e-2f;
|
||||
static constexpr float MaxTransformScale = 1e9f;
|
||||
//! @}
|
||||
|
||||
//! The basic transformation class, represented using a quaternion rotation, vector scale and vector translation.
|
||||
//! By design, cannot represent skew transformations.
|
||||
class Transform
|
||||
|
||||
@@ -167,14 +167,14 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Vector2::Vector2(const Vector3& source)
|
||||
Vector2::Vector2(const Vector3& source)
|
||||
: m_x(source.GetX())
|
||||
, m_y(source.GetY())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Vector2::Vector2(const Vector4& source)
|
||||
Vector2::Vector2(const Vector4& source)
|
||||
: m_x(source.GetX())
|
||||
, m_y(source.GetY())
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -720,9 +720,9 @@ namespace AZ
|
||||
StoragePolicyBase<Allocator>::Destroy(Base::GetModuleAllocatorInstance());
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE static bool IsReady()
|
||||
static bool IsReady()
|
||||
{
|
||||
return true;
|
||||
return Base::GetModuleAllocatorInstance().IsReady();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -707,7 +707,7 @@ PoolSchema::GarbageCollect()
|
||||
// occur exclusively in the destruction of the allocator.
|
||||
//
|
||||
// TODO: A better solution needs to be found for integrating back into mainline
|
||||
// Lumberyard.
|
||||
// Open 3D Engine.
|
||||
//m_impl->GarbageCollect();
|
||||
}
|
||||
|
||||
|
||||
@@ -31,4 +31,4 @@ namespace AZ
|
||||
return modulePath;
|
||||
}
|
||||
} // namespace Internal
|
||||
} // namespace AZ
|
||||
} // namespace AZ
|
||||
|
||||
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/PlatformId/PlatformDefaults.h>
|
||||
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
inline namespace PlatformDefaults
|
||||
{
|
||||
static const char* PlatformNames[PlatformId::NumPlatformIds] = { PlatformPC, PlatformES3, PlatformIOS, PlatformOSX, PlatformProvo, PlatformSalem, PlatformJasper, PlatformServer, PlatformAll, PlatformAllClient };
|
||||
|
||||
const char* PlatformIdToPalFolder(AZ::PlatformId platform)
|
||||
{
|
||||
#ifdef IOS
|
||||
#define AZ_REDEFINE_IOS_AT_END IOS
|
||||
#undef IOS
|
||||
#endif
|
||||
switch (platform)
|
||||
{
|
||||
case AZ::PC:
|
||||
return "PC";
|
||||
case AZ::ES3:
|
||||
return "Android";
|
||||
case AZ::IOS:
|
||||
return "iOS";
|
||||
case AZ::OSX:
|
||||
return "Mac";
|
||||
case AZ::PROVO:
|
||||
return "Provo";
|
||||
case AZ::SALEM:
|
||||
return "Salem";
|
||||
case AZ::JASPER:
|
||||
return "Jasper";
|
||||
case AZ::SERVER:
|
||||
return "Server";
|
||||
case AZ::ALL:
|
||||
case AZ::ALL_CLIENT:
|
||||
case AZ::NumPlatformIds:
|
||||
case AZ::Invalid:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
#ifdef AZ_REDEFINE_IOS_AT_END
|
||||
#define IOS AZ_REDEFINE_IOS_AT_END
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform)
|
||||
{
|
||||
if (osPlatform == PlatformCodeNameWindows || osPlatform == PlatformCodeNameLinux)
|
||||
{
|
||||
return PlatformPC;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameMac)
|
||||
{
|
||||
return PlatformOSX;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameAndroid)
|
||||
{
|
||||
return PlatformES3;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameiOS)
|
||||
{
|
||||
return PlatformIOS;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameProvo)
|
||||
{
|
||||
return PlatformProvo;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameSalem)
|
||||
{
|
||||
return PlatformSalem;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameJasper)
|
||||
{
|
||||
return PlatformJasper;
|
||||
}
|
||||
|
||||
AZ_Error("PlatformDefault", false, R"(Supplied OS platform "%.*s" does not have a corresponding default asset platform)",
|
||||
aznumeric_cast<int>(osPlatform.size()), osPlatform.data());
|
||||
return "";
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlagFromPlatformIndex(PlatformId platformIndex)
|
||||
{
|
||||
if (platformIndex < 0 || platformIndex > PlatformId::NumPlatformIds)
|
||||
{
|
||||
return PlatformFlags::Platform_NONE;
|
||||
}
|
||||
if (platformIndex == PlatformId::ALL)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL;
|
||||
}
|
||||
if (platformIndex == PlatformId::ALL_CLIENT)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL_CLIENT;
|
||||
}
|
||||
return static_cast<PlatformFlags>(1 << platformIndex);
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatforms(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platforms;
|
||||
for (int platformNum = 0; platformNum < PlatformId::NumPlatformIds; ++platformNum)
|
||||
{
|
||||
const bool isAllPlatforms = PlatformId::ALL == static_cast<PlatformId>(platformNum)
|
||||
&& ((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE);
|
||||
|
||||
const bool isAllClientPlatforms = PlatformId::ALL_CLIENT == static_cast<PlatformId>(platformNum)
|
||||
&& ((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE);
|
||||
|
||||
if (isAllPlatforms || isAllClientPlatforms
|
||||
|| (platformFlags & static_cast<PlatformFlags>(1 << platformNum)) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
platforms.push_back(PlatformNames[platformNum]);
|
||||
}
|
||||
}
|
||||
|
||||
return platforms;
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformsInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
return GetPlatforms(GetPlatformFlagsInterpreted(platformFlags));
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndices(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> platformIndices;
|
||||
for (int i = 0; i < PlatformId::NumPlatformIds; i++)
|
||||
{
|
||||
PlatformId index = static_cast<PlatformId>(i);
|
||||
if ((GetPlatformFlagFromPlatformIndex(index) & platformFlags) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
platformIndices.emplace_back(index);
|
||||
}
|
||||
}
|
||||
return platformIndices;
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndicesInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
return GetPlatformIndices(GetPlatformFlagsInterpreted(platformFlags));
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlag(AZStd::string_view platform)
|
||||
{
|
||||
int platformIndex = GetPlatformIndexFromName(platform);
|
||||
if (platformIndex == PlatformId::Invalid)
|
||||
{
|
||||
AZ_Error("PlatformDefault", false, "Invalid Platform ( %.*s ).\n", static_cast<int>(platform.length()), platform.data());
|
||||
return PlatformFlags::Platform_NONE;
|
||||
}
|
||||
|
||||
if (platformIndex == PlatformId::ALL)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL;
|
||||
}
|
||||
|
||||
if (platformIndex == PlatformId::ALL_CLIENT)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL_CLIENT;
|
||||
}
|
||||
|
||||
return static_cast<PlatformFlags>(1 << platformIndex);
|
||||
}
|
||||
|
||||
const char* PlatformHelper::GetPlatformName(PlatformId platform)
|
||||
{
|
||||
if (platform < 0 || platform > PlatformId::NumPlatformIds)
|
||||
{
|
||||
return "invalid";
|
||||
}
|
||||
return PlatformNames[platform];
|
||||
}
|
||||
|
||||
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformId)
|
||||
{
|
||||
PlatformId platform = GetPlatformIdFromName(platformId);
|
||||
AZ_Assert(platform != PlatformId::Invalid, "Unsupported Platform ID: %.*s", static_cast<int>(platformId.length()), platformId.data());
|
||||
AppendPlatformCodeNames(platformCodes, platform);
|
||||
}
|
||||
|
||||
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId)
|
||||
{
|
||||
// The IOS SDK has a macro that defines IOS as 1 which causes the enum below to be incorrectly converted to "PlatformId::1".
|
||||
#pragma push_macro("IOS")
|
||||
#undef IOS
|
||||
// To reduce work the Asset Processor groups assets that can be shared between hardware platforms together. For this
|
||||
// reason "PC" can for instance cover both the Windows and Linux platforms and "IOS" can cover AppleTV and iOS.
|
||||
switch (platformId)
|
||||
{
|
||||
case PlatformId::PC:
|
||||
platformCodes.emplace_back(PlatformCodeNameWindows);
|
||||
platformCodes.emplace_back(PlatformCodeNameLinux);
|
||||
break;
|
||||
case PlatformId::ES3:
|
||||
platformCodes.emplace_back(PlatformCodeNameAndroid);
|
||||
break;
|
||||
case PlatformId::IOS:
|
||||
platformCodes.emplace_back(PlatformCodeNameiOS);
|
||||
break;
|
||||
case PlatformId::OSX:
|
||||
platformCodes.emplace_back(PlatformCodeNameMac);
|
||||
break;
|
||||
case PlatformId::PROVO:
|
||||
platformCodes.emplace_back(PlatformCodeNameProvo);
|
||||
break;
|
||||
case PlatformId::SALEM:
|
||||
platformCodes.emplace_back(PlatformCodeNameSalem);
|
||||
break;
|
||||
case PlatformId::JASPER:
|
||||
platformCodes.emplace_back(PlatformCodeNameJasper);
|
||||
break;
|
||||
case PlatformId::SERVER:
|
||||
// Server is not a hardware platform
|
||||
break;
|
||||
default:
|
||||
AZ_Assert(false, "Unsupported Platform ID: %i", platformId);
|
||||
break;
|
||||
}
|
||||
#pragma pop_macro("IOS")
|
||||
}
|
||||
|
||||
int PlatformHelper::GetPlatformIndexFromName(AZStd::string_view platformName)
|
||||
{
|
||||
for (int idx = 0; idx < PlatformId::NumPlatformIds; idx++)
|
||||
{
|
||||
if (platformName == PlatformNames[idx])
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
return PlatformId::Invalid;
|
||||
}
|
||||
|
||||
PlatformId PlatformHelper::GetPlatformIdFromName(AZStd::string_view platformName)
|
||||
{
|
||||
return aznumeric_caster(GetPlatformIndexFromName(platformName));
|
||||
}
|
||||
|
||||
AssetPlatformCombinedString PlatformHelper::GetCommaSeparatedPlatformList(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platformNames = GetPlatforms(platformFlags);
|
||||
AssetPlatformCombinedString platformsString;
|
||||
AZ::StringFunc::Join(platformsString, platformNames.begin(), platformNames.end(), ", ");
|
||||
return platformsString;
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlagsInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
PlatformFlags returnFlags = PlatformFlags::Platform_NONE;
|
||||
|
||||
if ((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
for (int i = 0; i < NumPlatforms; ++i)
|
||||
{
|
||||
auto platformId = static_cast<PlatformId>(i);
|
||||
|
||||
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT)
|
||||
{
|
||||
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
for (int i = 0; i < NumPlatforms; ++i)
|
||||
{
|
||||
auto platformId = static_cast<PlatformId>(i);
|
||||
|
||||
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT && platformId != PlatformId::SERVER)
|
||||
{
|
||||
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnFlags = platformFlags;
|
||||
}
|
||||
|
||||
return returnFlags;
|
||||
}
|
||||
|
||||
bool PlatformHelper::IsSpecialPlatform(PlatformFlags platformFlags)
|
||||
{
|
||||
return (platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE
|
||||
|| (platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE;
|
||||
}
|
||||
|
||||
bool HasFlagHelper(PlatformFlags flags, PlatformFlags checkPlatform)
|
||||
{
|
||||
return (flags & checkPlatform) == checkPlatform;
|
||||
}
|
||||
|
||||
|
||||
bool PlatformHelper::HasPlatformFlag(PlatformFlags flags, PlatformId checkPlatform)
|
||||
{
|
||||
// If checkPlatform contains any kind of invalid id, just exit out here
|
||||
if (checkPlatform == PlatformId::Invalid || checkPlatform == NumPlatforms)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ALL_CLIENT + SERVER = ALL
|
||||
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT | PlatformFlags::Platform_SERVER))
|
||||
{
|
||||
flags = PlatformFlags::Platform_ALL;
|
||||
}
|
||||
|
||||
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL))
|
||||
{
|
||||
// It doesn't matter what checkPlatform is set to in this case, just return true
|
||||
return true;
|
||||
}
|
||||
|
||||
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT))
|
||||
{
|
||||
return checkPlatform != PlatformId::SERVER;
|
||||
}
|
||||
|
||||
return HasFlagHelper(flags, GetPlatformFlagFromPlatformIndex(checkPlatform));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Preprocessor/Enum.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
// On IOS builds IOS will be defined and interfere with the below enums
|
||||
#pragma push_macro("IOS")
|
||||
#undef IOS
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
inline namespace PlatformDefaults
|
||||
{
|
||||
constexpr char PlatformPC[] = "pc";
|
||||
constexpr char PlatformES3[] = "es3";
|
||||
constexpr char PlatformIOS[] = "ios";
|
||||
constexpr char PlatformOSX[] = "osx_gl";
|
||||
constexpr char PlatformProvo[] = "provo";
|
||||
constexpr char PlatformSalem[] = "salem";
|
||||
constexpr char PlatformJasper[] = "jasper";
|
||||
constexpr char PlatformServer[] = "server";
|
||||
|
||||
constexpr char PlatformCodeNameWindows[] = "Windows";
|
||||
constexpr char PlatformCodeNameLinux[] = "Linux";
|
||||
constexpr char PlatformCodeNameAndroid[] = "Android";
|
||||
constexpr char PlatformCodeNameiOS[] = "iOS";
|
||||
constexpr char PlatformCodeNameMac[] = "Mac";
|
||||
constexpr char PlatformCodeNameProvo[] = "Provo";
|
||||
constexpr char PlatformCodeNameSalem[] = "Salem";
|
||||
constexpr char PlatformCodeNameJasper[] = "Jasper";
|
||||
constexpr char PlatformAll[] = "all";
|
||||
constexpr char PlatformAllClient[] = "all_client";
|
||||
|
||||
// Used for the capacity of a fixed vector to store the code names of platforms
|
||||
// The value needs to be higher than the number of unique OS platforms that are supported(at this time 8)
|
||||
constexpr size_t MaxPlatformCodeNames = 16;
|
||||
|
||||
//! This platform enum have platform values in sequence and can also be used to get the platform count.
|
||||
AZ_ENUM_WITH_UNDERLYING_TYPE(PlatformId, int,
|
||||
(Invalid, -1),
|
||||
PC,
|
||||
ES3,
|
||||
IOS,
|
||||
OSX,
|
||||
PROVO,
|
||||
SALEM,
|
||||
JASPER,
|
||||
SERVER, // Corresponds to the customer's flavor of "server" which could be windows, ubuntu, etc
|
||||
ALL,
|
||||
ALL_CLIENT,
|
||||
|
||||
// Add new platforms above this
|
||||
NumPlatformIds
|
||||
);
|
||||
constexpr int NumClientPlatforms = 7;
|
||||
constexpr int NumPlatforms = NumClientPlatforms + 1; // 1 "Server" platform currently
|
||||
enum class PlatformFlags : AZ::u32
|
||||
{
|
||||
Platform_NONE = 0x00,
|
||||
Platform_PC = 1 << PlatformId::PC,
|
||||
Platform_ES3 = 1 << PlatformId::ES3,
|
||||
Platform_IOS = 1 << PlatformId::IOS,
|
||||
Platform_OSX = 1 << PlatformId::OSX,
|
||||
Platform_PROVO = 1 << PlatformId::PROVO,
|
||||
Platform_SALEM = 1 << PlatformId::SALEM,
|
||||
Platform_JASPER = 1 << PlatformId::JASPER,
|
||||
Platform_SERVER = 1 << PlatformId::SERVER,
|
||||
|
||||
// A special platform that will always correspond to all platforms, even if new ones are added
|
||||
Platform_ALL = 1ULL << 30,
|
||||
|
||||
// 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_ES3 | Platform_IOS | Platform_OSX | Platform_PROVO | Platform_SALEM | Platform_JASPER | Platform_SERVER,
|
||||
};
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(PlatformFlags);
|
||||
|
||||
// 32 characters should be more than enough to store a platform name
|
||||
using AssetPlatformFixedString = AZStd::fixed_string<32>;
|
||||
// Fixed string which can store a comma separated list of platforms names
|
||||
// Additional byte is added to take into account the comma
|
||||
using AssetPlatformCombinedString = AZStd::fixed_string < (AssetPlatformFixedString{}.max_size() + 1)* PlatformId::NumPlatformIds > ;
|
||||
|
||||
const char* PlatformIdToPalFolder(PlatformId platform);
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform);
|
||||
|
||||
//! Platform Helper is an utility class that can be used to retrieve platform related information
|
||||
class PlatformHelper
|
||||
{
|
||||
public:
|
||||
|
||||
//! Given a platformIndex returns the platform name
|
||||
static const char* GetPlatformName(PlatformId platform);
|
||||
|
||||
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
|
||||
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformName);
|
||||
|
||||
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
|
||||
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId);
|
||||
|
||||
//! Given a platform name returns a platform index.
|
||||
//! If the platform is not found, the method returns -1.
|
||||
static int GetPlatformIndexFromName(AZStd::string_view platformName);
|
||||
|
||||
//! Given a platform name returns a platform id.
|
||||
//! If the platform is not found, the method returns -1.
|
||||
static PlatformId GetPlatformIdFromName(AZStd::string_view platformName);
|
||||
|
||||
//! Given a platformIndex returns the platformFlags
|
||||
static PlatformFlags GetPlatformFlagFromPlatformIndex(PlatformId platform);
|
||||
|
||||
//! Given a platformFlags returns all the platform identifiers that are set.
|
||||
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatforms(PlatformFlags platformFlags);
|
||||
//! Given a platformFlags returns all the platform identifiers that are set, with special flags interpreted. Do not use the result for saving
|
||||
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatformsInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Given a platformFlags return a list of PlatformId indices
|
||||
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndices(PlatformFlags platformFlags);
|
||||
//! Given a platformFlags return a list of PlatformId indices, with special flags interpreted. Do not use the result for saving
|
||||
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndicesInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Given a platform identifier returns its corresponding platform flag.
|
||||
static PlatformFlags GetPlatformFlag(AZStd::string_view platform);
|
||||
|
||||
//! Given any platformFlags returns a string listing the input platforms
|
||||
static AssetPlatformCombinedString GetCommaSeparatedPlatformList(PlatformFlags platformFlags);
|
||||
|
||||
//! If platformFlags contains any special flags, they are removed and replaced with the normal flags they represent
|
||||
static PlatformFlags GetPlatformFlagsInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Returns true if platformFlags contains any special flags
|
||||
static bool IsSpecialPlatform(PlatformFlags platformFlags);
|
||||
|
||||
//! Returns true if platformFlags has checkPlatform flag set.
|
||||
static bool HasPlatformFlag(PlatformFlags platformFlags, PlatformId checkPlatform);
|
||||
};
|
||||
}
|
||||
}
|
||||
#pragma pop_macro("IOS")
|
||||
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user