diff --git a/Code/Editor/Plugins/EditorAssetImporter/AssetImporterDocument.cpp b/Code/Editor/Plugins/EditorAssetImporter/AssetImporterDocument.cpp index c7e14d9c4e..105a5b4954 100644 --- a/Code/Editor/Plugins/EditorAssetImporter/AssetImporterDocument.cpp +++ b/Code/Editor/Plugins/EditorAssetImporter/AssetImporterDocument.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/Code/Editor/Plugins/EditorAssetImporter/ImporterRootDisplay.cpp b/Code/Editor/Plugins/EditorAssetImporter/ImporterRootDisplay.cpp index 4f942a4251..2c00edbc39 100644 --- a/Code/Editor/Plugins/EditorAssetImporter/ImporterRootDisplay.cpp +++ b/Code/Editor/Plugins/EditorAssetImporter/ImporterRootDisplay.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include ImporterRootDisplay::ImporterRootDisplay(AZ::SerializeContext* serializeContext, QWidget* parent) diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp index 39b90a165b..e9e5738bd1 100644 --- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp +++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp @@ -545,6 +545,8 @@ namespace AZ m_entityActivatedEvent.DisconnectAllHandlers(); m_entityDeactivatedEvent.DisconnectAllHandlers(); + m_budgetTracker.Reset(); + DestroyAllocator(); } diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h index 609b683836..b2a1f0324b 100644 --- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h +++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h @@ -11,8 +11,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -395,6 +395,8 @@ namespace AZ // from the m_console member when it goes out of scope AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle m_settingsRegistryConsoleFunctors; + Debug::BudgetTracker m_budgetTracker; + // this is used when no argV/ArgC is supplied. // in order to have the same memory semantics (writable, non-const) // we create a buffer that can be written to (up to AZ_MAX_PATH_LEN) and then @@ -402,8 +404,6 @@ namespace AZ char m_commandLineBuffer[AZ_MAX_PATH_LEN]; char* m_commandLineBufferAddress{ m_commandLineBuffer }; - AZ::Debug::BudgetTracker m_budgetTracker; - StartupParameters m_startupParameters; char** m_argV{ nullptr }; diff --git a/Code/Framework/AzCore/AzCore/Debug/Budget.cpp b/Code/Framework/AzCore/AzCore/Debug/Budget.cpp index 5f17752f2a..9790257ded 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Budget.cpp +++ b/Code/Framework/AzCore/AzCore/Debug/Budget.cpp @@ -12,13 +12,14 @@ #include #include +AZ_DEFINE_BUDGET(Animation); +AZ_DEFINE_BUDGET(Audio); AZ_DEFINE_BUDGET(AzCore); AZ_DEFINE_BUDGET(Editor); AZ_DEFINE_BUDGET(Entity); AZ_DEFINE_BUDGET(Game); AZ_DEFINE_BUDGET(System); -AZ_DEFINE_BUDGET(Audio); -AZ_DEFINE_BUDGET(Animation); +AZ_DEFINE_BUDGET(Physics); namespace AZ::Debug { @@ -28,9 +29,9 @@ namespace AZ::Debug // TODO: Budget implementation for tracking budget wall time per-core, memory, etc. }; - Budget::Budget(const char* name) + Budget::Budget(const char* name, uint32_t crc) : m_name{ name } - , m_crc{ Crc32(name) } + , m_crc{ crc } { m_impl = aznew BudgetImpl; } diff --git a/Code/Framework/AzCore/AzCore/Debug/Budget.h b/Code/Framework/AzCore/AzCore/Debug/Budget.h index ce11469f81..376bf4cc4a 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Budget.h +++ b/Code/Framework/AzCore/AzCore/Debug/Budget.h @@ -7,15 +7,9 @@ */ #pragma once -#include #include - -#pragma warning(push) -// This warning must be disabled because Budget::Get may not have an implementation if this file is transitively included -// in a source file that doesn't actually have any budgets declared in scope (via AZ_DEFINE_BUDGET or AZ_DECLARE_BUDGET). -// In this situation, the warning about internal linkage without an implementation is benign because we know that this function -// cannot be invoked from that translation unit. -#pragma warning(disable: 5046) +#include +#include namespace AZ::Debug { @@ -23,13 +17,7 @@ namespace AZ::Debug class Budget final { public: - // If you encounter a linker error complaining that this function is not defined, you have likely forgotten to either - // define or declare the budget used in a profile or memory marker. See AZ_DEFINE_BUDGET and AZ_DECLARE_BUDGET below - // for usage. - template - static Budget* Get(); - - explicit Budget(const char* name); + Budget(const char* name, uint32_t crc); ~Budget(); void PerFrameReset(); @@ -54,11 +42,12 @@ namespace AZ::Debug struct BudgetImpl* m_impl = nullptr; }; } // namespace AZ::Debug -#pragma warning(pop) -// Budgets are registered and retrieved using the proxy type specialization of Budget::Get. The type itself has no declaration/definition -// other than this forward type pointer declaration -#define AZ_BUDGET_PROXY_TYPE(name) class AzBudget##name* +// The budget is usable in the same file it was defined without needing an additional declaration. +// If you encounter a linker error complaining that this function is not defined, you have likely forgotten to either +// define or declare the budget used in a profile or memory marker. See AZ_DEFINE_BUDGET and AZ_DECLARE_BUDGET below +// for usage. +#define AZ_BUDGET_GETTER(name) GetAzBudget##name // Usage example: // In a single C++ source file: @@ -66,12 +55,10 @@ namespace AZ::Debug // // Anywhere the budget is used, the budget must be declared (either in a header or in the source file itself) // AZ_DECLARE_BUDGET(AzCore); -// -// The budget is usable in the same file it was defined without needing an additional declaration #define AZ_DEFINE_BUDGET(name) \ - template<> \ - ::AZ::Debug::Budget* ::AZ::Debug::Budget::Get() \ + ::AZ::Debug::Budget* AZ_BUDGET_GETTER(name)() \ { \ + constexpr static uint32_t crc = AZ_CRC_CE(#name); \ static ::AZStd::atomic<::AZ::Debug::Budget*> budget; \ ::AZ::Debug::Budget* out = budget.load(AZStd::memory_order_acquire); \ if (out) \ @@ -80,22 +67,23 @@ namespace AZ::Debug } \ else \ { \ - budget.store(&::AZ::Debug::BudgetTracker::GetBudgetFromEnvironment(#name), AZStd::memory_order_release); \ + budget.store(::AZ::Debug::BudgetTracker::GetBudgetFromEnvironment(#name, crc), AZStd::memory_order_release); \ return budget; \ } \ } // If using a budget defined in a different C++ source file, add AZ_DECLARE_BUDGET(yourBudget); somewhere in your source file at namespace // scope Alternatively, AZ_DECLARE_BUDGET can be used in a header to declare the budget for use across any users of the header -#define AZ_DECLARE_BUDGET(name) extern template ::AZ::Debug::Budget* ::AZ::Debug::Budget::Get() +#define AZ_DECLARE_BUDGET(name) extern ::AZ::Debug::Budget* AZ_BUDGET_GETTER(name)() // Declare budgets that are core engine budgets, or may be shared/needed across multiple external gems // You should NOT need to declare user-space or budgets with isolated usage here. Prefer declaring them local to the module(s) that use // the budget and defining them within a single module to avoid needing to recompile the entire engine. +AZ_DECLARE_BUDGET(Animation); +AZ_DECLARE_BUDGET(Audio); AZ_DECLARE_BUDGET(AzCore); AZ_DECLARE_BUDGET(Editor); AZ_DECLARE_BUDGET(Entity); AZ_DECLARE_BUDGET(Game); AZ_DECLARE_BUDGET(System); AZ_DECLARE_BUDGET(Physics); -AZ_DECLARE_BUDGET(Animation); diff --git a/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.cpp b/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.cpp index c58c92deb2..959f8ba3a8 100644 --- a/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.cpp +++ b/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -20,40 +21,54 @@ namespace AZ::Debug struct BudgetTrackerImpl { - AZ_CLASS_ALLOCATOR(BudgetTrackerImpl, AZ::SystemAllocator, 0); - AZStd::unordered_map m_budgets; }; - Budget& BudgetTracker::GetBudgetFromEnvironment(const char* budgetName) + Budget* BudgetTracker::GetBudgetFromEnvironment(const char* budgetName, uint32_t crc) { - return (*Environment::FindVariable(BudgetTrackerEnvName))->GetBudget(budgetName); + BudgetTracker* tracker = Interface::Get(); + if (tracker) + { + return &tracker->GetBudget(budgetName, crc); + } + return nullptr; } BudgetTracker::~BudgetTracker() { - if (m_impl) + Reset(); + } + + bool BudgetTracker::Init() + { + if (Interface::Get()) { - delete m_impl; + return false; } + + Interface::Register(this); + m_impl = new BudgetTrackerImpl; + return true; } - void BudgetTracker::Init() + void BudgetTracker::Reset() { - AZ_Assert(!m_impl, "BudgetTracker::Init called more than once"); - - m_impl = aznew BudgetTrackerImpl; - m_envVar = Environment::CreateVariable(BudgetTrackerEnvName, this); + if (m_impl) + { + Interface::Unregister(this); + delete m_impl; + m_impl = nullptr; + } } - Budget& BudgetTracker::GetBudget(const char* budgetName) + Budget& BudgetTracker::GetBudget(const char* budgetName, uint32_t crc) { AZStd::scoped_lock lock{ m_mutex }; auto it = m_impl->m_budgets.find(budgetName); if (it == m_impl->m_budgets.end()) { - it = m_impl->m_budgets.emplace(budgetName, budgetName).first; + it = m_impl->m_budgets.try_emplace(budgetName, budgetName, crc).first; } return it->second; diff --git a/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.h b/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.h index bd4953c545..d89d55b913 100644 --- a/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.h +++ b/Code/Framework/AzCore/AzCore/Debug/BudgetTracker.h @@ -9,6 +9,7 @@ #pragma once #include +#include #include namespace AZ::Debug @@ -18,17 +19,19 @@ namespace AZ::Debug class BudgetTracker { public: - static Budget& GetBudgetFromEnvironment(const char* budgetName); + AZ_RTTI(BudgetTracker, "{E14A746D-BFFE-4C02-90FB-4699B79864A5}"); + static Budget* GetBudgetFromEnvironment(const char* budgetName, uint32_t crc); ~BudgetTracker(); - void Init(); + // Returns false if the budget tracker was already present in the environment (initialized already elsewhere) + bool Init(); + void Reset(); - Budget& GetBudget(const char* budgetName); + Budget& GetBudget(const char* budgetName, uint32_t crc); private: AZStd::mutex m_mutex; - AZ::EnvironmentVariable m_envVar; // The BudgetTracker is likely included in proportionally high number of files throughout the // engine, so indirection is used here to avoid imposing excessive recompilation in periods diff --git a/Code/Framework/AzCore/AzCore/Debug/Profiler.h b/Code/Framework/AzCore/AzCore/Debug/Profiler.h index a24c5af052..c8911a6ac4 100644 --- a/Code/Framework/AzCore/AzCore/Debug/Profiler.h +++ b/Code/Framework/AzCore/AzCore/Debug/Profiler.h @@ -29,15 +29,14 @@ #define AZ_PROFILE_SCOPE(budget, ...) \ ::AZ::Debug::ProfileScope AZ_JOIN(azProfileScope, __LINE__) \ { \ - *::AZ::Debug::Budget::Get(), __VA_ARGS__ \ + AZ_BUDGET_GETTER(budget)(), __VA_ARGS__ \ } #define AZ_PROFILE_FUNCTION(category) AZ_PROFILE_SCOPE(category, AZ_FUNCTION_SIGNATURE) // Prefer using the scoped macros which automatically end the event (AZ_PROFILE_SCOPE/AZ_PROFILE_FUNCTION) -#define AZ_PROFILE_BEGIN(budget, ...) \ - ::AZ::Debug::ProfileScope::BeginRegion(*::AZ::Debug::Budget::Get(), __VA_ARGS__) -#define AZ_PROFILE_END(budget) ::AZ::Debug::ProfileScope::EndRegion(*::AZ::Debug::Budget::Get()) +#define AZ_PROFILE_BEGIN(budget, ...) ::AZ::Debug::ProfileScope::BeginRegion(AZ_BUDGET_GETTER(budget)(), __VA_ARGS__) +#define AZ_PROFILE_END(budget) ::AZ::Debug::ProfileScope::EndRegion(AZ_BUDGET_GETTER(budget)()) #endif // AZ_PROFILER_MACRO_DISABLE @@ -64,44 +63,17 @@ namespace AZ::Debug { public: template - static void BeginRegion([[maybe_unused]] Budget& budget, [[maybe_unused]] const char* eventName, [[maybe_unused]] T const&... args) - { -#if !defined(_RELEASE) - // TODO: Verification that the supplied system name corresponds to a known budget -#if defined(USE_PIX) - PIXBeginEvent(PIX_COLOR_INDEX(budget.Crc() & 0xff), eventName, args...); -#endif - budget.BeginProfileRegion(); -// TODO: injecting instrumentation for other profilers -// NOTE: external profiler registration won't occur inline in a header necessarily in this manner, but the exact mechanism -// will be introduced in a future PR -#endif - } - - static void EndRegion([[maybe_unused]] Budget& budget) - { -#if !defined(_RELEASE) - budget.EndProfileRegion(); -#if defined(USE_PIX) - PIXEndEvent(); -#endif -#endif - } + static void BeginRegion([[maybe_unused]] Budget* budget, [[maybe_unused]] const char* eventName, [[maybe_unused]] T const&... args); + + static void EndRegion([[maybe_unused]] Budget* budget); template - ProfileScope(Budget& budget, char const* eventName, T const&... args) - : m_budget{ budget } - { - BeginRegion(budget, eventName, args...); - } + ProfileScope(Budget* budget, char const* eventName, T const&... args); - ~ProfileScope() - { - EndRegion(m_budget); - } + ~ProfileScope(); private: - Budget& m_budget; + Budget* m_budget; }; } // namespace AZ::Debug @@ -111,3 +83,5 @@ namespace AZ::Debug #undef LoadImage #undef GetCurrentTime #endif + +#include diff --git a/Code/Framework/AzCore/AzCore/Debug/Profiler.inl b/Code/Framework/AzCore/AzCore/Debug/Profiler.inl new file mode 100644 index 0000000000..8ca8368ce1 --- /dev/null +++ b/Code/Framework/AzCore/AzCore/Debug/Profiler.inl @@ -0,0 +1,57 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +namespace AZ::Debug +{ + template + void ProfileScope::BeginRegion( + [[maybe_unused]] Budget* budget, [[maybe_unused]] const char* eventName, [[maybe_unused]] T const&... args) + { + if (!budget) + { + return; + } +#if !defined(_RELEASE) + // TODO: Verification that the supplied system name corresponds to a known budget +#if defined(USE_PIX) + PIXBeginEvent(PIX_COLOR_INDEX(budget->Crc() & 0xff), eventName, args...); +#endif + budget->BeginProfileRegion(); +// TODO: injecting instrumentation for other profilers +// NOTE: external profiler registration won't occur inline in a header necessarily in this manner, but the exact mechanism +// will be introduced in a future PR +#endif + } + + inline void ProfileScope::EndRegion([[maybe_unused]] Budget* budget) + { + if (!budget) + { + return; + } +#if !defined(_RELEASE) + budget->EndProfileRegion(); +#if defined(USE_PIX) + PIXEndEvent(); +#endif +#endif + } + + template + ProfileScope::ProfileScope(Budget* budget, char const* eventName, T const&... args) + : m_budget{ budget } + { + BeginRegion(budget, eventName, args...); + } + + inline ProfileScope::~ProfileScope() + { + EndRegion(m_budget); + } + +} // namespace AZ::Debug diff --git a/Code/Framework/AzCore/AzCore/UnitTest/TestTypes.h b/Code/Framework/AzCore/AzCore/UnitTest/TestTypes.h index eb5011bbfa..c3e3f5210a 100644 --- a/Code/Framework/AzCore/AzCore/UnitTest/TestTypes.h +++ b/Code/Framework/AzCore/AzCore/UnitTest/TestTypes.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake index 745054855b..c2ee439645 100644 --- a/Code/Framework/AzCore/AzCore/azcore_files.cmake +++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake @@ -102,6 +102,7 @@ set(FILES Debug/IEventLogger.h Debug/MemoryProfiler.h Debug/Profiler.cpp + Debug/Profiler.inl Debug/Profiler.h Debug/ProfilerBus.h Debug/StackTracer.h diff --git a/Code/Framework/AzFramework/AzFramework/Entity/EntityContextBus.h b/Code/Framework/AzFramework/AzFramework/Entity/EntityContextBus.h index 49cb8db609..124c8d8f50 100644 --- a/Code/Framework/AzFramework/AzFramework/Entity/EntityContextBus.h +++ b/Code/Framework/AzFramework/AzFramework/Entity/EntityContextBus.h @@ -16,11 +16,14 @@ #ifndef AZFRAMEWORK_ENTITYCONTEXTBUS_H #define AZFRAMEWORK_ENTITYCONTEXTBUS_H +#include #include #include #include #include +AZ_DECLARE_BUDGET(AzFramework); + namespace AZ { class Entity; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h index 6f5183edaf..9ab896ab9d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h @@ -17,8 +17,6 @@ #include #include "PropertyEditorAPI_Internals.h" -AZ_DECLARE_BUDGET(AzToolsFramework); - class QWidget; class QCheckBox; class QLabel; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI_Internals.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI_Internals.h index 8b53121776..ecd27baed4 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI_Internals.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI_Internals.h @@ -25,6 +25,8 @@ class QColor; class QString; class QPoint; +AZ_DECLARE_BUDGET(AzToolsFramework); + namespace AzToolsFramework { namespace Components diff --git a/Code/Framework/GridMate/Tests/gridmate_test_files.cmake b/Code/Framework/GridMate/Tests/gridmate_test_files.cmake index 7b2ae2e8ab..3ff67f8eda 100644 --- a/Code/Framework/GridMate/Tests/gridmate_test_files.cmake +++ b/Code/Framework/GridMate/Tests/gridmate_test_files.cmake @@ -8,7 +8,6 @@ set(FILES test_Main.cpp - TestProfiler.cpp Tests.h Session.cpp Serialize.cpp @@ -16,7 +15,6 @@ set(FILES ReplicaSmall.cpp ReplicaMedium.cpp ReplicaBehavior.cpp - Replica.cpp StreamSecureSocketDriverTests.cpp StreamSocketDriverTests.cpp CarrierStreamSocketDriverTests.cpp diff --git a/Code/Legacy/CrySystem/System.cpp b/Code/Legacy/CrySystem/System.cpp index 5c03b06a48..8c950e900c 100644 --- a/Code/Legacy/CrySystem/System.cpp +++ b/Code/Legacy/CrySystem/System.cpp @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/Code/Legacy/CrySystem/SystemEventDispatcher.cpp b/Code/Legacy/CrySystem/SystemEventDispatcher.cpp index 525bf1a005..8e4e36b453 100644 --- a/Code/Legacy/CrySystem/SystemEventDispatcher.cpp +++ b/Code/Legacy/CrySystem/SystemEventDispatcher.cpp @@ -9,6 +9,7 @@ #include "CrySystem_precompiled.h" #include "SystemEventDispatcher.h" +#include CSystemEventDispatcher::CSystemEventDispatcher() : m_listeners(0) diff --git a/Gems/AudioSystem/Code/Source/Engine/ATL.cpp b/Gems/AudioSystem/Code/Source/Engine/ATL.cpp index ff56300b85..3122ddcbd3 100644 --- a/Gems/AudioSystem/Code/Source/Engine/ATL.cpp +++ b/Gems/AudioSystem/Code/Source/Engine/ATL.cpp @@ -13,6 +13,7 @@ #include #endif // !AUDIO_RELEASE +#include #include #include diff --git a/Gems/AudioSystem/Code/Source/Engine/AudioSystem.cpp b/Gems/AudioSystem/Code/Source/Engine/AudioSystem.cpp index 4e0a5b3baf..dfe34fb6eb 100644 --- a/Gems/AudioSystem/Code/Source/Engine/AudioSystem.cpp +++ b/Gems/AudioSystem/Code/Source/Engine/AudioSystem.cpp @@ -17,8 +17,6 @@ #include #include -AZ_DEFINE_BUDGET(Audio); - namespace Audio { extern CAudioLogger g_audioLogger; diff --git a/Gems/NvCloth/Code/Include/NvCloth/ITangentSpaceHelper.h b/Gems/NvCloth/Code/Include/NvCloth/ITangentSpaceHelper.h index 66ccd6a333..216dc6b4a5 100644 --- a/Gems/NvCloth/Code/Include/NvCloth/ITangentSpaceHelper.h +++ b/Gems/NvCloth/Code/Include/NvCloth/ITangentSpaceHelper.h @@ -8,10 +8,13 @@ #pragma once +#include #include #include +AZ_DECLARE_BUDGET(Cloth); + namespace NvCloth { //! Interface that provides a set of functions to diff --git a/Gems/PhysX/Code/Source/System/PhysXSystem.cpp b/Gems/PhysX/Code/Source/System/PhysXSystem.cpp index 3fa81172f5..ebdfc5d417 100644 --- a/Gems/PhysX/Code/Source/System/PhysXSystem.cpp +++ b/Gems/PhysX/Code/Source/System/PhysXSystem.cpp @@ -21,8 +21,6 @@ #define ENABLE_PHYSX_TIMESTEP_WARNING #endif -AZ_DEFINE_BUDGET(Physics); - namespace PhysX { AZ_CLASS_ALLOCATOR_IMPL(PhysXSystem, AZ::SystemAllocator, 0); diff --git a/Gems/ScriptEvents/Code/Source/Editor/ScriptEventsSystemEditorComponent.cpp b/Gems/ScriptEvents/Code/Source/Editor/ScriptEventsSystemEditorComponent.cpp index 548f8d137a..b7586618dd 100644 --- a/Gems/ScriptEvents/Code/Source/Editor/ScriptEventsSystemEditorComponent.cpp +++ b/Gems/ScriptEvents/Code/Source/Editor/ScriptEventsSystemEditorComponent.cpp @@ -22,6 +22,8 @@ #if defined(SCRIPTEVENTS_EDITOR) +AZ_DECLARE_BUDGET(AzToolsFramework); + namespace ScriptEventsEditor { ////////////////////////////