UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
TransactionallySafeArchiveWriter.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "AutoRTFM.h"
6#include "CoreTypes.h"
7#include "Containers/Array.h"
11#include "Templates/UniquePtr.h"
12
25{
27
28public:
30 {
31 check(InnerArchive);
32 check(InnerArchive->IsSaving());
33 SetIsSaving(true);
34 }
35
37 {
38 if (InnerArchive && bRegisteredCommitHandler)
39 {
40 // Our wrapper is going away, so move everything into a lambda-capture for safekeeping.
41 AutoRTFM::PopOnCommitHandler(this);
42 AutoRTFM::PushOnCommitHandler(this, [Archive = InnerArchive.Release(), WriteBuffer = MoveTemp(DeferredWrites), bFlush = bFlushRequested]() mutable
43 {
44 DoDeferredWrites(*Archive, WriteBuffer, bFlush);
45 delete Archive;
46 });
47 }
48 }
49
55 {
56 check(!AutoRTFM::IsTransactional());
57 return MoveTemp(InnerArchive);
58 }
59
60 virtual FString GetArchiveName() const override
61 {
62 return InnerArchive->GetArchiveName();
63 }
64
65 virtual void Seek(int64 InPos) final
66 {
68 }
69
70 virtual int64 Tell() final
71 {
73 return 0;
74 }
75
77 virtual void Flush() override
78 {
79 if (MaybeRegisterCommitHandler())
80 {
81 // Defer the flush until commit time.
82 bFlushRequested = true;
83 }
84 else
85 {
86 // We aren't in a transaction and don't have a commit handler, so nothing needs to be done. Forward to the inner archive.
87 InnerArchive->Flush();
88 }
89 }
90
91 virtual void Serialize(void* Data, int64 Num) override
92 {
93 check(InnerArchive);
94
95 if (MaybeRegisterCommitHandler())
96 {
97 // Defer serialization until commit time.
98 DeferredWrites.Append(static_cast<uint8*>(Data), IntCastChecked<DeferredWriteBuffer::SizeType>(Num));
99 }
100 else
101 {
102 // We aren't in a transaction and don't have a commit handler, so nothing needs to be done. Forward to the inner archive.
103 check(DeferredWrites.IsEmpty());
104 InnerArchive->Serialize(Data, Num);
105 }
106 }
107
108private:
109 bool MaybeRegisterCommitHandler()
110 {
111 // Returns true if a commit handler is in use.
112 if (bRegisteredCommitHandler)
113 {
114 // If we already have a registered commit handler, we are either within a transaction or are committing/aborting.
115 check(AutoRTFM::IsTransactional() || AutoRTFM::IsCommittingOrAborting());
116 return true;
117 }
118 else if (AutoRTFM::IsTransactional())
119 {
120 // If we don't have a commit handler set up yet, but find ourselves running transactionally, set up the commit handler now.
121 RegisterCommitHandler();
122 return true;
123 }
124 // We don't need a commit handler and can forward on requests directly to the inner archive.
125 return false;
126 }
127
128 void RegisterCommitHandler()
129 {
130 check(!bRegisteredCommitHandler);
131 bRegisteredCommitHandler = true;
132
133 AutoRTFM::PushOnCommitHandler(this, [this]
134 {
135 DoDeferredWrites(*InnerArchive, DeferredWrites, bFlushRequested);
136 bRegisteredCommitHandler = false;
137 });
138 }
139
140 static void DoDeferredWrites(FArchive& Archive, DeferredWriteBuffer& WriteBuffer, bool& bFlushRequested)
141 {
142 Archive.Serialize(WriteBuffer.GetData(), WriteBuffer.NumBytes());
143 WriteBuffer.Reset();
144
145 if (bFlushRequested)
146 {
147 Archive.Flush();
148 bFlushRequested = false;
149 }
150 }
151
152 TUniquePtr<FArchive> InnerArchive;
153 DeferredWriteBuffer DeferredWrites;
154 bool bRegisteredCommitHandler = false;
155 bool bFlushRequested = false;
156};
#define check(expr)
Definition AssertionMacros.h:314
#define unimplemented()
Definition AssertionMacros.h:321
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
@ Num
Definition MetalRHIPrivate.h:234
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint8_t uint8
Definition binka_ue_file_header.h:8
Definition Archive.h:1208
virtual CORE_API void SetIsSaving(bool bInIsSaving)
Definition Archive.cpp:1523
virtual void Serialize(void *V, int64 Length)
Definition Archive.h:1689
UE_FORCEINLINE_HINT bool IsSaving() const
Definition Archive.h:248
virtual CORE_API FString GetArchiveName() const
Definition Archive.cpp:335
virtual void Flush()
Definition Archive.h:1842
Definition TransactionallySafeArchiveWriter.h:25
FTransactionallySafeArchiveWriter(TUniquePtr< FArchive > Ar)
Definition TransactionallySafeArchiveWriter.h:29
virtual void Seek(int64 InPos) final
Definition TransactionallySafeArchiveWriter.h:65
virtual void Serialize(void *Data, int64 Num) override
Definition TransactionallySafeArchiveWriter.h:91
~FTransactionallySafeArchiveWriter()
Definition TransactionallySafeArchiveWriter.h:36
virtual void Flush() override
Definition TransactionallySafeArchiveWriter.h:77
virtual FString GetArchiveName() const override
Definition TransactionallySafeArchiveWriter.h:60
virtual int64 Tell() final
Definition TransactionallySafeArchiveWriter.h:70
TUniquePtr< FArchive > Release()
Definition TransactionallySafeArchiveWriter.h:54
UE_REWRITE bool IsEmpty() const
Definition Array.h:1133
void Append(const TArray< OtherElementType, OtherAllocatorType > &Source)
Definition Array.h:2412
Definition UniquePtr.h:107
T * Release()
Definition UniquePtr.h:334