void FAnimBlueprintNodeOptionalPinManager::PostRemovedOldPin(FOptionalPinFromProperty& Record, int32 ArrayIndex, UProperty* Property, uint8* PropertyAddress) const { check(PropertyAddress != NULL); check(!Record.bShowPin); if (Record.bCanToggleVisibility && (OldPins != NULL)) { const FString OldPinName = (ArrayIndex != INDEX_NONE) ? FString::Printf(TEXT("%s_%d"), *(Record.PropertyName.ToString()), ArrayIndex) : Record.PropertyName.ToString(); if (UEdGraphPin* OldPin = OldPinMap.FindRef(OldPinName)) { // Pin was visible but it's now hidden UObjectProperty* ObjectProperty = Cast<UObjectProperty>(Property); UAnimGraphNode_AssetPlayerBase* AssetPlayerNode = Cast<UAnimGraphNode_AssetPlayerBase>(BaseNode); if (AssetPlayerNode && ObjectProperty && ObjectProperty->PropertyClass->IsChildOf<UAnimationAsset>()) { // If this is an anim asset pin, dont store a hard reference to the asset in the node, as this ends up referencing things we might not want to load any more UObject* AssetReference = AssetPlayerNode->GetAssetReferenceForPinRestoration(); if (AssetReference) { ObjectProperty->SetObjectPropertyValue(PropertyAddress, AssetReference); } } else { // Convert DefaultValue/DefaultValueObject and push back into the struct FBlueprintEditorUtils::ImportKismetDefaultValueToProperty(OldPin, Property, PropertyAddress, BaseNode); } } } }
void FAnimBlueprintNodeOptionalPinManager::PostInitNewPin(UEdGraphPin* Pin, FOptionalPinFromProperty& Record, int32 ArrayIndex, UProperty* Property, uint8* PropertyAddress) const { check(PropertyAddress != NULL); check(Record.bShowPin); if (OldPins == NULL) { // Initial construction of a visible pin; copy values from the struct FBlueprintEditorUtils::ExportPropertyToKismetDefaultValue(Pin, Property, PropertyAddress, BaseNode); } else if (Record.bCanToggleVisibility) { if (UEdGraphPin* OldPin = OldPinMap.FindRef(Pin->PinName)) { // Was already visible } else { // Showing a pin that was previously hidden, during a reconstruction UObjectProperty* ObjectProperty = Cast<UObjectProperty>(Property); UAnimGraphNode_AssetPlayerBase* AssetPlayerNode = Cast<UAnimGraphNode_AssetPlayerBase>(BaseNode); const bool bIsAnimationAsset = AssetPlayerNode != nullptr && ObjectProperty != nullptr && ObjectProperty->PropertyClass->IsChildOf<UAnimationAsset>(); // Store the old reference to an animation asset in the node's asset reference if (bIsAnimationAsset) { AssetPlayerNode->SetAssetReferenceForPinRestoration(ObjectProperty->GetObjectPropertyValue(PropertyAddress)); } // Convert the struct property into DefaultValue/DefaultValueObject FBlueprintEditorUtils::ExportPropertyToKismetDefaultValue(Pin, Property, PropertyAddress, BaseNode); // clear the asset reference on the node if (bIsAnimationAsset) { ObjectProperty->SetObjectPropertyValue(PropertyAddress, nullptr); } } } }
bool ANUTActor::NotifyControlMessage(UNetConnection* Connection, uint8 MessageType, FInBunch& Bunch) { bool bHandledMessage = false; if (MessageType == NMT_NUTControl) { uint8 CmdType = 0; FString Command; FNetControlMessage<NMT_NUTControl>::Receive(Bunch, CmdType, Command); // Console command if (CmdType == ENUTControlCommand::Command_NoResult || CmdType == ENUTControlCommand::Command_SendResult) { UE_LOG(LogUnitTest, Log, TEXT("NMT_NUTControl: Executing command: %s"), *Command); FStringOutputDevice CmdResult; CmdResult.SetAutoEmitLineTerminator(true); bool bCmdSuccess = false; bCmdSuccess = GEngine->Exec(GetWorld(), *Command, CmdResult); UE_LOG(LogUnitTest, Log, TEXT("NMT_NUTControl: Command result: %s"), *CmdResult); bool bSendResult = CmdType == ENUTControlCommand::Command_SendResult; if (bSendResult) { uint8 ReturnCmdType = (bCmdSuccess ? ENUTControlCommand::CommandResult_Success : ENUTControlCommand::CommandResult_Failed); FNetControlMessage<NMT_NUTControl>::Send(Connection, ReturnCmdType, CmdResult); } } // Console command result else if (CmdType == ENUTControlCommand::CommandResult_Failed || CmdType == ENUTControlCommand::CommandResult_Success) { bool bCmdSuccess = CmdType == ENUTControlCommand::CommandResult_Success; if (bCmdSuccess) { UE_LOG(LogUnitTest, Log, TEXT("NMT_NUTControl: Got command result:")); UE_LOG(LogUnitTest, Log, TEXT("%s"), *Command); } else { UE_LOG(LogUnitTest, Log, TEXT("NMT_NUTControl: Failed to execute command")); } } // Ping request else if (CmdType == ENUTControlCommand::Ping) { uint8 TempCmdType = ENUTControlCommand::Pong; FString Dud; FNetControlMessage<NMT_NUTControl>::Send(Connection, TempCmdType, Dud); } // Pong reply - this should only be implemented by custom unit tests; hence the assert else if (CmdType == ENUTControlCommand::Pong) { UNIT_ASSERT(false); } // Custom implemented events, with the result triggered through 'NotifyEvent' else if (CmdType == ENUTControlCommand::WatchEvent) { // NOTE: Only the last NetConnection to request a WatchEvent, will receive notifications EventWatcher = Connection; // Watch for the end of seamless travel if (Command == TEXT("SeamlessTravelEnd")) { FCoreUObjectDelegates::PostLoadMap.AddStatic(&ANUTActor::NotifyPostLoadMap); } } // Event watch notification - should only be implemented by custom unit tests else if (CmdType == ENUTControlCommand::NotifyEvent) { UNIT_ASSERT(false); } // Create an actor instance (the 'summon' console command, doesn't work without a cheat manager) else if (CmdType == ENUTControlCommand::Summon) { const TCHAR* Cmd = *Command; FString SpawnClassName = FParse::Token(Cmd, false); bool bForceBeginPlay = FParse::Param(Cmd, TEXT("ForceBeginPlay")); // Hack specifically for getting the GameplayDebugger working - think the mainline code is broken bool bGameplayDebuggerHack = FParse::Param(Cmd, TEXT("GameplayDebuggerHack")); UClass* SpawnClass = FindObject<UClass>(NULL, *SpawnClassName); if (SpawnClass != NULL) { FActorSpawnParameters SpawnParms; SpawnParms.Owner = GetOwner(); AActor* NewActor = GetWorld()->SpawnActor<AActor>(SpawnClass, SpawnParms); if (NewActor != NULL) { UE_LOG(LogUnitTest, Log, TEXT("Successfully summoned actor of class '%s'"), *SpawnClassName); if (bForceBeginPlay && !NewActor->HasActorBegunPlay()) { UE_LOG(LogUnitTest, Log, TEXT("Forcing call to 'BeginPlay' on newly spawned actor.")); NewActor->BeginPlay(); } if (bGameplayDebuggerHack) { // Assign the LocalPlayerOwner property, to the PC owning this NUTActor, using reflection (to avoid dependency) UObjectProperty* LocalPlayerOwnerProp = FindField<UObjectProperty>(NewActor->GetClass(), TEXT("LocalPlayerOwner")); if (LocalPlayerOwnerProp != NULL) { LocalPlayerOwnerProp->SetObjectPropertyValue( LocalPlayerOwnerProp->ContainerPtrToValuePtr<UObject*>(NewActor), GetOwner()); } else { UE_LOG(LogUnitTest, Log, TEXT("WARNING: Failed to find 'LocalPlayerOwner' property. Unit test broken.")); } // Also hack-disable ticking, so that the replicator doesn't spawn a second replicator NewActor->SetActorTickEnabled(false); } } else { UE_LOG(LogUnitTest, Log, TEXT("SpawnActor failed for class '%s'"), *Command); } } else { UE_LOG(LogUnitTest, Log, TEXT("Could not find actor class '%s'"), *Command); } } // Suspend the game, until a resume request is received (used for giving time, to attach a debugger) else if (CmdType == ENUTControlCommand::SuspendProcess) { UE_LOG(LogUnitTest, Log, TEXT("Suspend start.")); // Setup a named pipe, to monitor for the resume request FString ResumePipeName = FString::Printf(TEXT("%s%u"), NUT_SUSPEND_PIPE, FPlatformProcess::GetCurrentProcessId()); FPlatformNamedPipe ResumePipe; bool bPipeCreated = ResumePipe.Create(ResumePipeName, true, false); if (bPipeCreated) { if (!ResumePipe.OpenConnection()) { UE_LOG(LogUnitTest, Log, TEXT("WARNING: Failed to open pipe connection.")); } } else { UE_LOG(LogUnitTest, Log, TEXT("WARNING: Failed to create resume pipe.")); } // Spin/sleep (effectively suspended) until a resume request is received while (true) { if (bPipeCreated && ResumePipe.IsReadyForRW()) { int32 ResumeVal = 0; if (ResumePipe.ReadInt32(ResumeVal) && !!ResumeVal) { UE_LOG(LogUnitTest, Log, TEXT("Got resume request.")); break; } } FPlatformProcess::Sleep(1.0f); } ResumePipe.Destroy(); UE_LOG(LogUnitTest, Log, TEXT("Suspend end.")); } bHandledMessage = true; } return bHandledMessage; }