Integrating latest 47acbe8

This commit is contained in:
alexpete
2021-03-25 13:57:57 -07:00
parent 448c549698
commit 75dc720198
10312 changed files with 2711566 additions and 671451 deletions
@@ -0,0 +1,254 @@
/*
* 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/Asset/AssetManagerBus.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Execution/ExecutionBus.h>
#include <ScriptCanvas/Execution/ExecutionPerformanceTimer.h>
#include <ScriptCanvas/PerformanceStatistician.h>
#include <ScriptCanvas/PerformanceTracker.h>
#include <ScriptCanvas/SystemComponent.h>
namespace ScriptCanvas
{
namespace Execution
{
void PerformanceStatistics::CalculateSecondary()
{
scriptCostPercent = aznumeric_cast<double>(report.tracking.timing.totalTime) / aznumeric_cast<double>(duration);
}
AZStd::string ToConsoleString(const PerformanceStatistics& stats)
{
AZStd::string consoleString("\n");
const double initializingMs = aznumeric_caster(stats.report.tracking.timing.initializationTime / 1000.0);
const double executionMs = aznumeric_caster(stats.report.tracking.timing.executionTime / 1000.0);
const double latentMs = aznumeric_caster(stats.report.tracking.timing.latentTime / 1000.0);
const double totalMs = aznumeric_caster(stats.report.tracking.timing.totalTime / 1000.0);
consoleString += "[ INITIALIZE] ";
consoleString += AZStd::string::format("%7.3f ms \n", initializingMs);
consoleString += "[ EXECUTION] ";
consoleString += AZStd::string::format("%7.3f ms \n", executionMs);
consoleString += "[ LATENT] ";
consoleString += AZStd::string::format("%7.3f ms \n", latentMs);
consoleString += "[ TOTAL] ";
consoleString += AZStd::string::format("%7.3f ms \n", totalMs);
consoleString += "[SCRIPT COST] ";
consoleString += AZStd::string::format("%7.4f%% of duration \n", stats.scriptCostPercent);
return consoleString;
}
PerformanceStatistician::PerformanceStatistician()
{
PerformanceStatisticsEBus::Handler::BusConnect();
}
void PerformanceStatistician::ClearSnaphotStatistics()
{
m_executedScripts.clear();
auto perfTracker = SystemComponent::ModPerformanceTracker();
perfTracker->ClearGlobalReport();
perfTracker->ClearSnapshotReport();
}
void PerformanceStatistician::ClearTrackingState()
{
m_trackingState = TrackingState::None;
if (AZ::SystemTickBus::Handler::BusIsConnected())
{
AZ::SystemTickBus::Handler::BusDisconnect();
}
}
void PerformanceStatistician::ConnectToSystemTickBus()
{
if (!AZ::SystemTickBus::Handler::BusIsConnected())
{
AZ::SystemTickBus::Handler::BusConnect();
}
}
AZStd::vector<AZStd::string> PerformanceStatistician::GetExecutedScriptsSinceLastSnapshot() const
{
AZStd::vector<AZStd::string> scripts;
scripts.reserve(m_executedScripts.size());
for (auto& iter : m_executedScripts)
{
scripts.push_back(iter.second);
}
return scripts;
}
const PerformanceStatistics& PerformanceStatistician::GetStatistics() const
{
return m_accumulatedStats;
}
void PerformanceStatistician::OnStartTrackingRequested()
{
m_accumulatedStats.tickCount = 0;
m_accumulatedTickCountRemaining;
m_accumulatedStartTime = AZStd::chrono::system_clock::now();
}
void PerformanceStatistician::OnSystemTick()
{
switch (m_trackingState)
{
case TrackingState::AccumulatedInProgress:
UpdateTickCounts();
break;
case TrackingState::AccumulatedStartRequested:
OnStartTrackingRequested();
m_trackingState = TrackingState::AccumulatedInProgress;
break;
case TrackingState::AccumulatedStopRequested:
UpdateAccumulatedTime();
UpdateStatisticsFromTracker();
UpdateAccumulatedStatistics();
ClearTrackingState();
break;
case TrackingState::PerFrameInProgress:
UpdateTickCounts();
UpdateStatisticsFromTracker();
break;
case TrackingState::PerFrameStartRequested:
OnStartTrackingRequested();
m_trackingState = TrackingState::PerFrameInProgress;
break;
case TrackingState::PerFrameStopRequested:
UpdateAccumulatedTime();
UpdateStatisticsFromTracker();
ClearTrackingState();
break;
default:
break;
}
}
void PerformanceStatistician::Reflect(AZ::ReflectContext* reflectContext)
{
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext))
{
behaviorContext->EBus<PerformanceStatisticsEBus>("PerformanceStatisticsEBus")
->Event("ClearSnaphotStatistics", &PerformanceStatisticsEBus::Events::ClearSnaphotStatistics)
->Event("TrackAccumulatedStart", &PerformanceStatisticsEBus::Events::TrackAccumulatedStart)
->Event("TrackAccumulatedStop", &PerformanceStatisticsEBus::Events::TrackAccumulatedStop)
->Event("TrackPerFrameStart", &PerformanceStatisticsEBus::Events::TrackPerFrameStart)
->Event("TrackPerFrameStop", &PerformanceStatisticsEBus::Events::TrackPerFrameStop)
;
}
}
void PerformanceStatistician::TrackAccumulatedStart(AZ::s32 tickCount)
{
if (m_trackingState != TrackingState::AccumulatedStartRequested || m_accumulatedTickCountRemaining != tickCount)
{
m_trackingState = TrackingState::AccumulatedStartRequested;
m_accumulatedTickCountRemaining = tickCount;
ConnectToSystemTickBus();
}
}
void PerformanceStatistician::TrackAccumulatedStop()
{
if (m_trackingState == TrackingState::AccumulatedInProgress)
{
m_trackingState = TrackingState::AccumulatedStopRequested;
}
}
void PerformanceStatistician::TrackPerFrameStart()
{
if (m_trackingState != TrackingState::PerFrameInProgress)
{
m_trackingState = TrackingState::PerFrameStartRequested;
ConnectToSystemTickBus();
}
}
void PerformanceStatistician::TrackPerFrameStop()
{
if (m_trackingState == TrackingState::PerFrameInProgress || m_trackingState == TrackingState::AccumulatedStartRequested)
{
m_trackingState = TrackingState::PerFrameStopRequested;
AZ::SystemTickBus::Handler::BusConnect();
}
}
void PerformanceStatistician::UpdateAccumulatedStatistics()
{
m_accumulatedStats.report = SystemComponent::ModPerformanceTracker()->GetGlobalReportFull();
m_accumulatedStats.CalculateSecondary();
AZ_TracePrintf("ScriptCanvas", "Global Performance Report:\n%s", ToConsoleString(m_accumulatedStats).c_str());
}
void PerformanceStatistician::UpdateAccumulatedTime()
{
m_accumulatedStats.duration = AZStd::chrono::microseconds(AZStd::chrono::system_clock::now() - m_accumulatedStartTime).count();
}
void PerformanceStatistician::UpdateStatisticsFromTracker()
{
auto perfTracker = SystemComponent::ModPerformanceTracker();
perfTracker->CalculateReports();
const PerformanceReport& snapShotReport = perfTracker->GetSnapshotReportFull();
for (auto& snapshotIter : snapShotReport.byAsset)
{
auto iter = m_executedScripts.find(snapshotIter.first);
if (iter == m_executedScripts.end())
{
AZ::Data::AssetInfo info;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(info, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, snapshotIter.first);
if (info.m_assetType == azrtti_typeid<ScriptCanvas::RuntimeAsset>())
{
AZStd::string fileName;
if (AZ::StringFunc::Path::GetFileName(info.m_relativePath.c_str(), fileName))
{
m_executedScripts.insert({ snapshotIter.first, fileName });
}
}
}
}
}
void PerformanceStatistician::UpdateTickCounts()
{
++m_accumulatedStats.tickCount;
--m_accumulatedTickCountRemaining;
if (m_trackingState == TrackingState::AccumulatedInProgress && m_accumulatedTickCountRemaining == 0)
{
m_trackingState = TrackingState::AccumulatedStopRequested;
}
}
}
}
@@ -0,0 +1,215 @@
/*
* 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 <ScriptCanvas/Execution/ExecutionPerformanceTimer.h>
#include <ScriptCanvas/PerformanceTracker.h>
namespace ScriptCanvas
{
namespace Execution
{
PerformanceTracker::PerformanceTracker()
{}
PerformanceTracker::~PerformanceTracker()
{
AZStd::lock_guard lock(m_activeTimerMutex);
for (auto iter : m_activeTimers)
{
delete iter.second;
}
m_activeTimers.clear();
for (auto iter : m_timersByAsset)
{
delete iter.second;
}
m_timersByAsset.clear();
}
void PerformanceTracker::CalculateReports()
{
AZStd::lock_guard lock(m_activeTimerMutex);
m_snapshotReport.tracking.activationCount += aznumeric_cast<AZ::u32>(m_activeTimers.size());
m_globalReport.tracking.activationCount += aznumeric_cast<AZ::u32>(m_activeTimers.size());
for (auto& iter : m_activeTimers)
{
const auto report = iter.second->GetReport();
m_snapshotReport.tracking.timing += report;
m_globalReport.tracking.timing += report;
delete iter.second;
}
m_activeTimers.clear();
for (auto& iter : m_timersByAsset)
{
const auto report = iter.second->timer.GetReport();
auto& snapshotByAssetReport = *ModOrCreateReport(m_snapshotReport.byAsset, iter.first);
auto& globalByAssetReport = *ModOrCreateReport(m_globalReport.byAsset, iter.first);
snapshotByAssetReport.timing += report;
snapshotByAssetReport.activationCount += iter.second->assetActivationCount;
globalByAssetReport.timing += report;
globalByAssetReport.activationCount += iter.second->assetActivationCount;
delete iter.second;
}
m_timersByAsset.clear();
m_lastCapturedSnapshot = m_snapshotReport;
m_lastCapturedGlobal = m_globalReport;
m_snapshotReport = {};
}
void PerformanceTracker::ClearGlobalReport()
{
AZStd::lock_guard lock(m_activeTimerMutex);
m_globalReport = {};
}
void PerformanceTracker::ClearSnapshotReport()
{
AZStd::lock_guard lock(m_activeTimerMutex);
m_snapshotReport = {};
}
PerformanceTimer* PerformanceTracker::CreateTimer(PerformanceKey key)
{
AZStd::lock_guard lock(m_activeTimerMutex);
return m_activeTimers.insert({ key, aznew PerformanceTimer() }).first->second;
}
void PerformanceTracker::FinalizeReport(PerformanceKey key, const AZ::Data::AssetId& assetId)
{
AZStd::lock_guard lock(m_activeTimerMutex);
auto iter = m_activeTimers.find(key);
if (iter != m_activeTimers.end())
{
PerformanceTimer* timer = iter->second;
auto report = timer->GetReport();
auto& globalByAssetReport = *ModOrCreateReport(m_globalReport.byAsset, assetId);
auto& snapshotByAssetReport = *ModOrCreateReport(m_snapshotReport.byAsset, assetId);
snapshotByAssetReport.timing += report;
globalByAssetReport.timing += report;
m_snapshotReport.tracking.timing += report;
m_globalReport.tracking.timing += report;
m_activeTimers.erase(iter);
delete timer;
}
}
PerformanceTracker::AssetTimer* PerformanceTracker::GetOrCreateTimer(const AZ::Data::AssetId& key)
{
AZStd::lock_guard lock(m_activeTimerMutex);
auto iter = m_timersByAsset.find(key);
if (iter != m_timersByAsset.end())
{
return iter->second;
}
else
{
return m_timersByAsset.insert({ key, aznew PerformanceTracker::AssetTimer() }).first->second;
}
}
PerformanceTimer* PerformanceTracker::GetOrCreateTimer(PerformanceKey key)
{
AZStd::lock_guard lock(m_activeTimerMutex);
auto iter = m_activeTimers.find(key);
if (iter != m_activeTimers.end())
{
return iter->second;
}
else
{
return m_activeTimers.insert({ key, aznew PerformanceTimer() }).first->second;
}
}
PerformanceTrackingReport PerformanceTracker::GetGlobalReport() const
{
return m_lastCapturedGlobal.tracking;
}
PerformanceTrackingReport PerformanceTracker::GetGlobalReportByAsset(const AZ::Data::AssetId& assetId) const
{
return GetReportByAsset(m_lastCapturedGlobal.byAsset, assetId);
}
const PerformanceReport& PerformanceTracker::GetGlobalReportFull() const
{
return m_globalReport;
}
PerformanceTrackingReport PerformanceTracker::GetReportByAsset(const PerformanceReportByAsset& reports, AZ::Data::AssetId key)
{
auto iter = reports.find(key);
return iter != reports.end() ? iter->second : PerformanceTrackingReport{};
}
PerformanceTrackingReport PerformanceTracker::GetSnapshotReport() const
{
return m_lastCapturedSnapshot.tracking;
}
PerformanceTrackingReport PerformanceTracker::GetSnapshotReportByAsset(const AZ::Data::AssetId& assetId) const
{
return GetReportByAsset(m_lastCapturedSnapshot.byAsset, assetId);
}
const PerformanceReport& PerformanceTracker::GetSnapshotReportFull() const
{
return m_lastCapturedSnapshot;
}
PerformanceTrackingReport* PerformanceTracker::ModOrCreateReport(PerformanceReportByAsset& reports, AZ::Data::AssetId key)
{
auto iter = reports.find(key);
if (iter != reports.end())
{
return &iter->second;
}
else
{
return &reports.insert({ key, PerformanceTrackingReport() }).first->second;
}
}
void PerformanceTracker::ReportExecutionTime(PerformanceKey key, const AZ::Data::AssetId& assetId, AZStd::sys_time_t time)
{
GetOrCreateTimer(key)->AddExecutionTime(time);
GetOrCreateTimer(assetId)->timer.AddExecutionTime(time);
}
void PerformanceTracker::ReportLatentTime(PerformanceKey key, const AZ::Data::AssetId& assetId, AZStd::sys_time_t time)
{
GetOrCreateTimer(key)->AddLatentTime(time);
GetOrCreateTimer(assetId)->timer.AddLatentTime(time);
}
void PerformanceTracker::ReportInitializationTime(PerformanceKey key, const AZ::Data::AssetId& assetId, AZStd::sys_time_t time)
{
CreateTimer(key)->AddInitializationTime(time);
AssetTimer* assetTimer = GetOrCreateTimer(assetId);
assetTimer->timer.AddInitializationTime(time);
++(assetTimer->assetActivationCount);
}
}
}
@@ -47,7 +47,7 @@ namespace ScriptCanvas
ScriptCanvas::Node::CreateDescriptor(),
ScriptCanvas::Debugger::ServiceComponent::CreateDescriptor(),
ScriptCanvas::Graph::CreateDescriptor(),
ScriptCanvas::ScriptCanvasFunctionDataComponent::CreateDescriptor(),
ScriptCanvasEditor::ScriptCanvasFunctionDataComponent::CreateDescriptor(),
ScriptCanvas::PureData::CreateDescriptor(),
ScriptCanvas::GraphVariableManagerComponent::CreateDescriptor(),
ScriptCanvas::RuntimeComponent::CreateDescriptor(),
@@ -79,4 +79,4 @@ namespace ScriptCanvas
azrtti_typeid<ScriptCanvas::Debugger::ServiceComponent>(),
};
}
}
}
@@ -56,6 +56,6 @@ namespace ScriptCanvas
}
}
AZ_DECLARE_MODULE_CLASS(Gem_ScriptCanvasGem, ScriptCanvas::ScriptCanvasModule)
AZ_DECLARE_MODULE_CLASS(Gem_ScriptCanvas, ScriptCanvas::ScriptCanvasModule)
#endif // !SCRIPTCANVAS_EDITOR
+126 -10
View File
@@ -10,27 +10,40 @@
*
*/
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/Utils.h>
#include <iostream>
#include <AzCore/Component/EntityUtils.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/Utils.h>
#include <Libraries/Libraries.h>
#include <ScriptCanvas/Core/Node.h>
#include <ScriptCanvas/Core/Contract.h>
#include <ScriptCanvas/Core/Slot.h>
#include <ScriptCanvas/Core/Graph.h>
#include <ScriptCanvas/Core/Node.h>
#include <ScriptCanvas/Core/Nodeable.h>
#include <ScriptCanvas/Core/Slot.h>
#include <ScriptCanvas/Data/DataRegistry.h>
#include <ScriptCanvas/Execution/ExecutionPerformanceTimer.h>
#include <ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.h>
#include <ScriptCanvas/Execution/RuntimeComponent.h>
#include <ScriptCanvas/Variable/GraphVariableManagerComponent.h>
#include <ScriptCanvas/SystemComponent.h>
#include <ScriptCanvas/Variable/GraphVariableManagerComponent.h>
#if defined(SC_EXECUTION_TRACE_ENABLED)
#include <ScriptCanvas/Asset/ExecutionLogAsset.h>
#endif
namespace
namespace ScriptCanvasSystemComponentCpp
{
#if !defined(_RELEASE) && !defined(PERFORMANCE_BUILD)
const int k_infiniteLoopDetectionMaxIterations = 3000;
const int k_maxHandlerStackDepth = 25;
#else
const int k_infiniteLoopDetectionMaxIterations = 10000;
const int k_maxHandlerStackDepth = 100;
#endif
bool IsDeprecated(const AZ::AttributeArray& attributes)
{
bool isDeprecated{};
@@ -42,13 +55,14 @@ namespace
return isDeprecated;
}
}
namespace ScriptCanvas
{
void SystemComponent::Reflect(AZ::ReflectContext* context)
{
Nodeable::Reflect(context);
ReflectLibraries(context);
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
@@ -58,6 +72,7 @@ namespace ScriptCanvas
// ScriptCanvas avoids a use dependency on the AssetBuilderSDK. Therefore the Crc is used directly to register this component with the Gem builder
->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector<AZ::Crc32>({ AZ_CRC("AssetBuilder", 0xc739c7d7) }))
->Field("m_infiniteLoopDetectionMaxIterations", &SystemComponent::m_infiniteLoopDetectionMaxIterations)
->Field("maxHandlerStackDepth", &SystemComponent::m_maxHandlerStackDepth)
;
if (AZ::EditContext* ec = serialize->GetEditContext())
@@ -68,6 +83,8 @@ namespace ScriptCanvas
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
->DataElement(AZ::Edit::UIHandlers::Default, &SystemComponent::m_infiniteLoopDetectionMaxIterations, "Infinite Loop Protection Max Iterations", "Script Canvas will avoid infinite loops by detecting potentially re-entrant conditions that execute up to this number of iterations.")
->DataElement(AZ::Edit::UIHandlers::Default, &SystemComponent::m_maxHandlerStackDepth, "Max Handler Stack Depth", "Script Canvas will avoid infinite loops at run-time by detecting sending Ebus Events while handling said Events. This limits the stack depth of the broadcast.")
->Attribute(AZ::Edit::Attributes::Min, 1000) // Safeguard user given value is valid
;
}
}
@@ -91,6 +108,9 @@ namespace ScriptCanvas
void SystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required)
{
// \todo configure the application to require these services
// required.push_back(AZ_CRC("AssetDatabaseService", 0x3abf5601));
// required.push_back(AZ_CRC("ScriptService", 0x787235ab));
}
void SystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
@@ -100,6 +120,9 @@ namespace ScriptCanvas
void SystemComponent::Init()
{
RegisterCreatableTypes();
m_infiniteLoopDetectionMaxIterations = ScriptCanvasSystemComponentCpp::k_infiniteLoopDetectionMaxIterations;
m_maxHandlerStackDepth = ScriptCanvasSystemComponentCpp::k_maxHandlerStackDepth;
}
void SystemComponent::Activate()
@@ -111,12 +134,50 @@ namespace ScriptCanvas
{
AZ::BehaviorContextBus::Handler::BusConnect(behaviorContext);
}
if (IsAnyScriptInterpreted()) // or if is the editor...
{
Execution::ActivateInterpreted();
}
SafeRegisterPerformanceTracker();
}
void SystemComponent::Deactivate()
{
AZ::BehaviorContextBus::Handler::BusDisconnect();
SystemRequestBus::Handler::BusDisconnect();
ModPerformanceTracker()->CalculateReports();
Execution::PerformanceTrackingReport report = ModPerformanceTracker()->GetGlobalReport();
const double ready = aznumeric_caster(report.timing.initializationTime);
const double instant = aznumeric_caster(report.timing.executionTime);
const double latent = aznumeric_caster(report.timing.latentTime);
const double total = aznumeric_caster(report.timing.totalTime);
std::cerr << "Global ScriptCanvas Performance Report:\n";
std::cerr << "[ INITIALIZE] " << AZStd::string::format("%7.3f ms \n", ready / 1000.0).c_str();
std::cerr << "[ EXECUTION] " << AZStd::string::format("%7.3f ms \n", instant / 1000.0).c_str();
std::cerr << "[ LATENT] " << AZStd::string::format("%7.3f ms \n", latent / 1000.0).c_str();
std::cerr << "[ TOTAL] " << AZStd::string::format("%7.3f ms \n", total / 1000.0).c_str();
SafeUnregisterPerformanceTracker();
}
bool SystemComponent::IsScriptUnitTestingInProgress()
{
return m_scriptBasedUnitTestingInProgress;
}
void SystemComponent::MarkScriptUnitTestBegin()
{
m_scriptBasedUnitTestingInProgress = true;
}
void SystemComponent::MarkScriptUnitTestEnd()
{
m_scriptBasedUnitTestingInProgress = false;
}
void SystemComponent::CreateEngineComponentsOnEntity(AZ::Entity* entity)
@@ -249,7 +310,7 @@ namespace ScriptCanvas
canCreate = listOnly || (!excludeClassAttributeData || (!(flags & exclusionFlags)));
canCreate = canCreate && (serializeContext->FindClassData(behaviorClass->m_typeId));
canCreate = canCreate && !IsDeprecated(behaviorClass->m_attributes);
canCreate = canCreate && !ScriptCanvasSystemComponentCpp::IsDeprecated(behaviorClass->m_attributes);
if (AZ::FindAttribute(AZ::ScriptCanvasAttributes::AllowInternalCreation, behaviorClass->m_attributes))
{
@@ -291,7 +352,7 @@ namespace ScriptCanvas
auto excludeClassAttributeData = azrtti_cast<const AZ::Edit::AttributeData<AZ::Script::Attributes::ExcludeFlags>*>(AZ::FindAttribute(AZ::Script::Attributes::ExcludeFrom, behaviorClass->m_attributes));
bool canCreate = !excludeClassAttributeData || !(excludeClassAttributeData->Get(nullptr) & exclusionFlags);
canCreate = canCreate && (serializeContext->FindClassData(behaviorClass->m_typeId) || AZ::FindAttribute(AZ::ScriptCanvasAttributes::AllowInternalCreation, behaviorClass->m_attributes));
canCreate = canCreate && !IsDeprecated(behaviorClass->m_attributes);
canCreate = canCreate && !ScriptCanvasSystemComponentCpp::IsDeprecated(behaviorClass->m_attributes);
// create able variables must have full memory support
canCreate = canCreate &&
@@ -317,4 +378,59 @@ namespace ScriptCanvas
dataRegistry->UnregisterType(behaviorClass->m_typeId);
}
}
void SystemComponent::SetInterpretedBuildConfiguration(BuildConfiguration config)
{
Execution::SetInterpretedExecutionMode(config);
}
AZ::EnvironmentVariable<Execution::PerformanceTracker*> SystemComponent::s_perfTracker;
AZStd::shared_mutex SystemComponent::s_perfTrackerMutex;
Execution::PerformanceTracker* SystemComponent::ModPerformanceTracker()
{
// First attempt to use the module-static reference; take a read lock to check it.
// This is the fast path which won't block.
{
AZStd::shared_lock<AZStd::shared_mutex> lock(s_perfTrackerMutex);
if (s_perfTracker)
{
return s_perfTracker.Get();
}
}
// If the instance doesn't exist (which means we could be in a different module),
// take the full lock and request it.
AZStd::unique_lock<AZStd::shared_mutex> lock(s_perfTrackerMutex);
s_perfTracker = AZ::Environment::FindVariable<Execution::PerformanceTracker*>(s_trackerName);
return s_perfTracker ? s_perfTracker.Get() : nullptr;
}
void SystemComponent::SafeRegisterPerformanceTracker()
{
if (ModPerformanceTracker())
{
return;
}
AZStd::unique_lock<AZStd::shared_mutex> lock(s_perfTrackerMutex);
auto tracker = aznew Execution::PerformanceTracker();
s_perfTracker = AZ::Environment::CreateVariable<Execution::PerformanceTracker*>(s_trackerName);
s_perfTracker.Get() = tracker;
}
void SystemComponent::SafeUnregisterPerformanceTracker()
{
auto performanceTracker = ModPerformanceTracker();
if (!performanceTracker)
{
return;
}
AZStd::unique_lock<AZStd::shared_mutex> lock(s_perfTrackerMutex);
*s_perfTracker = nullptr;
s_perfTracker.Reset();
delete performanceTracker;
}
}