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);
		}
	}
}
Пример #3
0
	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();
			}
		}
	}
}
Пример #7
0
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;
}
Пример #8
0
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;
}