// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "MassArchetypeTypes.h" #include "MassEntityQuery.h" #include "MassProcessorDependencySolver.h" #include "MassProcessingTypes.h" #include "MassProcessor.h" #include "Types/SlateEnums.h" #include "MassDebugger.h" class UMassProcessor; struct FMassArchetypeHandle; struct FMassDebuggerModel; struct FMassEntityHandle; struct FMassEntityManager; struct FMassEntityQuery; class UWorld; class SMassEntitiesView; class SMassDebugger; enum class EMassDebuggerSelectionMode : uint8 { None, Processor, Archetype, // @todo future: // Fragment MAX }; enum class EMassDebuggerProcessorSelection : uint8 { None, Selected, MAX }; enum class EMassDebuggerProcessingGraphNodeSelection : uint8 { None, WaitFor, Block, MAX }; struct FMassDebuggerQueryData { FMassDebuggerQueryData(const FMassEntityQuery& Query, const FText& InLabel); FMassDebuggerQueryData(const FMassSubsystemRequirements& SubsystemRequirements, const FText& InLabel); FMassExecutionRequirements ExecutionRequirements; FText Label; FText AdditionalInformation; int32 GetTotalBitsUsedCount(); bool IsEmpty() const; }; struct FMassDebuggerArchetypeData { FMassDebuggerArchetypeData(const FMassArchetypeHandle& ArchetypeHandle); FMassArchetypeHandle Handle; FMassArchetypeCompositionDescriptor Composition; /** Hash of the Compositions. */ uint32 CompositionHash = 0; /** Combined hash of composition and shared fragments. */ uint32 FullHash = 0; /** Archetype statistics */ UE::Mass::Debug::FArchetypeStats ArchetypeStats; /** Child debugger data (same as parent, but changed in some way) */ TArray> Children; /** Parent debugger data. */ TWeakPtr Parent; /** Index in FMassDebuggerModel::CachedArchetypes */ int32 Index = INDEX_NONE; /** Display label */ FText Label; /** Display label */ FText LabelLong; /** Display label tooltip */ FText LabelTooltip; /** FullHash as a display string */ FText HashLabel; /** Primary debug name, used for grouping derived archetypes. */ FString PrimaryDebugName; /** True if the archetype is selected. */ bool bIsSelected = false; int32 GetTotalBitsUsedCount() const; }; struct FMassDebuggerProcessorData { FMassDebuggerProcessorData(const UMassProcessor& InProcessor); FMassDebuggerProcessorData(const FMassEntityManager& InEntityManager, const UMassProcessor& InProcessor, const TMap>& InTransientArchetypesMap); private: void SetProcessor(const UMassProcessor& InProcessor); public: FString Name; FString Label; uint32 ProcessorHash = 0; bool bIsActive = true; TWeakPtr EntityManager; TWeakObjectPtr Processor; EMassDebuggerProcessorSelection Selection = EMassDebuggerProcessorSelection::None; TSharedPtr ProcessorRequirements; TArray> Queries; TArray> ValidArchetypes; #if WITH_MASSENTITY_DEBUG FString Description; #endif // WITH_MASSENTITY_DEBUG }; struct FMassDebuggerFragmentData { FMassDebuggerFragmentData(TNotNull InFragment); bool operator==(const FMassDebuggerFragmentData& Other) const { return Fragment == Other.Fragment; } friend uint32 GetTypeHash(const FMassDebuggerFragmentData& Item) { return GetTypeHash(Item.Fragment); } FText Name; TWeakObjectPtr Fragment; TWeakPtr EntityManager; TArray Archetypes; TArray> Processors; int32 NumEntities = 0; }; struct FMassDebuggerProcessingGraphNode { explicit FMassDebuggerProcessingGraphNode(const TSharedPtr& InProcessorData, const UMassCompositeProcessor::FDependencyNode& InProcessorNode = UMassCompositeProcessor::FDependencyNode()); FText GetLabel() const; TSharedPtr ProcessorData; TArray WaitForNodes; TArray BlockNodes; EMassDebuggerProcessingGraphNodeSelection GraphNodeSelection = EMassDebuggerProcessingGraphNodeSelection::None; }; struct FMassDebuggerProcessingGraph { FMassDebuggerProcessingGraph(const FMassDebuggerModel& DebuggerModel, TNotNull InGraphOwner); FString Label; TArray GraphNodes; bool bSingleTheadGraph = !bool(MASS_DO_PARALLEL); }; struct FMassDebuggerEnvironment { explicit FMassDebuggerEnvironment(const TSharedRef& InEntityManager); bool operator==(const FMassDebuggerEnvironment& Other) const { return EntityManager == Other.EntityManager; } FString GetDisplayName() const; TSharedPtr GetEntityManager() const; bool IsWorldValid() const { return World.IsValid(); } bool NeedsValidWorld() const { return bNeedsValidWorld; } TWeakPtr EntityManager; TMap ProcessorProviders; TWeakObjectPtr World; bool bNeedsValidWorld = false; }; struct FMassDebuggerModel { DECLARE_MULTICAST_DELEGATE(FOnRefresh); DECLARE_MULTICAST_DELEGATE_TwoParams(FOnProcessorsSelected, TConstArrayView>, ESelectInfo::Type); DECLARE_MULTICAST_DELEGATE_TwoParams(FOnArchetypesSelected, TConstArrayView>, ESelectInfo::Type); DECLARE_MULTICAST_DELEGATE_OneParam(FOnFragmentSelected, FName FragmentName); FMassDebuggerModel(); ~FMassDebuggerModel(); void SetEnvironment(const TSharedPtr& Item); void RefreshAll(); void SelectProcessor(TSharedPtr& Processor); void SelectProcessors(TArrayView> Processors, ESelectInfo::Type SelectInfo); void ClearProcessorSelection(); void SelectArchetypes(TArrayView> SelectedArchetypes, ESelectInfo::Type SelectInfo); void ClearArchetypeSelection(); bool IsCurrentEnvironment(const FMassDebuggerEnvironment& InEnvironment) const { return Environment && *Environment.Get() == InEnvironment; } bool IsCurrentEnvironmentValid() const { return Environment && Environment->EntityManager.IsValid(); } bool HasEnvironmentSelected() const { return static_cast(Environment); } void CacheArchetypesData(TMap>& OutTransientArchetypesMap); void CacheProcessorsData(const TMap>& InTransientArchetypesMap, TArray>& OutCompositeProcessors); void CacheProcessingGraphs(TConstArrayView> InCompositeProcessors); void CacheFragmentData(); float MinDistanceToSelectedArchetypes(const TSharedPtr& InArchetypeData) const; FText GetDisplayName() const; void MarkAsStale(); bool IsStale() const; const TSharedPtr& GetProcessorDataChecked(const UMassProcessor& Processor) const; void RegisterEntitiesView(TSharedRef EntitiesView, int32 Index); static const int32 MaxEntityViewCount = 1; void ShowEntitiesView(int Index, FMassArchetypeHandle ArchetypeHandle); void ShowEntitiesView(int Index, TArray EntitieHandles); void ShowEntitiesView(int Index, FMassEntityQuery& Query); void ShowEntitiesView(int Index, TConstArrayView InQueries); void ResetEntitiesViews(); TWeakPtr ShowEntitiesView(int32 Index); protected: void StoreArchetypes(const FMassEntityManager& EntityManager, TMap>& OutTransientArchetypesMap); void ResetSelectedArchetypes(); void ResetSelectedProcessors(); void OnEntitySelected(const FMassEntityManager& EntityManager, const FMassEntityHandle EntityHandle); public: TWeakPtr DebuggerWindow; FOnRefresh OnRefreshDelegate; FOnProcessorsSelected OnProcessorsSelectedDelegate; FOnArchetypesSelected OnArchetypesSelectedDelegate; FOnFragmentSelected OnFragmentSelectedDelegate; EMassDebuggerSelectionMode SelectionMode = EMassDebuggerSelectionMode::None; TSharedPtr Environment; struct FProcessorCollection { FProcessorCollection(FName InLabel = FName()) : Label(InLabel) { } FName Label; TArray> Container; }; TArray> CachedFragmentData; TArray> CachedProcessorCollections; TArray> SelectedProcessors; TArray> CachedAllArchetypes; TArray> CachedArchetypeRepresentatives; TArray> SelectedArchetypes; TArray> CachedProcessingGraphs; TMap> HandleToArchetypeMap; TArray> ArchetypeDistances; FString EnvironmentDisplayName; FDelegateHandle OnEntitySelectedHandle; void SelectFragment(FName InFragementName); FName GetSelectedFragment(); protected: TArray> AllCachedProcessors; TArray> EntityViews; FName SelectedFragmentName; public: UE_DEPRECATED(5.6, "CachedProcessors property is now deprecated. Use CachedProcessorCollections instead. ") TArray> CachedProcessors; };