Files
UnrealEngine/Engine/Source/Runtime/NavigationSystem/Private/NavigationObjectRepository.h
2025-05-18 13:04:45 +08:00

201 lines
8.9 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "AI/Navigation/NavigationElement.h" // required since we can't fwd declare types used as TMap keys
#include "Misc/MTTransactionallySafeAccessDetector.h"
#include "Subsystems/WorldSubsystem.h"
#include "UObject/ObjectKey.h"
#include "UObject/WeakInterfacePtr.h"
#include "NavigationObjectRepository.generated.h"
class INavLinkCustomInterface;
class INavRelevantInterface;
UE_DEPRECATED(5.5, "Use the overloaded version with FNavigationElement instead.")
DECLARE_DELEGATE_OneParam(FOnNavRelevantObjectRegistrationEvent, INavRelevantInterface&);
DECLARE_DELEGATE_OneParam(FOnNavigationElementRegistrationEvent, const TSharedRef<const FNavigationElement>&);
DECLARE_DELEGATE_OneParam(FOnCustomNavLinkObjectRegistrationEvent, INavLinkCustomInterface&);
/**
* World subsystem dedicated to store different types of navigation related elements that the
* NavigationSystem needs to access.
*/
UCLASS()
class UNavigationObjectRepository : public UWorldSubsystem
{
GENERATED_BODY()
public:
// Specifies whether OnNavigationElementAddedDelegate must be broadcast on successful registration.
enum class ENotifyOnSuccess : uint8
{
No,
Yes
};
/**
* Adds the provided navigation element to the list of registered elements.
* @param Element Reference to the navigation element to register.
* @param NotifyOnSuccess Indicates if OnNavigationElementRegisteredDelegate must be broadcast on successful registration.
* @return Handle to the registered element.
* @note Method will assert if the same element is registered twice.
*/
TSharedPtr<const FNavigationElement> AddNavigationElement(FNavigationElement&& Element, ENotifyOnSuccess NotifyOnSuccess = ENotifyOnSuccess::Yes);
/**
* Removes the navigation element associated with the provided handle from the list of registered elements.
* @param Handle Handle to the element to unregister.
* @note Method will assert if the element can't be removed (i.e., not registered or already unregistered).
*/
void RemoveNavigationElement(FNavigationElementHandle Handle);
/**
* Iterates through all registered navigation elements and call provided function with the element as parameter.
*/
void ForEachNavigationElement(TFunctionRef<void(const TSharedRef<const FNavigationElement>&)>) const;
/**
* Adds the provided object implementing INavRelevantInterface to the list of registered navigation relevant objects.
* @param NavRelevantObject INavRelevantInterface of the object to register.
* @note Method will also assert if same interface pointers is registered twice.
*/
TSharedPtr<const FNavigationElement> RegisterNavRelevantObject(const INavRelevantInterface& NavRelevantObject);
/**
* Removes the provided interface from the list of registered navigation relevant objects.
* @param NavRelevantObject INavRelevantInterface of the object to unregister.
* @note Method will also assert if interface can't be removed (i.e. not registered or already unregistered).
*/
void UnregisterNavRelevantObject(const INavRelevantInterface& NavRelevantObject);
/**
* Removes the provided object from the list of registered navigation relevant objects.
* @param NavRelevantObject INavRelevantInterface of the object to unregister.
* @note Method will also assert if interface can't be removed (i.e. not registered or already unregistered).
*/
void UnregisterNavRelevantObject(const UObject* NavRelevantObject);
/**
* Returns the handle associated with the specific UObject if it is registered in the repository.
* @param NavRelevantObject The UObject for which the handle must be retrieved.
* @return The handle associated with the specified UObject if already registered, an invalid handle otherwise.
*/
FNavigationElementHandle GetNavigationElementHandleForUObject(const UObject* NavRelevantObject);
/**
* Returns a shared pointer to the FNavigationElement created for a registered UObject.
* @param NavRelevantObject The UObject for which the FNavigationElement must be retrieved.
* @return A valid shared pointer if the specified UObject is registered and an associated FNavigationElement was created,
* null pointer otherwise.
*/
TSharedPtr<const FNavigationElement> GetNavigationElementForUObject(const UObject* NavRelevantObject);
/**
* Returns a shared pointer to the FNavigationElement created for a registered UObject.
* This method will not handle other navigation structure updates (e.g., NavigationOctree)
* and should only be used by the NavigationSystem.
* @param NavRelevantInterface The interface to use to update an existing element
* @param NavRelevantObject The UObject for which the FNavigationElement must be retrieved.
* @return A valid shared pointer if the specified UObject is registered and an associated FNavigationElement was created,
* null pointer otherwise.
*/
TSharedPtr<const FNavigationElement> UpdateNavigationElementForUObject(const INavRelevantInterface& NavRelevantInterface, const UObject& NavRelevantObject);
/**
* Returns a shared pointer to the FNavigationElement associated with the provided handle.
* @param Handle The handle for which the FNavigationElement must be retrieved.
* @return A valid shared pointer if a FNavigationElement associated with the provided handle was registered, null pointer otherwise.
*/
TSharedPtr<const FNavigationElement> GetNavigationElementForHandle(FNavigationElementHandle Handle) const;
/**
* Adds the provided interface to the list of registered custom navigation links.
* @param CustomNavLinkObject INavLinkCustomInterface of the object to register.
* @note Method will also assert if same interface pointers is registered twice.
*/
void RegisterCustomNavLinkObject(INavLinkCustomInterface& CustomNavLinkObject);
/**
* Removes the provided interface from the list of registered custom navigation links.
* @param CustomNavLinkObject INavLinkCustomInterface of the object to unregister.
* @note Method will also assert if interface can't be removed (i.e. not registered or already unregistered).
*/
void UnregisterCustomNavLinkObject(INavLinkCustomInterface& CustomNavLinkObject);
/**
* Returns the list of registered custom navigation links.
* @return Const view on the list of all registered custom navigation links.
*/
TConstArrayView<TWeakInterfacePtr<INavLinkCustomInterface>> GetCustomLinks() const
{
return CustomLinkObjects;
}
/** Returns the number of navigation elements registered in the repository */
int32 GetNumRegisteredElements() const
{
return NavRelevantElements.Num();
}
/** Returns the number of UObject registered in the repository for which a FNavigationElement has been created and registered. */
int32 GetNumRegisteredUObjects() const
{
return ObjectsToHandleMap.Num();
}
/** Returns the number of UObjects implementing INavLinkCustomInterface registered in the repository */
int32 GetNumRegisteredCustomLinks() const
{
return CustomLinkObjects.Num();
}
/** Delegate executed when a navigation element is added in the repository. */
FOnNavigationElementRegistrationEvent OnNavigationElementAddedDelegate;
/** Delegate executed when a navigation element is removed from the repository. */
FOnNavigationElementRegistrationEvent OnNavigationElementRemovedDelegate;
/** Delegate executed when a custom navigation link is registered with the repository. */
FOnCustomNavLinkObjectRegistrationEvent OnCustomNavLinkObjectRegistered;
/** Delegate executed when a custom navigation link is unregistered with the repository. */
FOnCustomNavLinkObjectRegistrationEvent OnCustomNavLinkObjectUnregistered;
protected:
virtual bool ShouldCreateSubsystem(UObject* Outer) const override;
private:
TSharedPtr<const FNavigationElement> RegisterNavRelevantObjectInternal(const INavRelevantInterface& NavRelevantInterface, const UObject& NavRelevantObject, ENotifyOnSuccess NotifyOnSuccess);
/** For legacy object registration path (i.e., Actor/ActorComponent) */
TMap<FObjectKey, FNavigationElementHandle> ObjectsToHandleMap;
/** List of registered navigation elements. */
TMap<FNavigationElementHandle, TSharedPtr<const FNavigationElement>> NavRelevantElements;
/** List of registered custom navigation link objects. */
TArray<TWeakInterfacePtr<INavLinkCustomInterface>> CustomLinkObjects;
/** Multi thread access detector used to validate accesses to the maps of registered UObjects and FNavigationElement */
UE_MT_DECLARE_TS_RW_ACCESS_DETECTOR(NavElementAccessDetector);
//----------------------------------------------------------------------//
// DEPRECATED
//----------------------------------------------------------------------//
public:
#if WITH_EDITORONLY_DATA
PRAGMA_DISABLE_DEPRECATION_WARNINGS
UE_DEPRECATED(5.5, "Use OnNavigationElementAddedDelegate instead.")
FOnNavRelevantObjectRegistrationEvent OnNavRelevantObjectRegistered;
UE_DEPRECATED(5.5, "Use OnNavigationElementRemovedDelegate instead.")
FOnNavRelevantObjectRegistrationEvent OnNavRelevantObjectUnregistered;
PRAGMA_ENABLE_DEPRECATION_WARNINGS
#endif // WITH_EDITORONLY_DATA
};