Skip to content

Commit 30feebb

Browse files
committed
Improved OnModified delegates to provide LastValues and simplify implementation
1 parent 74313a9 commit 30feebb

11 files changed

Lines changed: 120 additions & 57 deletions

AttributesExtension.uplugin

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"FileVersion": 3,
3-
"Version": 4,
4-
"VersionName": "1.3a",
3+
"Version": 5,
4+
"VersionName": "1.3b",
55
"FriendlyName": "Attributes Extension",
66
"Description": "A lightweight attributes system for Unreal Engine 4",
77
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/1f0ba37099a14e228a1ce5e4891ed70a",

Source/Attributes/Private/BaseAttr.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,11 @@ void FBaseAttr::AddModifier(const FAttrModifier& Modifier, const FAttrCategory&
3030
return;
3131
}
3232

33-
RefreshValue();
34-
OnModified.Broadcast(EAttributeOperation::Add, Modifier, Category);
33+
InternalRefreshValue({
34+
EAttributeOperation::AddedMod,
35+
Modifier,
36+
Category
37+
});
3538
}
3639

3740
bool FBaseAttr::RemoveModifier(const FAttrModifier& Modifier, const FAttrCategory& Category, bool bRemoveFromAllCategories)
@@ -88,8 +91,11 @@ bool FBaseAttr::RemoveModifier(const FAttrModifier& Modifier, const FAttrCategor
8891

8992
if (bChanged)
9093
{
91-
RefreshValue();
92-
OnModified.Broadcast(EAttributeOperation::Remove, Modifier, Category);
94+
InternalRefreshValue({
95+
EAttributeOperation::RemovedMod,
96+
Modifier,
97+
Category
98+
});
9399
}
94100
return bChanged;
95101
}
@@ -131,8 +137,11 @@ void FBaseAttr::CleanCategoryModifiers(const FAttrCategory& Category)
131137
BaseModifiers.Empty();
132138

133139
// Notify
134-
RefreshValue();
135-
OnModified.Broadcast(EAttributeOperation::RemoveCategory, {}, Category);
140+
InternalRefreshValue({
141+
EAttributeOperation::RemovedCategory,
142+
{},
143+
Category
144+
});
136145
}
137146
}
138147
else
@@ -144,8 +153,11 @@ void FBaseAttr::CleanCategoryModifiers(const FAttrCategory& Category)
144153
CategoryMods.HeapRemoveAt(Index);
145154

146155
// Notify
147-
RefreshValue();
148-
OnModified.Broadcast(EAttributeOperation::RemoveCategory, {}, Category);
156+
InternalRefreshValue({
157+
EAttributeOperation::RemovedCategory,
158+
{},
159+
Category
160+
});
149161
}
150162
else
151163
{
@@ -163,7 +175,10 @@ void FBaseAttr::CleanModifiers()
163175
BaseModifiers.Empty();
164176
CategoryMods.Empty();
165177

166-
RefreshValue();
167-
OnModified.Broadcast(EAttributeOperation::RemoveAll, {}, FAttrCategory::NoCategory);
178+
InternalRefreshValue({
179+
EAttributeOperation::RemovedAllMods,
180+
{},
181+
FAttrCategory::NoCategory
182+
});
168183
}
169184
}

Source/Attributes/Private/FloatAttr.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ void FFloatAttr::SetBaseValue(float NewValue)
1111
BaseValue = NewValue;
1212

1313
// Notify
14-
RefreshValue();
15-
OnModified.Broadcast(EAttributeOperation::Base, {}, FAttrCategory::NoCategory);
14+
InternalRefreshValue({
15+
EAttributeOperation::BaseValueChanged,
16+
{},
17+
FAttrCategory::NoCategory
18+
});
1619
}
1720
}
1821

@@ -21,8 +24,9 @@ void FFloatAttr::PostScriptConstruct()
2124
RefreshValue();
2225
}
2326

24-
void FFloatAttr::RefreshValue()
27+
void FFloatAttr::InternalRefreshValue(FAttributeModifiedInfo&& ChangeInfo)
2528
{
29+
const float LastValue = Value;
2630
Value = BaseValue;
2731

2832
for (const auto& Mod : BaseModifiers)
@@ -37,4 +41,7 @@ void FFloatAttr::RefreshValue()
3741
Mod.Apply(Value, BaseValue);
3842
}
3943
}
40-
}
44+
45+
// Notify changes
46+
OnModified.Broadcast(LastValue, ChangeInfo);
47+
}

Source/Attributes/Private/Int32Attr.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ void FInt32Attr::SetBaseValue(int32 NewValue)
1111
BaseValue = NewValue;
1212

