Skip to content

Commit 5ae35cf

Browse files
committed
refactor FPropertyTypeName
1 parent ccc58d0 commit 5ae35cf

3 files changed

Lines changed: 73 additions & 21 deletions

File tree

libsave/include/SatisfactorySave/GameTypes/Properties/Base/PropertyTag.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace SatisfactorySave {
1818
};
1919

2020
struct SATISFACTORYSAVE_API PropertyTag {
21-
FPropertyTypeName TypeName;
21+
FPropertyTypeName_Data TypeName;
2222
FName Name;
2323
FName Type;
2424
int32_t Size = 0;
@@ -38,6 +38,7 @@ namespace SatisfactorySave {
3838

3939
void serialize(Archive& ar);
4040

41-
void SetType(FPropertyTypeName InFullType);
41+
protected:
42+
void SetType();
4243
};
4344
} // namespace SatisfactorySave

libsave/include/SatisfactorySave/GameTypes/UE/CoreUObject/UObject/PropertyTypeName.h

Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <cstdint>
4+
#include <span>
45
#include <vector>
56

67
#include "../../../../IO/Archive/Archive.h"
@@ -20,29 +21,38 @@ namespace SatisfactorySave {
2021
};
2122

2223
class SATISFACTORYSAVE_API FPropertyTypeName {
23-
public:
24-
std::vector<FPropertyTypeNameNode> Nodes;
24+
protected:
25+
std::span<FPropertyTypeNameNode> Nodes;
2526

26-
void serialize(Archive& ar) {
27-
if (ar.isIArchive()) {
28-
Nodes.clear();
29-
int32_t Remaining = 1;
30-
do {
31-
FPropertyTypeNameNode& Node = Nodes.emplace_back();
32-
ar << Node;
33-
Remaining += Node.InnerCount - 1;
34-
} while (Remaining > 0);
35-
} else {
36-
for (auto& Node : Nodes) {
37-
ar << Node;
38-
}
39-
}
27+
public:
28+
[[nodiscard]] inline bool IsEmpty() const {
29+
return Nodes.empty();
4030
}
4131

4232
[[nodiscard]] inline const FName& GetName() const {
4333
return Nodes[0].Name;
4434
}
4535

36+
[[nodiscard]] inline FPropertyTypeName GetParameter(int32_t ParamIndex) const {
37+
const FPropertyTypeNameNode& First = Nodes[0];
38+
if (ParamIndex < 0 || ParamIndex >= First.InnerCount) {
39+
return {};
40+
}
41+
int32_t ParamIdxPtr = 1;
42+
for (int32_t Skip = ParamIndex; Skip > 0; Skip--, ParamIdxPtr++) {
43+
Skip += Nodes[ParamIdxPtr].InnerCount;
44+
}
45+
int32_t Remaining = Nodes[ParamIdxPtr].InnerCount;
46+
int Length = 1;
47+
while (Remaining > 0) {
48+
Remaining += Nodes[ParamIdxPtr + Length].InnerCount - 1;
49+
Length++;
50+
}
51+
FPropertyTypeName Param;
52+
Param.Nodes = Nodes.subspan(ParamIdxPtr, Length);
53+
return Param;
54+
}
55+
4656
[[nodiscard]] inline FName GetParameterName(int32_t ParamIndex) const {
4757
const FPropertyTypeNameNode& First = Nodes[0];
4858
if (ParamIndex < 0 || ParamIndex >= First.InnerCount) {
@@ -55,4 +65,46 @@ namespace SatisfactorySave {
5565
return Nodes[ParamIdxPtr].Name;
5666
}
5767
};
68+
69+
/**
70+
* FPropertyTypeName_Data is a custom wrapper to actually hold the FPropertyTypeName data. Unreal internally
71+
* instead uses a global table, but here data should be held locally.
72+
*/
73+
class SATISFACTORYSAVE_API FPropertyTypeName_Data : public FPropertyTypeName {
74+
protected:
75+
std::vector<FPropertyTypeNameNode> Nodes_Data;
76+
77+
public:
78+
FPropertyTypeName_Data() = default;
79+
FPropertyTypeName_Data(const FPropertyTypeName_Data& other) : Nodes_Data(other.Nodes_Data) {
80+
Nodes = Nodes_Data;
81+
}
82+
FPropertyTypeName_Data& operator=(const FPropertyTypeName_Data& other) {
83+
if (this != &other) {
84+
Nodes_Data = other.Nodes_Data;
85+
Nodes = Nodes_Data;
86+
}
87+
return *this;
88+
}
89+
FPropertyTypeName_Data(FPropertyTypeName_Data&&) noexcept = default;
90+
FPropertyTypeName_Data& operator=(FPropertyTypeName_Data&&) noexcept = default;
91+
92+
void serialize(Archive& ar) {
93+
if (ar.isIArchive()) {
94+
Nodes_Data.clear();
95+
int32_t Remaining = 1;
96+
do {
97+
FPropertyTypeNameNode& Node = Nodes_Data.emplace_back();
98+
ar << Node;
99+
Remaining += Node.InnerCount - 1;
100+
} while (Remaining > 0);
101+
// Update Nodes span.
102+
Nodes = Nodes_Data;
103+
} else {
104+
for (auto& Node : Nodes_Data) {
105+
ar << Node;
106+
}
107+
}
108+
}
109+
};
58110
} // namespace SatisfactorySave

libsave/src/GameTypes/Properties/Base/PropertyTag.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ void SatisfactorySave::PropertyTag::serialize(Archive& ar) {
1919
if (ar.getSaveVersion() >= 53) {
2020
ar << TypeName;
2121
if (ar.isIArchive()) {
22-
SetType(TypeName);
22+
SetType();
2323
}
2424

2525
if (ar.isOArchive()) {
@@ -103,8 +103,7 @@ void SatisfactorySave::PropertyTag::serialize(Archive& ar) {
103103
}
104104
}
105105

106-
void SatisfactorySave::PropertyTag::SetType(FPropertyTypeName InFullType) {
107-
TypeName = std::move(InFullType);
106+
void SatisfactorySave::PropertyTag::SetType() {
108107
Type = TypeName.GetName();
109108

110109
if (Type.Number == /*NAME_NO_NUMBER_INTERNAL*/ 0) {

0 commit comments

Comments
 (0)