Engine verion: 4.25.4
Description
In previous engine versions, adapters like FArchiveUObjectFromStructuredArchive would close automatically on destruction, while now they don’t, thus requiring a manual closure.
This is done correcty is places like in SavePackage.cpp:5326:
FArchiveUObjectFromStructuredArchive Adapter(ExportSlot);
Export.Object->Serialize(Adapter.GetArchive());
Adapter.Close();
or Class.cpp:2722:
FArchiveUObjectFromStructuredArchive Adapter(Slot);
FArchive& Ar = Adapter.GetArchive();
// [...]
Adapter.Close();
but after the changes done in some places, the closure is now missing, like in PropertyMulticastDelegate:382:
void FMulticastInlineDelegateProperty::SerializeItem(FStructuredArchive::FSlot Slot, void* Value, void const* Defaults) const
{
FArchiveUObjectFromStructuredArchive Adapter(Slot);
FArchive& Ar = Adapter.GetArchive();
Ar << *GetPropertyValuePtr(Value);
}
similar missing closures are found in LinkerLoad and PropertyStruct too, among maybe others.
Consequences
In some cases, using a StructuredArchive for serialization, this check in ArchiveFromStructuredArchive.cpp triggers:
FArchiveFromStructuredArchiveImpl::~FArchiveFromStructuredArchiveImpl()
{
checkf(!Pimpl->bPendingSerialize, TEXT("Archive adapters must be closed before destruction"));
}
since the adapter wasn’t closed.
Suggested solutions
The most straightforward way would be to just commit the stuff in the destructor (if already closed, it will do nothing), like this:
FArchiveFromStructuredArchiveImpl::~FArchiveFromStructuredArchiveImpl()
{
Commit(); // or Close()
checkf(!Pimpl->bPendingSerialize, TEXT("Archive adapters must be closed before destruction"));
}
maybe removing the check too. For the moment we’ll go this way.
On the other hand, if the “auto close” was removed for a valid reason and it isn’t appropriate to replace it in, all usages of FArchiveFromStructuredArchive and childs should be located, checked and eventually fixed.