/** * Returns a pointer to the duplicate of a given object, creating the duplicate object if necessary. * * @param Object the object to find a duplicate for * * @return a pointer to the duplicate of the specified object */ UObject* FDuplicateDataWriter::GetDuplicatedObject(UObject* Object, bool bCreateIfMissing) { UObject* Result = NULL; if (IsValid(Object)) { // Check for an existing duplicate of the object. FDuplicatedObject DupObjectInfo = DuplicatedObjectAnnotation.GetAnnotation( Object ); if( !DupObjectInfo.IsDefault() ) { Result = DupObjectInfo.DuplicatedObject; } else if (bCreateIfMissing) { // Check to see if the object's outer is being duplicated. UObject* DupOuter = GetDuplicatedObject(Object->GetOuter()); if(DupOuter != NULL) { // The object's outer is being duplicated, create a duplicate of this object. UObject* NewEmptyDuplicate = StaticConstructObject_Internal(Object->GetClass(), DupOuter, Object->GetFName(), ApplyFlags | Object->GetMaskedFlags(FlagMask), ApplyInternalFlags | (Object->GetInternalFlags() & InternalFlagMask), Object->GetArchetype(), true, InstanceGraph); Result = AddDuplicate(Object, NewEmptyDuplicate); } } } return Result; }
FArchive& FDuplicateDataReader::operator<<( UObject*& Object ) { UObject* SourceObject = Object; Serialize(&SourceObject,sizeof(UObject*)); FDuplicatedObject ObjectInfo = SourceObject ? DuplicatedObjectAnnotation.GetAnnotation(SourceObject) : FDuplicatedObject(); if( !ObjectInfo.IsDefault() ) { Object = ObjectInfo.DuplicatedObject; } else { Object = SourceObject; } return *this; }
/** * Places a new duplicate in the DuplicatedObjects map as well as the UnserializedObjects list * * @param SourceObject the original version of the object * @param DuplicateObject the copy of the object * * @return a pointer to the copy of the object */ UObject* FDuplicateDataWriter::AddDuplicate(UObject* SourceObject,UObject* DupObject) { if ( DupObject && !DupObject->IsTemplate() ) { // Make sure the duplicated object is prepared to postload DupObject->SetFlags(RF_NeedPostLoad|RF_NeedPostLoadSubobjects); } // Check for an existing duplicate of the object; if found, use that one instead of creating a new one. FDuplicatedObject Info = DuplicatedObjectAnnotation.GetAnnotation( SourceObject ); if ( Info.IsDefault() ) { DuplicatedObjectAnnotation.AddAnnotation( SourceObject, FDuplicatedObject( DupObject ) ); } else { Info.DuplicatedObject = DupObject; } UnserializedObjects.Add(SourceObject); return DupObject; }