1313
// Notify
14-
RefreshValue();
15-
OnModified.Broadcast(EAttributeOperation::Base, {}, FAttrCategory::NoCategory);
14+
InternalRefreshValue({
15+
EAttributeOperation::BaseValueChanged,
16+
{},
17+
FAttrCategory::NoCategory
18+
});
1619
}
1720
}
1821

@@ -21,8 +24,9 @@ void FInt32Attr::PostScriptConstruct()
2124
RefreshValue();
2225
}
2326

24-
void FInt32Attr::RefreshValue()
27+
void FInt32Attr::InternalRefreshValue(FAttributeModifiedInfo&& ChangeInfo)
2528
{
29+
const int32 LastValue = Value;
2630
double TempValue = BaseValue;
2731

2832
for (const auto& Mod : BaseModifiers)

Source/Attributes/Public/AttrCategory.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ struct ATTRIBUTES_API FAttrCategory
3030

3131
public:
3232

33-
FAttrCategory() : Name(NO_ATTRCATEGORY_NAME) {
34-
}
33+
FAttrCategory() : Name(NO_ATTRCATEGORY_NAME) {}
3534

3635
FAttrCategory(FName Name)
3736
: Name(Name)
@@ -50,7 +49,8 @@ struct ATTRIBUTES_API FAttrCategory
5049
return GetTypeHash(InRelation.Name);
5150
}
5251

53-
FName GetName() const {
52+
FName GetName() const
53+
{
5454
return Name;
5555
}
5656
};
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2015-2019 Piperift. All Rights Reserved.
2+
3+
#pragma once
4+
5+
#include <CoreMinimal.h>
6+
7+
#include "AttrModifier.h"
8+
#include "AttrCategory.h"
9+
10+
#include "AttributeEvents.generated.h"
11+
12+
13+
UENUM(BlueprintType)
14+
enum class EAttributeOperation : uint8
15+
{
16+
None UMETA(Hidden),
17+
BaseValueChanged,
18+
AddedMod,
19+
RemovedMod,
20+
RemovedAllMods,
21+
RemovedCategory
22+
};
23+
24+
25+
USTRUCT(BlueprintType)
26+
struct FAttributeModifiedInfo
27+
{
28+
GENERATED_BODY()
29+
30+
UPROPERTY(BlueprintReadOnly)
31+
EAttributeOperation Operation;
32+
33+
UPROPERTY(BlueprintReadOnly)
34+
FAttrModifier Modifier;
35+
36+
UPROPERTY(BlueprintReadOnly)
37+
FAttrCategory Category;
38+
};
39+
40+
DECLARE_DYNAMIC_DELEGATE_TwoParams(FFloatModifiedDelegate, float, LastValue, const FAttributeModifiedInfo&, Modification);
41+
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FFloatModifiedMCDelegate, float, LastValue, const FAttributeModifiedInfo&, Modification);
42+
43+
DECLARE_DYNAMIC_DELEGATE_TwoParams(FInt32ModifiedDelegate, int32, LastValue, const FAttributeModifiedInfo&, Modification);
44+
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FInt32ModifiedMCDelegate, int32, LastValue, const FAttributeModifiedInfo&, Modification);

Source/Attributes/Public/BaseAttr.h

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,11 @@
66

77
#include "AttrModifier.h"
88
#include "AttrCategory.h"
9+
#include "AttributeEvents.h"
910

1011
#include "BaseAttr.generated.h"
1112

1213

