void FWidgetBlueprintEditor::PasteWidgets() { TSet<FWidgetReference> Widgets = GetSelectedWidgets(); FWidgetReference Target = Widgets.Num() > 0 ? *Widgets.CreateIterator() : FWidgetReference(); FWidgetBlueprintEditorUtils::PasteWidgets(SharedThis(this), GetWidgetBlueprintObj(), Target, PasteDropLocation); //TODO UMG - Select the newly selected pasted widgets. }
void FUserDefinedStructureCompilerUtils::CompileStructs(class UBlueprint* Blueprint, class FCompilerResultsLog& MessageLog, bool bForceRecompileAll) { if (FStructureEditorUtils::StructureEditingEnabled() && Blueprint && Blueprint->UserDefinedStructures.Num()) { TSet<UBlueprint*> BlueprintsToRecompile; TArray<UBlueprintGeneratedStruct*> ChangedStructs; for (auto StructDescIter = Blueprint->UserDefinedStructures.CreateIterator(); StructDescIter; ++StructDescIter) { FBPStructureDescription& StructDesc = (*StructDescIter); if (UBlueprintGeneratedStruct* Struct = StructDesc.CompiledStruct) { if (FUserDefinedStructureCompilerInner::ShouldBeCompiled(StructDesc) || bForceRecompileAll) { ChangedStructs.Add(Struct); BlueprintsToRecompile.Add(Blueprint); } } else { StructDesc.CompiledStruct = FUserDefinedStructureCompilerInner::CreateNewStruct(StructDesc.Name, Blueprint); FUserDefinedStructureCompilerInner::InnerCompileStruct(StructDesc, GetDefault<UEdGraphSchema_K2>(), MessageLog); } } for (int32 StructIdx = 0; StructIdx < ChangedStructs.Num(); ++StructIdx) { FUserDefinedStructureCompilerInner::ReplaceStructWithTempDuplicate(ChangedStructs[StructIdx], BlueprintsToRecompile, ChangedStructs); ChangedStructs[StructIdx]->Status = EBlueprintStructureStatus::BSS_Dirty; } // COMPILE IN PROPER ORDER FUserDefinedStructureCompilerInner::BuildDependencyMapAndCompile(ChangedStructs, MessageLog); for (TObjectIterator<UK2Node_StructOperation> It(RF_Transient | RF_PendingKill | RF_ClassDefaultObject, true); It && ChangedStructs.Num(); ++It) { UK2Node_StructOperation* Node = *It; if (Node && !Node->HasAnyFlags(RF_Transient|RF_PendingKill)) { UBlueprintGeneratedStruct* StructInNode = Cast<UBlueprintGeneratedStruct>(Node->StructType); if (StructInNode && ChangedStructs.Contains(StructInNode)) { if (UBlueprint* FoundBlueprint = Node->GetBlueprint()) { Node->ReconstructNode(); BlueprintsToRecompile.Add(FoundBlueprint); } } } } for (auto BPIter = BlueprintsToRecompile.CreateIterator(); BPIter; ++BPIter) { FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(*BPIter); } } }
void CollectGarbageDelegates() { for (auto it = Delegates.CreateIterator(); it; ++it) { auto d = *it; if (!d->IsValid()) { delete d; it.RemoveCurrent(); } } }
void FPackageDependencyInfo::ResolveCircularDependenciesInnerFast() { int32 NumReResolves = 0; // We have a list of all packages the current package depends on. // And we iterate through the list as long as we won't update any package info. TSet<FPackageDependencyTrackingInfo*> ToBeProcessed; // Find packages that matters. for( auto ResolveIt = AllPackages.CreateIterator(); ResolveIt; ++ResolveIt ) { FPackageDependencyTrackingInfo* PkgInfo = *ResolveIt; if( PkgInfo && PkgInfo->DependentPackages.Num() ) { ToBeProcessed.Add( PkgInfo ); } } do { NumReResolves = 0; // Iterate through all valid packages. for( auto ResolveIt = ToBeProcessed.CreateIterator(); ResolveIt; ++ResolveIt ) { const int32 PackageIndex = 0; FPackageDependencyTrackingInfo* InPkgInfo = *ResolveIt; // Iterate through all dependent packages and update time if necessary. for( auto DepPkgIt = InPkgInfo->DependentPackages.CreateIterator(); DepPkgIt; ++DepPkgIt ) { NumResolveIterations++; FPackageDependencyTrackingInfo* DepPkgInfo = DepPkgIt.Value(); if( DepPkgInfo != NULL ) { if( InPkgInfo->DependentTimeStamp < DepPkgInfo->DependentTimeStamp ) { InPkgInfo->DependentTimeStamp = DepPkgInfo->DependentTimeStamp; ResolvedCircularDependencies.Add(InPkgInfo); NumCirculars++; // We updated a timestamp, so we need to run the iteration once again to make sure that other packages will be updated as well. NumReResolves++; } } } } NumResolvePasses++; } while( NumReResolves > 0 ); }
bool FWidgetBlueprintEditor::CanPasteWidgets() { TSet<FWidgetReference> Widgets = GetSelectedWidgets(); if ( Widgets.Num() == 1 ) { FWidgetReference Target = *Widgets.CreateIterator(); const bool bIsPanel = Cast<UPanelWidget>(Target.GetTemplate()) != nullptr; return bIsPanel; } else if ( Widgets.Num() == 0 ) { if ( GetWidgetBlueprintObj()->WidgetTree->RootWidget == nullptr ) { return true; } } return false; }
void FUserDefinedStructureCompilerUtils::CompileStruct(class UUserDefinedStruct* Struct, class FCompilerResultsLog& MessageLog, bool bForceRecompile) { if (FStructureEditorUtils::UserDefinedStructEnabled() && Struct) { TSet<UBlueprint*> BlueprintsThatHaveBeenRecompiled; TSet<UBlueprint*> BlueprintsToRecompile; TArray<UUserDefinedStruct*> ChangedStructs; if (FUserDefinedStructureCompilerInner::ShouldBeCompiled(Struct) || bForceRecompile) { ChangedStructs.Add(Struct); } for (int32 StructIdx = 0; StructIdx < ChangedStructs.Num(); ++StructIdx) { UUserDefinedStruct* ChangedStruct = ChangedStructs[StructIdx]; if (ChangedStruct) { FStructureEditorUtils::BroadcastPreChange(ChangedStruct); FUserDefinedStructureCompilerInner::ReplaceStructWithTempDuplicate(ChangedStruct, BlueprintsToRecompile, ChangedStructs); ChangedStruct->Status = EUserDefinedStructureStatus::UDSS_Dirty; } } // COMPILE IN PROPER ORDER FUserDefinedStructureCompilerInner::BuildDependencyMapAndCompile(ChangedStructs, MessageLog); // UPDATE ALL THINGS DEPENDENT ON COMPILED STRUCTURES for (TObjectIterator<UK2Node> It(RF_Transient | RF_PendingKill | RF_ClassDefaultObject, true); It && ChangedStructs.Num(); ++It) { bool bReconstruct = false; UK2Node* Node = *It; if (Node && !Node->HasAnyFlags(RF_Transient | RF_PendingKill)) { // If this is a struct operation node operation on the changed struct we must reconstruct if (UK2Node_StructOperation* StructOpNode = Cast<UK2Node_StructOperation>(Node)) { UUserDefinedStruct* StructInNode = Cast<UUserDefinedStruct>(StructOpNode->StructType); if (StructInNode && ChangedStructs.Contains(StructInNode)) { bReconstruct = true; } } if (!bReconstruct) { // Look through the nodes pins and if any of them are split and the type of the split pin is a user defined struct we need to reconstruct for (UEdGraphPin* Pin : Node->Pins) { if (Pin->SubPins.Num() > 0) { UUserDefinedStruct* StructType = Cast<UUserDefinedStruct>(Pin->PinType.PinSubCategoryObject.Get()); if (StructType && ChangedStructs.Contains(StructType)) { bReconstruct = true; break; } } } } } if (bReconstruct) { if (UBlueprint* FoundBlueprint = Node->GetBlueprint()) { // The blueprint skeleton needs to be updated before we reconstruct the node // or else we may have member references that point to the old skeleton if (!BlueprintsThatHaveBeenRecompiled.Contains(FoundBlueprint)) { BlueprintsThatHaveBeenRecompiled.Add(FoundBlueprint); BlueprintsToRecompile.Remove(FoundBlueprint); FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(FoundBlueprint); } Node->ReconstructNode(); } } } for (auto BPIter = BlueprintsToRecompile.CreateIterator(); BPIter; ++BPIter) { FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(*BPIter); } for (auto ChangedStruct : ChangedStructs) { if (ChangedStruct) { FStructureEditorUtils::BroadcastPostChange(ChangedStruct); ChangedStruct->MarkPackageDirty(); } } } }
void AFogOfWarWorker::UpdateFowTexture() { Manager->LastFrameTextureData = TArray<FColor>(Manager->TextureData); uint32 halfTextureSize = Manager->TextureSize / 2; int signedSize = (int)Manager->TextureSize; //For convenience.... TSet<FVector2D> texelsToBlur; int sightTexels = Manager->SightRange * Manager->SamplesPerMeter; float dividend = 100.0f / Manager->SamplesPerMeter; Manager->CurrentlyInSight.Reset(); for (auto Itr(Manager->FowActors.CreateIterator()); Itr; Itr++) { if (StopTaskCounter.GetValue() != 0) { return; } //Find actor position if (!*Itr) continue; FVector position = (*Itr)->GetActorLocation(); //We divide by 100.0 because 1 texel equals 1 meter of visibility-data. int posX = (int)(position.X / dividend) + halfTextureSize; int posY = (int)(position.Y / dividend) + halfTextureSize; float integerX, integerY; FVector2D fractions = FVector2D(modf(position.X / 50.0f, &integerX), modf(position.Y / 50.0f, &integerY)); FVector2D textureSpacePos = FVector2D(posX, posY); int size = (int)Manager->TextureSize; FCollisionQueryParams queryParams(FName(TEXT("FOW trace")), false, (*Itr)); int halfKernelSize = (Manager->blurKernelSize - 1) / 2; //Store the positions we want to blur for (int y = posY - sightTexels - halfKernelSize; y <= posY + sightTexels + halfKernelSize; y++) { for (int x = posX - sightTexels - halfKernelSize; x <= posX + sightTexels + halfKernelSize; x++) { if (x > 0 && x < size && y > 0 && y < size) { texelsToBlur.Add(FIntPoint(x, y)); } } } //Unveil the positions our actors are currently looking at for (int y = posY - sightTexels; y <= posY + sightTexels; y++) { for (int x = posX - sightTexels; x <= posX + sightTexels; x++) { //Kernel for radial sight if (x > 0 && x < size && y > 0 && y < size) { FVector2D currentTextureSpacePos = FVector2D(x, y); int length = (int)(textureSpacePos - currentTextureSpacePos).Size(); if (length <= sightTexels) { FVector currentWorldSpacePos = FVector( ((x - (int)halfTextureSize)) * dividend, ((y - (int)halfTextureSize)) * dividend, position.Z); //CONSIDER: This is NOT the most efficient way to do conditional unfogging. With long view distances and/or a lot of actors affecting the FOW-data //it would be preferrable to not trace against all the boundary points and internal texels/positions of the circle, but create and cache "rasterizations" of //viewing circles (using Bresenham's midpoint circle algorithm) for the needed sightranges, shift the circles to the actor's location //and just trace against the boundaries. //We would then use Manager->GetWorld()->LineTraceSingle() and find the first collision texel. Having found the nearest collision //for every ray we would unveil all the points between the collision and origo using Bresenham's Line-drawing algorithm. //However, the tracing doesn't seem like it takes much time at all (~0.02ms with four actors tracing circles of 18 texels each), //it's the blurring that chews CPU.. if (!Manager->GetWorld()->LineTraceTestByObjectType(position, currentWorldSpacePos, ECC_WorldStatic, queryParams)) //if (!Manager->GetWorld()->LineTraceTestByChannel(position, currentWorldSpacePos, ECC_WorldStatic, queryParams)) { //Unveil the positions we are currently seeing Manager->UnfoggedData[x + y * Manager->TextureSize] = true; //Store the positions we are currently seeing. Manager->CurrentlyInSight.Add(FVector2D(x, y)); } } } } } } if (Manager->GetIsBlurEnabled()) { //Horizontal blur pass int offset = floorf(Manager->blurKernelSize / 2.0f); for (auto Itr(texelsToBlur.CreateIterator()); Itr; ++Itr) { int x = (Itr)->IntPoint().X; int y = (Itr)->IntPoint().Y; float sum = 0; for (int i = 0; i < Manager->blurKernelSize; i++) { int shiftedIndex = i - offset; if (x + shiftedIndex >= 0 && x + shiftedIndex <= signedSize - 1) { if (Manager->UnfoggedData[x + shiftedIndex + (y * signedSize)]) { //If we are currently looking at a position, unveil it completely if (Manager->CurrentlyInSight.Contains(FVector2D(x + shiftedIndex, y))) { sum += (Manager->blurKernel[i] * 255); } //If this is a previously discovered position that we're not currently looking at, put it into a "shroud of darkness". else { sum += (Manager->blurKernel[i] * 100); } } } } Manager->HorizontalBlurData[x + y * signedSize] = (uint8)sum; } //Vertical blur pass for (auto Itr(texelsToBlur.CreateIterator()); Itr; ++Itr) { int x = (Itr)->IntPoint().X; int y = (Itr)->IntPoint().Y; float sum = 0; for (int i = 0; i < Manager->blurKernelSize; i++) { int shiftedIndex = i - offset; if (y + shiftedIndex >= 0 && y + shiftedIndex <= signedSize - 1) { sum += (Manager->blurKernel[i] * Manager->HorizontalBlurData[x + (y + shiftedIndex) * signedSize]); } } Manager->TextureData[x + y * signedSize] = FColor((uint8)FMath::Max(sum, 100.0f), (uint8)FMath::Max(sum, 100.0f), (uint8)FMath::Max(sum, 100.0f), 255); } } else { for (int y = 0; y < signedSize; y++) { for (int x = 0; x < signedSize; x++) { if (Manager->UnfoggedData[x + (y * signedSize)]) { if (Manager->CurrentlyInSight.Contains(FVector2D(x, y))) { Manager->TextureData[x + y * signedSize] = FColor((uint8)255, (uint8)255, (uint8)255, 255); } else { Manager->TextureData[x + y * signedSize] = FColor((uint8)100, (uint8)100, (uint8)100, 255); } } } } } Manager->bHasFOWTextureUpdate = true; }
void FEnumEditorUtils::BroadcastChanges(const UUserDefinedEnum* Enum, const TArray<TPair<FName, int8>>& OldNames, bool bResolveData) { check(NULL != Enum); if (bResolveData) { FArchiveEnumeratorResolver EnumeratorResolver(Enum, OldNames); TArray<UClass*> ClassesToCheck; for (TObjectIterator<UByteProperty> PropertyIter; PropertyIter; ++PropertyIter) { const UByteProperty* ByteProperty = *PropertyIter; if (ByteProperty && (Enum == ByteProperty->GetIntPropertyEnum())) { UClass* OwnerClass = ByteProperty->GetOwnerClass(); if (OwnerClass) { ClassesToCheck.Add(OwnerClass); } } } for (FObjectIterator ObjIter; ObjIter; ++ObjIter) { for (auto ClassIter = ClassesToCheck.CreateConstIterator(); ClassIter; ++ClassIter) { if (ObjIter->IsA(*ClassIter)) { ObjIter->Serialize(EnumeratorResolver); break; } } } } struct FNodeValidatorHelper { static bool IsValid(UK2Node* Node) { return Node && (NULL != Cast<UEdGraph>(Node->GetOuter())) && !Node->HasAnyFlags(RF_Transient | RF_PendingKill); } }; TSet<UBlueprint*> BlueprintsToRefresh; { //CUSTOM NODES DEPENTENT ON ENUM for (TObjectIterator<UK2Node> It(RF_Transient); It; ++It) { UK2Node* Node = *It; INodeDependingOnEnumInterface* NodeDependingOnEnum = Cast<INodeDependingOnEnumInterface>(Node); if (FNodeValidatorHelper::IsValid(Node) && NodeDependingOnEnum && (Enum == NodeDependingOnEnum->GetEnum())) { if (UBlueprint* Blueprint = Node->GetBlueprint()) { if (NodeDependingOnEnum->ShouldBeReconstructedAfterEnumChanged()) { Node->ReconstructNode(); } BlueprintsToRefresh.Add(Blueprint); } } } } for (TObjectIterator<UEdGraphPin> It(RF_Transient); It; ++It) { UEdGraphPin* Pin = *It; if (Pin && (Enum == Pin->PinType.PinSubCategoryObject.Get()) && (EEdGraphPinDirection::EGPD_Input == Pin->Direction)) { UK2Node* Node = Cast<UK2Node>(Pin->GetOuter()); if (FNodeValidatorHelper::IsValid(Node)) { if (UBlueprint* Blueprint = Node->GetBlueprint()) { if (INDEX_NONE == Enum->FindEnumIndex(*Pin->DefaultValue)) { Pin->Modify(); if (Blueprint->BlueprintType == BPTYPE_Interface) { Pin->DefaultValue = Enum->GetEnumName(0); } else { Pin->DefaultValue = FEnumEditorUtilsHelper::InvalidName(); } Node->PinDefaultValueChanged(Pin); BlueprintsToRefresh.Add(Blueprint); } } } } } for (auto It = BlueprintsToRefresh.CreateIterator(); It; ++It) { FBlueprintEditorUtils::MarkBlueprintAsModified(*It); (*It)->BroadcastChanged(); } FEnumEditorManager::Get().PostChange(Enum, EEnumEditorChangeInfo::Changed); }
/** * Uses test maps in Engine and/or game content folder which are populated with a few blueprint instances * See InstanceTestMaps entries in the [Automation.Blueprint] config sections * For all blueprint instances in the map: * Duplicates the instance * Compares the duplicated instance properties to the original instance properties */ bool FBlueprintInstancesTest::RunTest(const FString& InParameters) { FBlueprintAutomationTestUtilities::LoadMap(InParameters); // Pause before running test ADD_LATENT_AUTOMATION_COMMAND(FDelayLatentCommand(2.f)); // Grab BP instances from map TSet<AActor*> BlueprintInstances; for ( FActorIterator It(GWorld); It; ++It ) { AActor* Actor = *It; UClass* ActorClass = Actor->GetClass(); if (ActorClass->ClassGeneratedBy && ActorClass->ClassGeneratedBy->IsA( UBlueprint::StaticClass() ) ) { BlueprintInstances.Add(Actor); } } bool bPropertiesMatch = true; FCompilerResultsLog ResultLog; TSet<UPackage*> PackagesUserRefusedToFullyLoad; ObjectTools::FPackageGroupName PGN; for (auto BpIter = BlueprintInstances.CreateIterator(); BpIter; ++BpIter ) { AActor* BPInstance = *BpIter; UObject* BPInstanceOuter = BPInstance ? BPInstance->GetOuter() : NULL; TMap<FString,FString> BPNativePropertyValues; BPInstance->GetNativePropertyValues(BPNativePropertyValues); // Grab the package and save out its dirty state UPackage* ActorPackage = BPInstance->GetOutermost(); FBlueprintAutomationTestUtilities::FPackageCleaner Cleaner(ActorPackage); // Use this when duplicating the object to keep a list of everything that was duplicated //TMap<UObject*, UObject*> DuplicatedObjectList; FObjectDuplicationParameters Parameters(BPInstance, BPInstanceOuter); //Parameters.CreatedObjects = &DuplicatedObjectList; Parameters.DestName = MakeUniqueObjectName( BPInstanceOuter, AActor::StaticClass(), BPInstance->GetFName() ); // Duplicate the object AActor* ClonedInstance = Cast<AActor>(StaticDuplicateObjectEx(Parameters)); if (!FBlueprintAutomationTestUtilities::CompareObjects(BPInstance, ClonedInstance, ResultLog)) { bPropertiesMatch = false; break; } // Ensure we can't save package in editor FBlueprintAutomationTestUtilities::DontSavePackage(ActorPackage); } // Start a new map for now // @todo find a way return to previous map thats a 100% reliably GEditor->CreateNewMapForEditing(); ADD_LATENT_AUTOMATION_COMMAND(FDelayLatentCommand(2.f)); return bPropertiesMatch; }