/** * Finds the outermost package and marks it dirty */ bool UObjectBaseUtility::MarkPackageDirty() const { // since transient objects will never be saved into a package, there is no need to mark a package dirty // if we're transient if ( !HasAnyFlags(RF_Transient) ) { UPackage* Package = GetOutermost(); if( Package != NULL ) { // It is against policy to dirty a map or package during load in the Editor, to enforce this policy // we explicitly disable the ability to dirty a package or map during load. Commandlets can still // set the dirty state on load. if( IsRunningCommandlet() || (GIsEditor && !GIsEditorLoadingPackage && !GIsPlayInEditorWorld && !IsInAsyncLoadingThread() #if WITH_HOT_RELOAD && !GIsHotReload #endif // WITH_HOT_RELOAD #if WITH_EDITORONLY_DATA && !Package->bIsCookedForEditor // Cooked packages can't be modified nor marked as dirty #endif )) { const bool bIsDirty = Package->IsDirty(); // We prevent needless re-dirtying as this can be an expensive operation. if( !bIsDirty ) { Package->SetDirtyFlag(true); } // Always call PackageMarkedDirtyEvent, even when the package is already dirty Package->PackageMarkedDirtyEvent.Broadcast(Package, bIsDirty); return true; } else { // notify the caller that the request to mark the package as dirty was suppressed return false; } } } return true; }
void GetObjectsWithAnyMarks(TArray<UObject *>& Results, EObjectMark Marks) { // We don't want to return any objects that are currently being background loaded unless we're using the object iterator during async loading. EObjectFlags ExclusionFlags = RF_Unreachable; if (!IsInAsyncLoadingThread()) { ExclusionFlags = EObjectFlags(ExclusionFlags | RF_AsyncLoading); } const TMap<const UObjectBase *, FObjectMark>& Map = MarkAnnotation.GetAnnotationMap(); Results.Empty(Map.Num()); for (TMap<const UObjectBase *, FObjectMark>::TConstIterator It(Map); It; ++It) { if (It.Value().Marks & Marks) { UObject* Item = (UObject*)It.Key(); if (!Item->HasAnyFlags(ExclusionFlags)) { Results.Add(Item); } } } }