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
0 commit comments