13-
UENUM(BlueprintType)
14-
enum class EAttributeOperation : uint8
15-
{
16-
None,
17-
Add,
18-
Remove,
19-
RemoveAll,
20-
RemoveCategory,
21-
Base
22-
};
23-
24-
DECLARE_DYNAMIC_DELEGATE_ThreeParams(FAttributeModifiedDelegate, const EAttributeOperation, Operation, const FAttrModifier&, Modifier, const FAttrCategory&, Category);
25-
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FAttributeModifiedMCDelegate, const EAttributeOperation, Operation, const FAttrModifier&, Modifier, const FAttrCategory&, Category);
26-
27-
2814
/**
2915
* Base Attribute
3016
* Extended upon to support different types of attributes
@@ -34,7 +20,6 @@ struct ATTRIBUTES_API FBaseAttr
3420
{
3521
GENERATED_BODY()
3622

37-
3823
private:
3924

4025
/** Using an static counter for Ids.
@@ -54,17 +39,12 @@ struct ATTRIBUTES_API FBaseAttr
5439
UPROPERTY(NotReplicated, SaveGame)
5540
TArray<FAttributeCategoryMods> CategoryMods;
5641

57-
public:
58-
59-
UPROPERTY()
60-
FAttributeModifiedMCDelegate OnModified;
6142

43+
public:
6244

6345
FBaseAttr() : Id(IdCount++) {}
6446
virtual ~FBaseAttr() {}
6547

66-
public:
67-
6848
void AddModifier(const FAttrModifier& Modifier, const FAttrCategory& Category = FAttrCategory::NoCategory);
6949
bool RemoveModifier(const FAttrModifier& Modifier, const FAttrCategory& Category = FAttrCategory::NoCategory, bool bRemoveFromAllCategories = false);
7050

@@ -82,8 +62,12 @@ struct ATTRIBUTES_API FBaseAttr
8262
void CleanCategoryModifiers(const FAttrCategory& Category);
8363
void CleanModifiers();
8464

85-
virtual void RefreshValue() {}
65+
void RefreshValue() { InternalRefreshValue({}); }
8666

8767
// Compare two attributes by Id
8868
FORCEINLINE bool operator==(const FBaseAttr& Other) const { return Id == Other.Id; }
69+
70+
protected:
71+
72+
virtual void InternalRefreshValue(FAttributeModifiedInfo&& ChangeInfo) {}
8973
};

Source/Attributes/Public/FloatAttr.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ struct ATTRIBUTES_API FFloatAttr : public FBaseAttr
2828
UPROPERTY(EditAnywhere, Category = Attribute, Transient)
2929
float Value = 0.f;
3030

31+
UPROPERTY()
32+
FFloatModifiedMCDelegate OnModified;
33+
3134

3235
public:
3336

@@ -53,9 +56,12 @@ struct ATTRIBUTES_API FFloatAttr : public FBaseAttr
5356

5457
void PostScriptConstruct();
5558

59+
FFloatModifiedMCDelegate& GetOnModified() { return OnModified; }
60+
const FFloatModifiedMCDelegate& GetOnModified() const { return OnModified; }
61+
5662
private:
5763

58-
virtual void RefreshValue() override;
64+
virtual void InternalRefreshValue(FAttributeModifiedInfo&& ChangeInfo) override;
5965
};
6066

6167

Source/Attributes/Public/FloatAttributesLibrary.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,15 @@ class ATTRIBUTES_API UFloatAttributesLibrary : public UBlueprintFunctionLibrary
133133
}
134134

135135
UFUNCTION(BlueprintCallable, Category = Attributes, meta = (AdvancedDisplay = "Category"))
136-
static void BindOnModified(UPARAM(ref) FFloatAttr& Attribute, const FAttributeModifiedDelegate& Event)
136+
static void BindOnModified(UPARAM(ref) FFloatAttr& Attribute, const FFloatModifiedDelegate& Event)
137137
{
138-
Attribute.OnModified.AddUnique(Event);
138+
Attribute.GetOnModified().AddUnique(Event);
139139
}
140140

141141
UFUNCTION(BlueprintCallable, Category = Attributes, meta = (AdvancedDisplay = "Category"))
142-
static void UnbindOnModified(UPARAM(ref) FFloatAttr& Attribute, const FAttributeModifiedDelegate& Event)
142+
static void UnbindOnModified(UPARAM(ref) FFloatAttr& Attribute, const FFloatModifiedDelegate& Event)
143143
{
144-
Attribute.OnModified.Remove(Event);
144+
Attribute.GetOnModified().Remove(Event);
145145
}
146146

147147
protected:

Source/Attributes/Public/Int32Attr.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ struct ATTRIBUTES_API FInt32Attr : public FBaseAttr
2424
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Attribute, SaveGame)
2525
int32 BaseValue = 0;
2626

27-
private:
28-
2927
/** Cached final value from modifiers */
3028
UPROPERTY(EditAnywhere, Category = Attribute, Transient)
3129
int32 Value = 0;
3230

31+
UPROPERTY()
32+
FInt32ModifiedMCDelegate OnModified;
3333

3434
public:
3535

@@ -55,9 +55,12 @@ struct ATTRIBUTES_API FInt32Attr : public FBaseAttr
5555

5656
void PostScriptConstruct();
5757

58+
FInt32ModifiedMCDelegate& GetOnModified() { return OnModified; }
59+
const FInt32ModifiedMCDelegate& GetOnModified() const { return OnModified; }
60+
5861
private:
5962

60-
virtual void RefreshValue() override;
63+
virtual void InternalRefreshValue(FAttributeModifiedInfo&& ChangeInfo) override;
6164
};
6265

6366

0 commit comments

Comments
 (0)