44. Infinite Effect Application and Removal
This commit is contained in:
		
							
								
								
									
										
											BIN
										
									
								
								Project/Binaries/Win64/UnrealEditor-GasaEditor.dll
									 (Stored with Git LFS)
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Project/Binaries/Win64/UnrealEditor-GasaEditor.dll
									 (Stored with Git LFS)
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,6 +1,7 @@ | |||||||
| #include "GasaEffectActor.h" | #include "GasaEffectActor.h" | ||||||
|  |  | ||||||
| #include "GasaAbilitySystemComponent_Inlines.h" | #include "GasaAbilitySystemComponent_Inlines.h" | ||||||
|  | #include "GasaContainers.h" | ||||||
| using namespace Gasa; | using namespace Gasa; | ||||||
|  |  | ||||||
| AGasaEffectActor::AGasaEffectActor() | AGasaEffectActor::AGasaEffectActor() | ||||||
| @@ -9,21 +10,24 @@ AGasaEffectActor::AGasaEffectActor() | |||||||
|  |  | ||||||
| 	RootComponent = CreateDefaultSubobject<USceneComponent>("Root"); | 	RootComponent = CreateDefaultSubobject<USceneComponent>("Root"); | ||||||
|  |  | ||||||
| 	InstantEffectUsage  = DefaultEffectUsagePolicy; | 	InstantEffectUsage  = EInstantEffectUsagePolicy::DoNotApply; | ||||||
| 	DurationEffectUsage = DefaultEffectUsagePolicy; | 	DurationEffectUsage = DefaultEffectUsagePolicy; | ||||||
| 	InfiniteEffectUsage = DefaultEffectUsagePolicy; | 	InfiniteEffectUsage = DefaultEffectUsagePolicy; | ||||||
|  |  | ||||||
|  | 	bDestroyOnEffectRemoval = false; | ||||||
| } | } | ||||||
|  |  | ||||||
| void AGasaEffectActor::ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass) | void AGasaEffectActor::ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass, bool bRemoveOnEndOverlap) | ||||||
| { | { | ||||||
| 	UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true); | 	UGasaAbilitySystemComp* AS = GetAbilitySystem(Actor, true); | ||||||
|  |  | ||||||
| 	FGameplayEffectContextHandle | 	FGameplayEffectContextHandle | ||||||
| 	Context = AS->MakeEffectContext(); | 	Context = AS->MakeEffectContext(); | ||||||
| 	Context.AddSourceObject(Actor); | 	Context.AddSourceObject(Actor); | ||||||
|  |  | ||||||
| 	FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( EffectClass, 1.0f, Context ); | 	FGameplayEffectSpecHandle   Spec         = AS->MakeOutgoingSpec( EffectClass, 1.0f, Context ); | ||||||
| 	AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); | 	FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); | ||||||
|  | 	if (bRemoveOnEndOverlap) | ||||||
|  | 		ActiveEffectsToRemove.Add(ActiveEffect, AS); | ||||||
| } | } | ||||||
|  |  | ||||||
| void AGasaEffectActor::OnOverlap(AActor* Actor) | void AGasaEffectActor::OnOverlap(AActor* Actor) | ||||||
| @@ -33,40 +37,37 @@ void AGasaEffectActor::OnOverlap(AActor* Actor) | |||||||
| 	Context = AS->MakeEffectContext(); | 	Context = AS->MakeEffectContext(); | ||||||
| 	Context.AddSourceObject(Actor); | 	Context.AddSourceObject(Actor); | ||||||
| 	 | 	 | ||||||
| 	if (InstantEffectClass.Get()) | 	if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnOverlap) | ||||||
| 	{ | 	{ | ||||||
| 		if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::ApplyOnOverlap)) | 		FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context ); | ||||||
| 		{ | 		AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); | ||||||
|         	FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context ); |  | ||||||
|         	AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );	 |  | ||||||
| 		} |  | ||||||
| 		if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::RemoveOnOverlap)) |  | ||||||
| 		{ |  | ||||||
|         	AS->RemoveActiveGameplayEffectBySourceEffect( InstantEffectClass, AS ); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 	if (DurationEffectClass.Get()) | 	if (DurationEffectClass) | ||||||
| 	{ | 	{ | ||||||
| 		if (Bitfield_IsSet(DurationEffectUsage, (int32)EEffectUsagePolicy::ApplyOnOverlap)) | 		if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnOverlap)) | ||||||
| 		{ | 		{ | ||||||
|         	FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context ); |         	FGameplayEffectSpecHandle   Spec         = AS->MakeOutgoingSpec( DurationEffectClass, 1.0f, Context ); | ||||||
|         	AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );	 | 			FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); | ||||||
| 		} | 			if (Bitfield_IsSet(DurationEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap)) | ||||||
| 		if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::RemoveOnOverlap)) | 				ActiveDuration = ActiveEffect; | ||||||
| 		{ |  | ||||||
|         	AS->RemoveActiveGameplayEffectBySourceEffect( DurationEffectClass, AS ); |  | ||||||
| 		} | 		} | ||||||
|  | 		if (ActiveDuration.IsValid() && Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::RemoveOnOverlap)) | ||||||
|  | 			AS->RemoveActiveGameplayEffect(ActiveDuration); | ||||||
| 	} | 	} | ||||||
| 	if (InfiniteEffectClass.Get()) | 	if (InfiniteEffectClass) | ||||||
| 	{ | 	{ | ||||||
| 		if (Bitfield_IsSet(InfiniteEffectUsage, (int32)EEffectUsagePolicy::ApplyOnOverlap)) | 		bool bApplyOnOverlap = Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::ApplyOnOverlap); | ||||||
|  | 		if (bApplyOnOverlap) | ||||||
| 		{ | 		{ | ||||||
|         	FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context ); | 			FGameplayEffectSpecHandle   Spec         = AS->MakeOutgoingSpec( InfiniteEffectClass, 1.0f, Context ); | ||||||
|         	AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );	 | 			FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); | ||||||
|  | 			if (Bitfield_IsSet(InfiniteEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap)) | ||||||
|  | 				ActiveInfinite = ActiveEffect; | ||||||
| 		} | 		} | ||||||
| 		if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::RemoveOnOverlap)) | 		if (ActiveInfinite.IsValid() && Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnOverlap)) | ||||||
| 		{ | 		{ | ||||||
| 			AS->RemoveActiveGameplayEffectBySourceEffect( InfiniteEffectClass, AS ); | 			if (ActiveInfinite.IsValid()) | ||||||
|  | 				AS->RemoveActiveGameplayEffect(ActiveInfinite); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -78,40 +79,46 @@ void AGasaEffectActor::OnEndOverlap(AActor* Actor) | |||||||
| 	Context = AS->MakeEffectContext(); | 	Context = AS->MakeEffectContext(); | ||||||
| 	Context.AddSourceObject(Actor); | 	Context.AddSourceObject(Actor); | ||||||
| 	 | 	 | ||||||
| 	if (InstantEffectClass.Get()) | 	if (InstantEffectClass && InstantEffectUsage == EInstantEffectUsagePolicy::ApplyOnEndOverlap) | ||||||
| 	{ | 	{ | ||||||
| 		if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::ApplyOnEndOverlap)) | 		FGameplayEffectSpecHandle Spec= AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context ); | ||||||
|  | 		AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); | ||||||
|  | 	} | ||||||
|  | 	if (DurationEffectClass) | ||||||
|  | 	{ | ||||||
|  | 		if (Bitfield_IsSet(DurationEffectUsage, EEffectUsagePolicy::ApplyOnEndOverlap)) | ||||||
| 		{ | 		{ | ||||||
| 			FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context ); | 			FGameplayEffectSpecHandle   Spec         = AS->MakeOutgoingSpec( DurationEffectClass, 1.0f, Context ); | ||||||
| 			AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );	 | 			FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); | ||||||
|  | 			if (Bitfield_IsSet(DurationEffectUsage, (int32)EEffectUsagePolicy::RemoveOnOverlap)) | ||||||
|  | 				ActiveDuration = ActiveEffect; | ||||||
| 		} | 		} | ||||||
| 		if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap)) | 		if (ActiveDuration.IsValid() && Bitfield_IsSet(DurationEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap)) | ||||||
|  | 			AS->RemoveActiveGameplayEffect(ActiveDuration); | ||||||
|  | 	} | ||||||
|  | 	if (InfiniteEffectClass) | ||||||
|  | 	{ | ||||||
|  | 		if (Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::ApplyOnEndOverlap)) | ||||||
| 		{ | 		{ | ||||||
| 			AS->RemoveActiveGameplayEffectBySourceEffect( InstantEffectClass, AS ); | 			FGameplayEffectSpecHandle   Spec         = AS->MakeOutgoingSpec( InfiniteEffectClass, 1.0f, Context ); | ||||||
|  | 			FActiveGameplayEffectHandle ActiveEffect = AS->ApplyGameplayEffectSpecToSelf( * Spec.Data ); | ||||||
|  | 			if (Bitfield_IsSet(InfiniteEffectUsage, (int32)EEffectUsagePolicy::RemoveOnOverlap)) | ||||||
|  | 				ActiveInfinite = ActiveEffect; | ||||||
|  | 		} | ||||||
|  | 		if (ActiveInfinite.IsValid() && Bitfield_IsSet(InfiniteEffectUsage, EEffectUsagePolicy::RemoveOnEndOverlap)) | ||||||
|  | 		{ | ||||||
|  | 			if (ActiveInfinite.IsValid()) | ||||||
|  | 				AS->RemoveActiveGameplayEffect(ActiveInfinite); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if (DurationEffectClass.Get()) |  | ||||||
|  | 	TArray<FActiveGameplayEffectHandle> EffectsRemoved; | ||||||
|  | 	for (ActiveEffectEntry ActiveEffect : ActiveEffectsToRemove) | ||||||
| 	{ | 	{ | ||||||
| 		if (Bitfield_IsSet(DurationEffectUsage, (int32)EEffectUsagePolicy::ApplyOnEndOverlap)) | 		if (ActiveEffect.Value != AS) | ||||||
| 		{ | 			continue; | ||||||
| 			FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context ); | 		AS->RemoveActiveGameplayEffect(ActiveEffect.Key, 1); | ||||||
| 			AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );	 | 		EffectsRemoved.Add(ActiveEffect.Key); | ||||||
| 		} |  | ||||||
| 		if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap)) |  | ||||||
| 		{ |  | ||||||
| 			AS->RemoveActiveGameplayEffectBySourceEffect( DurationEffectClass, AS ); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if (InfiniteEffectClass.Get()) |  | ||||||
| 	{ |  | ||||||
| 		if (Bitfield_IsSet(InfiniteEffectUsage, (int32)EEffectUsagePolicy::ApplyOnEndOverlap)) |  | ||||||
| 		{ |  | ||||||
| 			FGameplayEffectSpecHandle Spec = AS->MakeOutgoingSpec( InstantEffectClass, 1.0f, Context ); |  | ||||||
| 			AS->ApplyGameplayEffectSpecToSelf( * Spec.Data );	 |  | ||||||
| 		} |  | ||||||
| 		if (Bitfield_IsSet(InstantEffectUsage, (int32)EEffectUsagePolicy::RemoveOnEndOverlap)) |  | ||||||
| 		{ |  | ||||||
| 			AS->RemoveActiveGameplayEffectBySourceEffect( InfiniteEffectClass, AS ); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
|  | 	RemoveKeys(ActiveEffectsToRemove, EffectsRemoved); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,18 +2,29 @@ | |||||||
|  |  | ||||||
| #include "GasaCommon.h" | #include "GasaCommon.h" | ||||||
| #include "Actors/GasaActor.h" | #include "Actors/GasaActor.h" | ||||||
|  | #include "ActiveGameplayEffectHandle.h" | ||||||
| #include "GameFramework/Actor.h" | #include "GameFramework/Actor.h" | ||||||
|  |  | ||||||
| #include "GasaEffectActor.generated.h" | #include "GasaEffectActor.generated.h" | ||||||
|  |  | ||||||
|  | struct FActiveGameplayEffectHandle; | ||||||
|  |  | ||||||
| UENUM(BlueprintType) | UENUM(BlueprintType) | ||||||
|  | enum class EInstantEffectUsagePolicy : uint8 | ||||||
|  | { | ||||||
|  | 	DoNotApply, | ||||||
|  | 	ApplyOnOverlap, | ||||||
|  | 	ApplyOnEndOverlap, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | UENUM(BlueprintType, meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true")) | ||||||
| enum class EEffectUsagePolicy : uint8 | enum class EEffectUsagePolicy : uint8 | ||||||
| { | { | ||||||
| 	None               = 0 UMETA(Hidden), | 	None               = 0 UMETA(Hidden), | ||||||
| 	ApplyOnOverlap     = bit(0), | 	ApplyOnOverlap     = bit(0), | ||||||
| 	ApplyOnEndOverlap  = bit(1), | 	ApplyOnEndOverlap  = bit(1), | ||||||
| 	RemoveOnOverlap    = bit(3), | 	RemoveOnOverlap    = bit(2), | ||||||
| 	RemoveOnEndOverlap = bit(4), | 	RemoveOnEndOverlap = bit(3), | ||||||
| }; | }; | ||||||
|  |  | ||||||
| constexpr int32 DefaultEffectUsagePolicy = (int32(EEffectUsagePolicy::RemoveOnEndOverlap)); | constexpr int32 DefaultEffectUsagePolicy = (int32(EEffectUsagePolicy::RemoveOnEndOverlap)); | ||||||
| @@ -27,28 +38,34 @@ public: | |||||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects") | 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects") | ||||||
| 	TSubclassOf<UGameplayEffect> InstantEffectClass; | 	TSubclassOf<UGameplayEffect> InstantEffectClass; | ||||||
|  |  | ||||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = EEffectUsagePolicy)) | 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects") | ||||||
| 	int32 InstantEffectUsage; | 	EInstantEffectUsagePolicy InstantEffectUsage; | ||||||
| 	 |  | ||||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects") | 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects") | ||||||
| 	TSubclassOf<UGameplayEffect> DurationEffectClass; | 	TSubclassOf<UGameplayEffect> DurationEffectClass; | ||||||
| 	 | 	 | ||||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = EEffectUsagePolicy)) | 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = "/Script/Gasa.EEffectUsagePolicy")) | ||||||
| 	int32 DurationEffectUsage; | 	int32 DurationEffectUsage; | ||||||
| 	 | 	 | ||||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects") | 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects") | ||||||
| 	TSubclassOf<UGameplayEffect> InfiniteEffectClass; | 	TSubclassOf<UGameplayEffect> InfiniteEffectClass; | ||||||
| 	 | 	 | ||||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = EEffectUsagePolicy)) | 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects", meta=(Bitmask, BitmaskEnum = "/Script/Gasa.EEffectUsagePolicy")) | ||||||
| 	int32 InfiniteEffectUsage; | 	int32 InfiniteEffectUsage; | ||||||
|  |  | ||||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects") |  | ||||||
| 	bool bDestroyOnEffectRemoval = false; |  | ||||||
| 	 | 	 | ||||||
|  | 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay Effects") | ||||||
|  | 	bool bDestroyOnEffectRemoval; | ||||||
|  |  | ||||||
|  | 	TMap<FActiveGameplayEffectHandle, UAbilitySystemComponent*> ActiveEffectsToRemove; | ||||||
|  | 	using ActiveEffectEntry = TTuple<FActiveGameplayEffectHandle, UAbilitySystemComponent*>; | ||||||
|  | 	 | ||||||
|  | 	FActiveGameplayEffectHandle ActiveDuration; | ||||||
|  | 	FActiveGameplayEffectHandle ActiveInfinite; | ||||||
|  |  | ||||||
| 	AGasaEffectActor(); | 	AGasaEffectActor(); | ||||||
|  |  | ||||||
| 	UFUNCTION(BlueprintCallable, Category = "Gameplay Effects") | 	UFUNCTION(BlueprintCallable, Category = "Gameplay Effects") | ||||||
| 	void ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass ); | 	void ApplyEffectToActor(AActor* Actor, TSubclassOf<UGameplayEffect> EffectClass, bool bRemoveOnEndOverlap = false); | ||||||
|  |  | ||||||
| 	UFUNCTION(BlueprintCallable) | 	UFUNCTION(BlueprintCallable) | ||||||
| 	void OnOverlap(AActor* Actor); | 	void OnOverlap(AActor* Actor); | ||||||
|   | |||||||
| @@ -45,7 +45,7 @@ public: | |||||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameFramework") | 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameFramework") | ||||||
| 	EGameFrameworkState GameFrameworkState; | 	EGameFrameworkState GameFrameworkState; | ||||||
|  |  | ||||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameFramework", meta=(Bitmask, BitmaskEnum = EGameFrameworkClassFlag)) | 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameFramework", meta=(Bitmask, BitmaskEnum = "/Script/Gasa.EGameFrameworkClassFlag")) | ||||||
| 	int32 GameFrameworkClassesState; | 	int32 GameFrameworkClassesState; | ||||||
|  |  | ||||||
| 	UFUNCTION(BlueprintCallable, Category="GameFramework") | 	UFUNCTION(BlueprintCallable, Category="GameFramework") | ||||||
|   | |||||||
| @@ -80,13 +80,30 @@ namespace Gasa | |||||||
| { | { | ||||||
| 	inline | 	inline | ||||||
| 	bool Bitfield_IsSet(int32 Bitfield, int32 Bitmask) { | 	bool Bitfield_IsSet(int32 Bitfield, int32 Bitmask) { | ||||||
| 		int32 Result = Bitmask == (Bitfield & Bitmask); | 		bool Result = Bitmask == (Bitfield & Bitmask); | ||||||
| 		return scast(bool, Result); | 		return Result; | ||||||
|  | 	} | ||||||
|  | 	inline | ||||||
|  | 	bool Bitfield_IsSetExactly(int32 Bitfield, int32 Bitmask) | ||||||
|  | 	{ | ||||||
|  | 		bool Result = Bitfield == (Bitfield & Bitmask); | ||||||
|  | 		return Result; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	inline void Bitfield_Set   ( int32& Bitfield, int32 BitsToAdd )    { Bitfield |= BitsToAdd; } | 	inline void Bitfield_Set   ( int32& Bitfield, int32 BitsToAdd )    { Bitfield |= BitsToAdd; } | ||||||
| 	inline void Bitfield_Remove( int32& Bitfield, int32 BitsToRemove ) { Bitfield &= (! BitsToRemove); } | 	inline void Bitfield_Remove( int32& Bitfield, int32 BitsToRemove ) { Bitfield &= (! BitsToRemove); } | ||||||
| 	inline void Bitfield_Toggle( int32& Bitfield, int32 Bitmask )      { Bitfield ^= Bitmask; } | 	inline void Bitfield_Toggle( int32& Bitfield, int32 Bitmask )      { Bitfield ^= Bitmask; } | ||||||
|  |  | ||||||
|  | 	template<typename EnumType> | ||||||
|  | 	inline | ||||||
|  | 	bool Bitfield_IsSet(int32 Bitfield, EnumType Mask) | ||||||
|  | 	{ | ||||||
|  | 		bool Result = int32(Mask) == (Bitfield & int32(Mask)); | ||||||
|  | 		return Result; | ||||||
|  | 	} | ||||||
|  | 	template<typename EnumType> inline void Bitfield_Set   ( int32& Bitfield, EnumType BitToAdd )    { Bitfield |= int32(BitToAdd); } | ||||||
|  | 	template<typename EnumType> inline void Bitfield_Remove( int32& Bitfield, EnumType BitToRemove ) { Bitfield &= (! int32(BitToRemove)); } | ||||||
|  | 	template<typename EnumType> inline void Bitfield_Toggle( int32& Bitfield, EnumType BitToToggle ) { Bitfield ^= int32(BitToToggle); } | ||||||
| } | } | ||||||
| #pragma endregion Bitfields | #pragma endregion Bitfields | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										0
									
								
								Project/Source/Gasa/GasaContainers.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								Project/Source/Gasa/GasaContainers.cpp
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										14
									
								
								Project/Source/Gasa/GasaContainers.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Project/Source/Gasa/GasaContainers.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "GasaCommon.h" | ||||||
|  |  | ||||||
|  | template<typename KeyType, typename ValueType> | ||||||
|  | inline | ||||||
|  | void RemoveKeys(TMap<KeyType, ValueType> Map, TArray<KeyType> Keys) | ||||||
|  | { | ||||||
|  | 	for (KeyType& Key : Keys ) | ||||||
|  | 	{ | ||||||
|  | 		Map.Remove(Key); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 	 | ||||||
		Reference in New Issue
	
	Block a user