573 lines
31 KiB
C
573 lines
31 KiB
C
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////
|
||
|
/// Copyright 2019 (C) Bruno Xavier B. Leite
|
||
|
//////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include "PooledPawn.h"
|
||
|
#include "PooledActor.h"
|
||
|
#include "PooledCharacter.h"
|
||
|
#include "PooledProjectile.h"
|
||
|
#include "PoolSpawnOptions.h"
|
||
|
#include "PooledSplineProjectile.h"
|
||
|
|
||
|
#include "OBJPool.generated.h"
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
/// Template Pool Enumerators
|
||
|
|
||
|
UENUM(BlueprintType, meta=(DisplayName="Validation", Keywords="Spawn Validation"))
|
||
|
enum class FOBJPoolSpawning : uint8 {
|
||
|
SpawnSuccessful,
|
||
|
SpawnFailed
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
/// Object Pool Component:: Stores Pooled Objects for Owner
|
||
|
|
||
|
/// Pool Data Component;
|
||
|
/// Builds and holds pointers to the data stored in memory to be used by Object-Pool Queries.
|
||
|
UCLASS(ClassGroup = Synaptech, Category="Performance", Blueprintable, BlueprintType, hideCategories = ("Activation", "Collision", "Sockets", "Variable"), meta=(BlueprintSpawnableComponent, DisplayName="Object-Pool Component", ShortTooltip = "Pool Data Class."))
|
||
|
class OBJPOOL_API UObjectPool : public UActorComponent {
|
||
|
GENERATED_UCLASS_BODY()
|
||
|
//
|
||
|
friend class APooledActor;
|
||
|
protected:
|
||
|
/// The Memory Pool.
|
||
|
UPROPERTY()
|
||
|
TArray<APooledActor*> Pool;
|
||
|
public:
|
||
|
/// If enabled, every time the object is Pooled by the Pool, it's OnPoolBeginPlay() and OnPoolEndPlay() events will be executed.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool ReinitializeInstances;
|
||
|
//
|
||
|
/// If enabled, a new object will be created by the Pool to fulfill the request from owner when there's no instances available;
|
||
|
/// If disabled, nothing is instantiated if pool is empty and instead, resulting object returns NULL for the request out of bounds.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool InstantiateOnDemand;
|
||
|
//
|
||
|
/// If enabled, the Pool will guarantee that the 'Spawn Deferred' function will never fail with a null pointer.
|
||
|
/// If there's no inactive Actor available then the function will point to the last spawned Actor instead.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool NeverFailDeferredSpawn;
|
||
|
//
|
||
|
/// If enabled, keeps alive Pooled Actors that are still active when the parent Pool Component has been destroyed.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool KeepOrphanActorsAlive;
|
||
|
public:
|
||
|
/// Empties the Pool; Respawns all of its members based on 'Pool Size' allocation.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Initialize Object Pool", Keywords="initialize pool"))
|
||
|
virtual void InitializeObjectPool();
|
||
|
//
|
||
|
/// Empties the Pool; Respawns all of its members based on 'Pool Size' allocation.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Initialize Object Pool with Class [Template]", Keywords="initialize pool"))
|
||
|
virtual void InitializeObjectPoolWithNewTemplateClass(const TSubclassOf<APooledActor> Template, const int32 SizeOfPool);
|
||
|
public:
|
||
|
virtual void BeginPlay() override;
|
||
|
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||
|
//
|
||
|
virtual void FlushObjectPool();
|
||
|
//
|
||
|
//
|
||
|
/// The Actor Class needed to populate this Object-Pool.
|
||
|
UPROPERTY(Category="Object Pool", EditAnywhere, BlueprintReadOnly)
|
||
|
TSubclassOf<APooledActor> TemplateClass;
|
||
|
//
|
||
|
/// How many instances you want to store pre-loaded.
|
||
|
UPROPERTY(Category="Object Pool", EditAnywhere, BlueprintReadWrite, meta=(ClampMin = "1"))
|
||
|
int32 PoolSize = 1;
|
||
|
//
|
||
|
/// If checked, this will make this Pool Component to automatically load Object Instances when the Game starts.
|
||
|
/// Initialization is still going to happen, independently, when a Pull request is received and the Pool is empty.
|
||
|
UPROPERTY(Category="Object Pool", EditAnywhere, BlueprintReadWrite)
|
||
|
bool AutoInitialize;
|
||
|
//
|
||
|
UFUNCTION()
|
||
|
void ReturnActor(APooledActor* PooledActor);
|
||
|
//
|
||
|
/// Will destroy all Pooled Actors stored by this Object-Pool.
|
||
|
/// Note: A Pool Component, when destroyed, will also destroy all of its Pooled objects; Spawned or not.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Empty Object Pool", Keywords="empty delete pool"))
|
||
|
void EmptyObjectPool();
|
||
|
//
|
||
|
//
|
||
|
/// Returns the Container Array of Pooled Objects.
|
||
|
/// WARNING: Danger! Do not manually Add or Remove members from this!
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Object Array", Keywords="get pool objects"))
|
||
|
TArray<APooledActor*> GetObjectArray() const {return Pool;}
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns all of its Spawned or Inactive Actors as separate lists.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Objects From Pool", Keywords="get pool objects"))
|
||
|
void GetObjectsFromPool(TArray<APooledActor*> &Spawned, TArray<APooledActor*> &Inactive);
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns all of its Spawned Actors list.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Spawned Objects", Keywords="get spawned objects"))
|
||
|
void GetSpawnedObjects(TArray<APooledActor*> &Spawned);
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns all of its Inactive Actors list.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Inactive Objects", Keywords="get inactive objects"))
|
||
|
void GetInactiveObjects(TArray<APooledActor*> &Inactive);
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns the first Spawned Actor found on top of the Pool.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Spawned Object", Keywords="get pool spawned object"))
|
||
|
APooledActor* GetSpawnedObject() const;
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns the first Inactive Actor found on top of the Pool.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Inactive Object", Keywords="get pool inactive object"))
|
||
|
APooledActor* GetInactiveObject() const;
|
||
|
//
|
||
|
//
|
||
|
/// Spawns an Actor from Pool, manually running its Construction Scripts if a full reset is needed.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(WorldContext="WorldContextObject", UnsafeDuringActorConstruction = "true", BlueprintInternalUseOnly = "true"))
|
||
|
static APooledActor* BeginDeferredSpawnFromPool(const UObject* WorldContextObject, UObjectPool* ObjectPool, UClass* PooledClass, const FPoolSpawnOptions &SpawnOptions, const FTransform &SpawnTransform, ESpawnActorCollisionHandlingMethod CollisionHandlingOverride, AActor* Owner, const bool Reconstruct, bool &SpawnSuccessful);
|
||
|
//
|
||
|
/// Finishes Deferred Spawning an Actor from Pool.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(WorldContext="WorldContextObject", UnsafeDuringActorConstruction = "true", BlueprintInternalUseOnly = "true"))
|
||
|
static APooledActor* FinishDeferredSpawnFromPool(APooledActor* Actor, const bool Reconstruct, const FTransform &SpawnTransform);
|
||
|
//
|
||
|
//
|
||
|
/// Gets this Pool's Objects, Type-casting.
|
||
|
/// Returns Empty Array if Cast fails.
|
||
|
template <typename T>
|
||
|
FORCEINLINE TArray<T*> GetObjectsFromPool() const {
|
||
|
TArray<T*> TC;
|
||
|
for (const auto &OBJ : Pool) {
|
||
|
if (!IsValid(OBJ)) {continue;}
|
||
|
T* O = Cast<T>(*&OBJ); if (O) {TC.Add(O);}
|
||
|
} return TC;}
|
||
|
//
|
||
|
/// Gets this Pool's Spawned Objects, Type-casting.
|
||
|
/// Returns Empty Array if Cast fails.
|
||
|
template <typename T>
|
||
|
FORCEINLINE TArray<T*> GetSpawnedObjects() const {
|
||
|
TArray<T*> TC;
|
||
|
for (const auto &OBJ : Pool) {
|
||
|
if (!IsValid(OBJ)) {continue;}
|
||
|
T* O = Cast<T>(*&OBJ); if (O&&O->Spawned) {TC.Add(O);}
|
||
|
} return TC;}
|
||
|
//
|
||
|
/// Gets this Pool's Inactive Objects, Type-casting.
|
||
|
/// Returns Empty Array if Cast fails.
|
||
|
template <typename T>
|
||
|
FORCEINLINE TArray<T*> GetInactiveObjects() const {
|
||
|
TArray<T*> TC;
|
||
|
for (const auto &OBJ : Pool) {
|
||
|
if (!IsValid(OBJ)) {continue;}
|
||
|
T* O = Cast<T>(*&OBJ); if (O&&(!O->Spawned)) {TC.Add(O);}
|
||
|
} return TC;}
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
/// Pawn Pool Component:: Stores Pooled Pawn Actors for Owner
|
||
|
|
||
|
/// Pool Data Component;
|
||
|
/// Builds and holds pointers to the data stored in memory to be used by Object-Pool Queries.
|
||
|
UCLASS(ClassGroup = Synaptech, Category="Performance", Blueprintable, BlueprintType, hideCategories = ("Activation", "Collision", "Sockets", "Variable"), meta=(BlueprintSpawnableComponent, DisplayName="Pawn-Pool Component", ShortTooltip = "Pool Data Class."))
|
||
|
class OBJPOOL_API UPawnPool : public UActorComponent {
|
||
|
GENERATED_UCLASS_BODY()
|
||
|
//
|
||
|
friend class APooledPawn;
|
||
|
protected:
|
||
|
/// The Memory Pool.
|
||
|
UPROPERTY()
|
||
|
TArray<APooledPawn*> Pool;
|
||
|
public:
|
||
|
/// If enabled, every time the object is Pooled by the Pool, it's OnPoolBeginPlay() and OnPoolEndPlay() events will be executed.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool ReinitializeInstances;
|
||
|
//
|
||
|
/// If enabled, a new object will be created by the Pool to fulfill the request from owner when there's no instances available;
|
||
|
/// If disabled, nothing is instantiated if pool is empty and instead, resulting object returns NULL for the request out of bounds.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool InstantiateOnDemand;
|
||
|
//
|
||
|
/// If enabled, the Pool will guarantee that the 'Spawn Deferred' function will never fail with a null pointer.
|
||
|
/// If there's no inactive Actor available then the function will point to the last spawned Actor instead.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool NeverFailDeferredSpawn;
|
||
|
//
|
||
|
/// If enabled, keeps alive Pooled Actors that are still active when the parent Pool Component has been destroyed.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool KeepOrphanActorsAlive;
|
||
|
public:
|
||
|
/// Empties the Pool; Respawns all of its members based on 'Pool Size' allocation.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Initialize Object Pool", Keywords="initialize pool"))
|
||
|
virtual void InitializeObjectPool();
|
||
|
//
|
||
|
/// Empties the Pool; Respawns all of its members based on 'Pool Size' allocation.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Initialize Object Pool with Class [Template]", Keywords="initialize pool"))
|
||
|
virtual void InitializeObjectPoolWithNewTemplateClass(const TSubclassOf<APooledPawn> Template, const int32 SizeOfPool);
|
||
|
public:
|
||
|
virtual void BeginPlay() override;
|
||
|
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||
|
//
|
||
|
virtual void FlushObjectPool();
|
||
|
//
|
||
|
//
|
||
|
/// The Actor Class needed to populate this Object-Pool.
|
||
|
UPROPERTY(Category="Object Pool", EditAnywhere, BlueprintReadOnly)
|
||
|
TSubclassOf<APooledPawn> TemplateClass;
|
||
|
//
|
||
|
/// How many instances you want to store pre-loaded.
|
||
|
UPROPERTY(Category="Object Pool", EditAnywhere, BlueprintReadWrite, meta=(ClampMin = "1"))
|
||
|
int32 PoolSize = 1;
|
||
|
//
|
||
|
/// If checked, this will make this Pool Component to automatically load Object Instances when the Game starts.
|
||
|
/// Initialization is still going to happen, independently, when a Pull request is received and the Pool is empty.
|
||
|
UPROPERTY(Category="Object Pool", EditAnywhere, BlueprintReadWrite)
|
||
|
bool AutoInitialize;
|
||
|
//
|
||
|
UFUNCTION()
|
||
|
void ReturnActor(APooledPawn* PooledActor);
|
||
|
//
|
||
|
/// Will destroy all Pooled Actors stored by this Object-Pool.
|
||
|
/// Note: A Pool Component, when destroyed, will also destroy all of its Pooled objects; Spawned or not.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Empty Object Pool", Keywords="empty delete pool"))
|
||
|
void EmptyObjectPool();
|
||
|
//
|
||
|
//
|
||
|
/// Returns the Container Array of Pooled Objects.
|
||
|
/// WARNING: Danger! Do not manually Add or Remove members from this!
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Object Array", Keywords="get pool objects"))
|
||
|
TArray<APooledPawn*> GetObjectArray() const {return Pool;}
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns all of its Spawned or Inactive Actors as separate lists.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Objects From Pool", Keywords="get pool objects"))
|
||
|
void GetObjectsFromPool(TArray<APooledPawn*> &Spawned, TArray<APooledPawn*> &Inactive);
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns all of its Spawned Actors list.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Spawned Objects", Keywords="get spawned objects"))
|
||
|
void GetSpawnedObjects(TArray<APooledPawn*> &Spawned);
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns all of its Inactive Actors list.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Inactive Objects", Keywords="get inactive objects"))
|
||
|
void GetInactiveObjects(TArray<APooledPawn*> &Inactive);
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns the first Spawned Actor found on top of the Pool.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Spawned Object", Keywords="get pool spawned object"))
|
||
|
APooledPawn* GetSpawnedObject() const;
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns the first Inactive Actor found on top of the Pool.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Inactive Object", Keywords="get pool inactive object"))
|
||
|
APooledPawn* GetInactiveObject() const;
|
||
|
//
|
||
|
//
|
||
|
/// Spawns an Actor from Pool, manually running its Construction Scripts if a full reset is needed.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(WorldContext="WorldContextObject", UnsafeDuringActorConstruction = "true", BlueprintInternalUseOnly = "true"))
|
||
|
static APooledPawn* BeginDeferredSpawnFromPool(const UObject* WorldContextObject, UPawnPool* ObjectPool, UClass* PooledClass, const FPoolSpawnOptions &SpawnOptions, const FTransform &SpawnTransform, ESpawnActorCollisionHandlingMethod CollisionHandlingOverride, AActor* Owner, const bool Reconstruct, bool &SpawnSuccessful);
|
||
|
//
|
||
|
/// Finishes Deferred Spawning an Actor from Pool.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(WorldContext="WorldContextObject", UnsafeDuringActorConstruction = "true", BlueprintInternalUseOnly = "true"))
|
||
|
static APooledPawn* FinishDeferredSpawnFromPool(APooledPawn* Pawn, const bool Reconstruct, const FTransform &SpawnTransform);
|
||
|
//
|
||
|
//
|
||
|
/// Gets this Pool's Objects, Type-casting.
|
||
|
/// Returns Empty Array if Cast fails.
|
||
|
template <typename T>
|
||
|
FORCEINLINE TArray<T*> GetObjectsFromPool() const {
|
||
|
TArray<T*> TC;
|
||
|
for (const auto &OBJ : Pool) {
|
||
|
if (!IsValid(OBJ)) {continue;}
|
||
|
T* O = Cast<T>(*&OBJ); if (O) {TC.Add(O);}
|
||
|
} return TC;}
|
||
|
//
|
||
|
/// Gets this Pool's Spawned Objects, Type-casting.
|
||
|
/// Returns Empty Array if Cast fails.
|
||
|
template <typename T>
|
||
|
FORCEINLINE TArray<T*> GetSpawnedObjects() const {
|
||
|
TArray<T*> TC;
|
||
|
for (const auto &OBJ : Pool) {
|
||
|
if (!IsValid(OBJ)) {continue;}
|
||
|
T* O = Cast<T>(*&OBJ); if (O&&O->Spawned) {TC.Add(O);}
|
||
|
} return TC;}
|
||
|
//
|
||
|
/// Gets this Pool's Inactive Objects, Type-casting.
|
||
|
/// Returns Empty Array if Cast fails.
|
||
|
template <typename T>
|
||
|
FORCEINLINE TArray<T*> GetInactiveObjects() const {
|
||
|
TArray<T*> TC;
|
||
|
for (const auto &OBJ : Pool) {
|
||
|
if (!IsValid(OBJ)) {continue;}
|
||
|
T* O = Cast<T>(*&OBJ); if (O&&(!O->Spawned)) {TC.Add(O);}
|
||
|
} return TC;}
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
/// Character Pool Component:: Stores Pooled Character Actors for Owner
|
||
|
|
||
|
/// Pool Data Component;
|
||
|
/// Builds and holds pointers to the data stored in memory to be used by Object-Pool Queries.
|
||
|
UCLASS(ClassGroup = Synaptech, Category="Performance", Blueprintable, BlueprintType, hideCategories = ("Activation", "Collision", "Sockets", "Variable"), meta=(BlueprintSpawnableComponent, DisplayName="Character-Pool Component", ShortTooltip = "Pool Data Class."))
|
||
|
class OBJPOOL_API UCharacterPool : public UActorComponent {
|
||
|
GENERATED_UCLASS_BODY()
|
||
|
//
|
||
|
friend class APooledCharacter;
|
||
|
protected:
|
||
|
/// The Memory Pool.
|
||
|
UPROPERTY()
|
||
|
TArray<APooledCharacter*> Pool;
|
||
|
public:
|
||
|
/// If enabled, every time the object is Pooled by the Pool, it's OnPoolBeginPlay() and OnPoolEndPlay() events will be executed.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool ReinitializeInstances;
|
||
|
//
|
||
|
/// If enabled, a new object will be created by the Pool to fulfill the request from owner when there's no instances available;
|
||
|
/// If disabled, nothing is instantiated if pool is empty and instead, resulting object returns NULL for the request out of bounds.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool InstantiateOnDemand;
|
||
|
//
|
||
|
/// If enabled, the Pool will guarantee that the 'Spawn Deferred' function will never fail with a null pointer.
|
||
|
/// If there's no inactive Actor available then the function will point to the last spawned Actor instead.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool NeverFailDeferredSpawn;
|
||
|
//
|
||
|
/// If enabled, keeps alive Pooled Actors that are still active when the parent Pool Component has been destroyed.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool KeepOrphanActorsAlive;
|
||
|
public:
|
||
|
/// Empties the Pool; Respawns all of its members based on 'Pool Size' allocation.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Initialize Object Pool", Keywords="initialize pool"))
|
||
|
virtual void InitializeObjectPool();
|
||
|
//
|
||
|
/// Empties the Pool; Respawns all of its members based on 'Pool Size' allocation.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Initialize Object Pool with Class [Template]", Keywords="initialize pool"))
|
||
|
virtual void InitializeObjectPoolWithNewTemplateClass(const TSubclassOf<APooledCharacter> Template, const int32 SizeOfPool);
|
||
|
public:
|
||
|
virtual void BeginPlay() override;
|
||
|
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||
|
//
|
||
|
virtual void FlushObjectPool();
|
||
|
//
|
||
|
//
|
||
|
/// The Actor Class needed to populate this Object-Pool.
|
||
|
UPROPERTY(Category="Object Pool", EditAnywhere, BlueprintReadOnly)
|
||
|
TSubclassOf<APooledCharacter> TemplateClass;
|
||
|
//
|
||
|
/// How many instances you want to store pre-loaded.
|
||
|
UPROPERTY(Category="Object Pool", EditAnywhere, BlueprintReadWrite, meta=(ClampMin = "1"))
|
||
|
int32 PoolSize = 1;
|
||
|
//
|
||
|
/// If checked, this will make this Pool Component to automatically load Object Instances when the Game starts.
|
||
|
/// Initialization is still going to happen, independently, when a Pull request is received and the Pool is empty.
|
||
|
UPROPERTY(Category="Object Pool", EditAnywhere, BlueprintReadWrite)
|
||
|
bool AutoInitialize;
|
||
|
//
|
||
|
UFUNCTION()
|
||
|
void ReturnActor(APooledCharacter* PooledActor);
|
||
|
//
|
||
|
/// Will destroy all Pooled Actors stored by this Object-Pool.
|
||
|
/// Note: A Pool Component, when destroyed, will also destroy all of its Pooled objects; Spawned or not.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Empty Object Pool", Keywords="empty delete pool"))
|
||
|
void EmptyObjectPool();
|
||
|
//
|
||
|
//
|
||
|
/// Returns the Container Array of Pooled Objects.
|
||
|
/// WARNING: Danger! Do not manually Add or Remove members from this!
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Object Array", Keywords="get pool objects"))
|
||
|
TArray<APooledCharacter*> GetObjectArray() const {return Pool;}
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns all of its Spawned or Inactive Actors as separate lists.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Objects From Pool", Keywords="get pool objects"))
|
||
|
void GetObjectsFromPool(TArray<APooledCharacter*> &Spawned, TArray<APooledCharacter*> &Inactive);
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns all of its Spawned Actors list.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Spawned Objects", Keywords="get spawned objects"))
|
||
|
void GetSpawnedObjects(TArray<APooledCharacter*> &Spawned);
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns all of its Inactive Actors list.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Inactive Objects", Keywords="get inactive objects"))
|
||
|
void GetInactiveObjects(TArray<APooledCharacter*> &Inactive);
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns the first Spawned Actor found on top of the Pool.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Spawned Object", Keywords="get pool spawned object"))
|
||
|
APooledCharacter* GetSpawnedObject() const;
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns the first Inactive Actor found on top of the Pool.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Inactive Object", Keywords="get pool inactive object"))
|
||
|
APooledCharacter* GetInactiveObject() const;
|
||
|
//
|
||
|
//
|
||
|
/// Spawns an Actor from Pool, manually running its Construction Scripts if a full reset is needed.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(WorldContext="WorldContextObject", UnsafeDuringActorConstruction = "true", BlueprintInternalUseOnly = "true"))
|
||
|
static APooledCharacter* BeginDeferredSpawnFromPool(const UObject* WorldContextObject, UCharacterPool* ObjectPool, UClass* PooledClass, const FPoolSpawnOptions &SpawnOptions, const FTransform &SpawnTransform, ESpawnActorCollisionHandlingMethod CollisionHandlingOverride, AActor* Owner, const bool Reconstruct, bool &SpawnSuccessful);
|
||
|
//
|
||
|
/// Finishes Deferred Spawning an Actor from Pool.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(WorldContext="WorldContextObject", UnsafeDuringActorConstruction = "true", BlueprintInternalUseOnly = "true"))
|
||
|
static APooledCharacter* FinishDeferredSpawnFromPool(APooledCharacter* Character, const bool Reconstruct, const FTransform &SpawnTransform);
|
||
|
//
|
||
|
//
|
||
|
/// Gets this Pool's Objects, Type-casting.
|
||
|
/// Returns Empty Array if Cast fails.
|
||
|
template <typename T>
|
||
|
FORCEINLINE TArray<T*> GetObjectsFromPool() const {
|
||
|
TArray<T*> TC;
|
||
|
for (const auto &OBJ : Pool) {
|
||
|
if (!IsValid(OBJ)) {continue;}
|
||
|
T* O = Cast<T>(*&OBJ); if (O) {TC.Add(O);}
|
||
|
} return TC;}
|
||
|
//
|
||
|
/// Gets this Pool's Spawned Objects, Type-casting.
|
||
|
/// Returns Empty Array if Cast fails.
|
||
|
template <typename T>
|
||
|
FORCEINLINE TArray<T*> GetSpawnedObjects() const {
|
||
|
TArray<T*> TC;
|
||
|
for (const auto &OBJ : Pool) {
|
||
|
if (!IsValid(OBJ)) {continue;}
|
||
|
T* O = Cast<T>(*&OBJ); if (O&&O->Spawned) {TC.Add(O);}
|
||
|
} return TC;}
|
||
|
//
|
||
|
/// Gets this Pool's Inactive Objects, Type-casting.
|
||
|
/// Returns Empty Array if Cast fails.
|
||
|
template <typename T>
|
||
|
FORCEINLINE TArray<T*> GetInactiveObjects() const {
|
||
|
TArray<T*> TC;
|
||
|
for (const auto &OBJ : Pool) {
|
||
|
if (!IsValid(OBJ)) {continue;}
|
||
|
T* O = Cast<T>(*&OBJ); if (O&&(!O->Spawned)) {TC.Add(O);}
|
||
|
} return TC;}
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
/// Shared Object Pool Component:: Stores Pooled Objects for Owner
|
||
|
|
||
|
/// Pool Data Component;
|
||
|
/// Builds and holds pointers to the data stored in memory to be used by Object-Pool Queries.
|
||
|
UCLASS(ClassGroup = Synaptech, Category="Performance", Blueprintable, BlueprintType, hideCategories = ("Activation", "Collision", "Sockets", "Variable"), meta=(BlueprintSpawnableComponent, DisplayName="Shared-Pool Component", ShortTooltip = " Shared Pool Data Class."))
|
||
|
class OBJPOOL_API USharedObjectPool : public UActorComponent {
|
||
|
GENERATED_UCLASS_BODY()
|
||
|
//
|
||
|
friend class APooledActor;
|
||
|
protected:
|
||
|
/// The Memory Pool.
|
||
|
UPROPERTY()
|
||
|
TArray<APooledActor*> Pool;
|
||
|
public:
|
||
|
/// If enabled, every time the object is Pooled by the Pool, it's OnPoolBeginPlay() and OnPoolEndPlay() events will be executed.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool ReinitializeInstances;
|
||
|
//
|
||
|
/// If enabled, a new object will be created by the Pool to fulfill the request from owner when there's no instances available;
|
||
|
/// If disabled, nothing is instantiated if pool is empty and instead, resulting object returns NULL for the request out of bounds.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool InstantiateOnDemand;
|
||
|
//
|
||
|
/// If enabled, the Pool will guarantee that the 'Spawn Deferred' function will never fail with a null pointer.
|
||
|
/// If there's no inactive Actor available then the function will point to the last spawned Actor instead.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool NeverFailDeferredSpawn;
|
||
|
//
|
||
|
/// If enabled, keeps alive Pooled Actors that are still active when the parent Pool Component has been destroyed.
|
||
|
UPROPERTY(Category="Object Pool", AdvancedDisplay, EditAnywhere, BlueprintReadOnly)
|
||
|
bool KeepOrphanActorsAlive;
|
||
|
public:
|
||
|
virtual void FlushObjectPool();
|
||
|
//
|
||
|
/// Empties the Pool; Respawns all of its members based on 'Pool Size' allocation.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Initialize Object Pool", Keywords="initialize pool"))
|
||
|
void InitializeObjectPool();
|
||
|
public:
|
||
|
virtual void BeginPlay() override;
|
||
|
virtual void PostInitProperties() override;
|
||
|
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||
|
//
|
||
|
//
|
||
|
/// If checked, this will make this Pool Component to automatically load Object Instances when the Game starts.
|
||
|
/// Initialization is still going to happen, independently, when a Pull request is received and the Pool is empty.
|
||
|
UPROPERTY(Category="Object Pool", EditAnywhere, BlueprintReadWrite)
|
||
|
bool AutoInitialize;
|
||
|
//
|
||
|
/// The Template Classes used to populate this Object-Pool.
|
||
|
UPROPERTY(Category="Object Pool", EditAnywhere, BlueprintReadOnly)
|
||
|
TMap<TSubclassOf<APooledActor>,int32> TemplateClasses;
|
||
|
//
|
||
|
//
|
||
|
UFUNCTION()
|
||
|
void ReturnActor(APooledActor* PooledActor);
|
||
|
//
|
||
|
/// Will destroy all Pooled Actors of Class stored by this Object-Pool.
|
||
|
/// Note: A Pool Component, when destroyed, will also destroy all of its Pooled objects; Spawned or not.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Empty Object Pool", Keywords="empty delete pool"))
|
||
|
void EmptyObjectPool(const UClass* Class);
|
||
|
//
|
||
|
//
|
||
|
/// Returns the Container Array of Pooled Objects.
|
||
|
/// WARNING: Danger! Do not manually Add or Remove members from this!
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Object Array", Keywords="get pool objects"))
|
||
|
TArray<APooledActor*> GetObjectArray() const {return Pool;}
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns all of its Spawned or Inactive Actors as separate lists.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Objects From Pool", Keywords="get pool objects"))
|
||
|
void GetObjectsFromPool(const UClass* Class, TArray<APooledActor*> &Spawned, TArray<APooledActor*> &Inactive);
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns all of its Spawned Actors list.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Spawned Objects", Keywords="get spawned objects"))
|
||
|
void GetSpawnedObjects(const UClass* Class, TArray<APooledActor*> &Spawned);
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns all of its Inactive Actors list.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Inactive Objects", Keywords="get inactive objects"))
|
||
|
void GetInactiveObjects(const UClass* Class, TArray<APooledActor*> &Inactive);
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns the first Spawned Actor found on top of the Pool.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Spawned Object", Keywords="get pool spawned object"))
|
||
|
APooledActor* GetSpawnedObject(const UClass* Class) const;
|
||
|
//
|
||
|
/// Fast-Query this Pool and returns the first Inactive Actor found on top of the Pool.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(DisplayName="Get Inactive Object", Keywords="get pool inactive object"))
|
||
|
APooledActor* GetInactiveObject(const UClass* Class) const;
|
||
|
//
|
||
|
//
|
||
|
/// Spawns an Actor from Pool, manually running its Construction Scripts if a full reset is needed.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(WorldContext="WorldContextObject", UnsafeDuringActorConstruction="true", BlueprintInternalUseOnly="true"))
|
||
|
static APooledActor* BeginDeferredSpawnFromPool(const UObject* WorldContextObject, USharedObjectPool* SharedPool, UClass* Class, const FPoolSpawnOptions &SpawnOptions, const FTransform &SpawnTransform, ESpawnActorCollisionHandlingMethod CollisionHandlingOverride, AActor* Owner, const bool Reconstruct, bool &SpawnSuccessful);
|
||
|
//
|
||
|
/// Finishes Deferred Spawning an Actor from Pool.
|
||
|
UFUNCTION(Category="Object Pool", BlueprintCallable, meta=(WorldContext="WorldContextObject", UnsafeDuringActorConstruction="true", BlueprintInternalUseOnly="true"))
|
||
|
static APooledActor* FinishDeferredSpawnFromPool(APooledActor* Actor, const bool Reconstruct, const FTransform &SpawnTransform);
|
||
|
//
|
||
|
//
|
||
|
/// Gets this Pool's Objects, Type-casting.
|
||
|
/// Returns Empty Array if Cast fails.
|
||
|
template <typename T>
|
||
|
FORCEINLINE TArray<T*> GetObjectsFromPool() const {
|
||
|
TArray<T*> TC;
|
||
|
for (const auto &OBJ : Pool) {
|
||
|
if (!IsValid(OBJ)) {continue;}
|
||
|
T* O = Cast<T>(*&OBJ); if (O) {TC.Add(O);}
|
||
|
} return TC;}
|
||
|
//
|
||
|
/// Gets this Pool's Spawned Objects, Type-casting.
|
||
|
/// Returns Empty Array if Cast fails.
|
||
|
template <typename T>
|
||
|
FORCEINLINE TArray<T*> GetSpawnedObjects() const {
|
||
|
TArray<T*> TC;
|
||
|
for (const auto &OBJ : Pool) {
|
||
|
if (!IsValid(OBJ)) {continue;}
|
||
|
T* O = Cast<T>(*&OBJ); if (O&&O->Spawned) {TC.Add(O);}
|
||
|
} return TC;}
|
||
|
//
|
||
|
/// Gets this Pool's Inactive Objects, Type-casting.
|
||
|
/// Returns Empty Array if Cast fails.
|
||
|
template <typename T>
|
||
|
FORCEINLINE TArray<T*> GetInactiveObjects() const {
|
||
|
TArray<T*> TC;
|
||
|
for (const auto &OBJ : Pool) {
|
||
|
if (!IsValid(OBJ)) {continue;}
|
||
|
T* O = Cast<T>(*&OBJ); if (O&&(!O->Spawned)) {TC.Add(O);}
|
||
|
} return TC;}
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void LOG_OBJ(const bool Debug, const float Duration, const FColor Color, const FString Message);
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|