void FContentDirectoryMonitor::ExtractAssetsToDelete(TArray<FAssetData>& OutAssetsToDelete) { for (auto& Deletion : DeletedFiles) { for (const auto& AssetData : Utils::FindAssetsPertainingToFile(*Registry, Cache.GetDirectory() + Deletion.Filename.Get())) { OutAssetsToDelete.Add(AssetData); } // Let the cache know that we've dealt with this change (it will be imported in due course) Cache.CompleteTransaction(MoveTemp(Deletion)); } DeletedFiles.Empty(); }
virtual FArchive& operator<<(FStringAssetReference& Value) override { FArchive& Ar = *this; FString Path = Value.ToString(); Ar << Path; if (IsLoading()) { Value.SetPath(MoveTemp(Path)); } return Ar; }
/** Given a potential string, we produce a final FTextToken for it using the correct comparison mode (as inferred from the given string) */ FTextToken CreateTextTokenFromUnquotedString(FString InString) { ETextFilterTextComparisonMode TextComparisonMode = ETextFilterTextComparisonMode::Partial; // The final string may embed the TextCmpExact (+) operator, or the TextCmpAnchor operators (...) - test for those now so we can use the correct comparison mode if (InString.Len() > 0 && InString[0] == '+') { // Matched TextCmpExact - update the comparison mode and remove the + token from the start of the string TextComparisonMode = ETextFilterTextComparisonMode::Exact; InString.RemoveAt(0, 1, false); } else if (InString.Len() > 2 && InString.StartsWith(TEXT("..."), ESearchCase::CaseSensitive)) { // Matched TextCmpAnchor (pre-unary) - update the comparison mode and remove the ... token from the start of the string TextComparisonMode = ETextFilterTextComparisonMode::EndsWith; InString.RemoveAt(0, 3, false); } else if (InString.Len() > 2 && InString.EndsWith(TEXT("..."), ESearchCase::CaseSensitive)) { // Matched TextCmpAnchor (post-unary) - update the comparison mode and remove the ... token from the end of the string TextComparisonMode = ETextFilterTextComparisonMode::StartsWith; InString.RemoveAt(InString.Len() - 3, 3, false); } // To preserve behavior with the old text filter, the final string may also contain a TextCmpInvert (-) operator (after stripping the TextCmpExact or TextCmpAnchor tokens from the start) FTextToken::EInvertResult InvertResult = FTextToken::EInvertResult::No; if (InString.Len() > 0 && InString[0] == '-') { // Matched TextCmpInvert - remove the - token from the start of the string InvertResult = FTextToken::EInvertResult::Yes; InString.RemoveAt(0, 1, false); } // Finally, if our string starts and ends with a quote, we need to strip those off now if (InString.Len() > 1 && (InString[0] == '"' || InString[0] == '\'')) { const TCHAR QuoteChar = InString[0]; if (InString[InString.Len() - 1] == QuoteChar) { // Remove the quotes InString.RemoveAt(0, 1, false); InString.RemoveAt(InString.Len() - 1, 1, false); } } return FTextToken(MoveTemp(InString), TextComparisonMode, InvertResult); }
TSharedRef<IToolTip> FWidgetTemplateBlueprintClass::GetToolTip() const { FText Description; FString DescriptionStr = WidgetAssetData.GetTagValueRef<FString>( GET_MEMBER_NAME_CHECKED( UBlueprint, BlueprintDescription ) ); if ( !DescriptionStr.IsEmpty() ) { DescriptionStr.ReplaceInline( TEXT( "\\n" ), TEXT( "\n" ) ); Description = FText::FromString( MoveTemp(DescriptionStr) ); } else { Description = Name; } return IDocumentation::Get()->CreateToolTip( Description, nullptr, FString( TEXT( "Shared/Types/" ) ) + Name.ToString(), TEXT( "Class" ) ); }
void UCreatureAnimationAsset::PostLoad() { Super::PostLoad(); if (!creature_filename.IsEmpty() && AssetImportData && AssetImportData->GetSourceData().SourceFiles.Num() == 0) { // convert old source file path to proper UE4 Asset data system FAssetImportInfo Info; Info.Insert(FAssetImportInfo::FSourceFile(creature_filename)); AssetImportData->SourceData = MoveTemp(Info); } if (CreatureZipBinary.Num() != 0 || CreatureFileJSonData.IsEmpty() == false) { // load the animation data caches from the json data GatherAnimationData(); } }
bool FOnlineUserCloudOculus::ReadUserFile(const FUniqueNetId& UserId, const FString& FileName) { auto LoggedInPlayerId = OculusSubsystem.GetIdentityInterface()->GetUniquePlayerId(0); if (!LoggedInPlayerId.IsValid() || UserId != *LoggedInPlayerId) { UE_LOG_ONLINE(Warning, TEXT("Can only read data for logged in player")); return false; } FString BucketName; FString Key; if (!(FileName.Split(SEPARATOR, &BucketName, &Key))) { BucketName = DefaultBucket; Key = FileName; } OculusSubsystem.AddRequestDelegate( ovr_CloudStorage_Load(TCHAR_TO_UTF8(*BucketName), TCHAR_TO_UTF8(*Key)), FOculusMessageOnCompleteDelegate::CreateLambda([this, BucketName, Key, LoggedInPlayerId, FileName](ovrMessageHandle Message, bool bIsError) { ovrCloudStorageDataHandle response = ovr_Message_GetCloudStorageData(Message); check(BucketName == UTF8_TO_TCHAR(ovr_CloudStorageData_GetBucket(response))); check(Key == UTF8_TO_TCHAR(ovr_CloudStorageData_GetKey(response))); if (bIsError) { UE_LOG_ONLINE(Warning, TEXT("Failed to Load: %s%s%s"), *BucketName, *SEPARATOR, *Key); } else { int64 BlobSize = ovr_CloudStorageData_GetDataSize(response); const void* RawBlob = ovr_CloudStorageData_GetData(response); TArray<uint8> Blob; Blob.Insert(static_cast<const uint8 *>(RawBlob), BlobSize, 0); ReadCache.Add(FileName, MoveTemp(Blob)); } TriggerOnReadUserFileCompleteDelegates(!bIsError, *LoggedInPlayerId, FileName); })); return true; }
void FVideoCaptureProtocol::ProcessFrame(FCapturedFrameData Frame) { FVideoFrameData* Payload = Frame.GetPayload<FVideoFrameData>(); const int32 WriterIndex = Payload->WriterIndex; AVIWriters[WriterIndex]->DropFrames(Payload->Metrics.NumDroppedFrames); AVIWriters[WriterIndex]->Update(Payload->Metrics.TotalElapsedTime, MoveTemp(Frame.ColorBuffer)); // Finalize previous writers if necessary for (int32 Index = 0; Index < Payload->WriterIndex; ++Index) { TUniquePtr<FAVIWriter>& Writer = AVIWriters[Index]; if (Writer->IsCapturing()) { Writer->Finalize(); } } }
void FVideoCaptureProtocol::ConditionallyCreateWriter(const ICaptureProtocolHost& Host) { #if PLATFORM_MAC static const TCHAR* Extension = TEXT(".mov"); #else static const TCHAR* Extension = TEXT(".avi"); #endif FString VideoFilename = Host.GenerateFilename(FFrameMetrics(), Extension); if (AVIWriters.Num() && VideoFilename == AVIWriters.Last()->Options.OutputFilename) { return; } Host.EnsureFileWritable(VideoFilename); UVideoCaptureSettings* CaptureSettings = CastChecked<UVideoCaptureSettings>(InitSettings->ProtocolSettings); FAVIWriterOptions Options; Options.OutputFilename = MoveTemp(VideoFilename); Options.CaptureFPS = Host.GetCaptureFrequency(); Options.CodecName = CaptureSettings->VideoCodec; Options.bSynchronizeFrames = Host.GetCaptureStrategy().ShouldSynchronizeFrames(); Options.Width = InitSettings->DesiredSize.X; Options.Height = InitSettings->DesiredSize.Y; if (CaptureSettings->bUseCompression) { Options.CompressionQuality = CaptureSettings->CompressionQuality / 100.f; float QualityOverride = 100.f; if (FParse::Value( FCommandLine::Get(), TEXT( "-MovieQuality=" ), QualityOverride )) { Options.CompressionQuality = FMath::Clamp(QualityOverride, 1.f, 100.f) / 100.f; } Options.CompressionQuality = FMath::Clamp<float>(Options.CompressionQuality.GetValue(), 0.f, 1.f); } AVIWriters.Emplace(FAVIWriter::CreateInstance(Options)); AVIWriters.Last()->Initialize(); }
bool FStringAssetReference::SerializeFromMismatchedTag(struct FPropertyTag const& Tag, FArchive& Ar) { struct UObjectTypePolicy { typedef UObject Type; static const FName FORCEINLINE GetTypeName() { return NAME_ObjectProperty; } }; FString Path = ToString(); bool bReturn = SerializeFromMismatchedTagTemplate<UObjectTypePolicy>(Path, Tag, Ar); if (Ar.IsLoading()) { SetPath(MoveTemp(Path)); } return bReturn; }
/** * Helper function for FCheckInWorker::Execute. * Makes sure directories are committed with files that are also marked for add. * If we don't do this, the commit will fail. */ static void AddDirectoriesToCommit(const FSubversionSourceControlCommand& InCommand, TArray<FString>& InOutFiles) { // because of the use of "--parents" when we mark for add, we can just traverse up // the directory tree until we meet a directory that isn't already marked for add TArray<FString> Directories; FString WorkingCopyRoot = InCommand.WorkingCopyRoot; FPaths::NormalizeDirectoryName(WorkingCopyRoot); for(const auto& Filename : InOutFiles) { FString Directory = FPaths::GetPath(Filename); FPaths::NormalizeDirectoryName(Directory); // Stop once we leave our working copy, or find a directory that isn't marked for add while(Directory.StartsWith(WorkingCopyRoot)) { // Stop if we've already processed this directory, or if this directory isn't marked for add if(Directories.Contains(Directory) || !IsDirectoryAdded(InCommand, Directory)) { break; } Directories.Add(Directory); // Chop off the end of this directory to move up to our parent directory // This is safe to do since we called NormalizeDirectoryName on it, and we're testing to make sure we stay within the working copy int32 ChopPoint = INDEX_NONE; if(Directory.FindLastChar('/', ChopPoint)) { Directory = Directory.Left(ChopPoint); } else { // No more path to process break; } } } InOutFiles.Append(MoveTemp(Directories)); }
virtual void SetupView(FSceneViewFamily& InViewFamily, FSceneView& InView) { if (!bNeedsCapture) { return; } InView.FinalPostProcessSettings.bBufferVisualizationDumpRequired = true; InView.FinalPostProcessSettings.BufferVisualizationOverviewMaterials.Empty(); InView.FinalPostProcessSettings.BufferVisualizationDumpBaseFilename = MoveTemp(OutputFilename); struct FIterator { FFinalPostProcessSettings& FinalPostProcessSettings; const TArray<FString>& RenderPasses; FIterator(FFinalPostProcessSettings& InFinalPostProcessSettings, const TArray<FString>& InRenderPasses) : FinalPostProcessSettings(InFinalPostProcessSettings), RenderPasses(InRenderPasses) {} void ProcessValue(const FString& InName, UMaterial* Material, const FText& InText) { if (!RenderPasses.Num() || RenderPasses.Contains(InName) || RenderPasses.Contains(InText.ToString())) { FinalPostProcessSettings.BufferVisualizationOverviewMaterials.Add(Material); } } } Iterator(InView.FinalPostProcessSettings, RenderPasses); GetBufferVisualizationData().IterateOverAvailableMaterials(Iterator); if (PostProcessingMaterial) { FWeightedBlendable Blendable(1.f, PostProcessingMaterial); PostProcessingMaterial->OverrideBlendableSettings(InView, 1.f); } // Ensure we're rendering at full size InView.ViewRect = InView.UnscaledViewRect; bNeedsCapture = false; }
bool FStringAssetReference::ImportTextItem(const TCHAR*& Buffer, int32 PortFlags, UObject* Parent, FOutputDevice* ErrorText) { FString ImportedPath = TEXT(""); const TCHAR* NewBuffer = UPropertyHelpers::ReadToken(Buffer, ImportedPath, 1); if (!NewBuffer) { return false; } Buffer = NewBuffer; if (ImportedPath == TEXT("None")) { ImportedPath = TEXT(""); } else { if (*Buffer == TCHAR('\'')) { NewBuffer = UPropertyHelpers::ReadToken(Buffer, ImportedPath, 1); if (!NewBuffer) { return false; } Buffer = NewBuffer; if (*Buffer++ != TCHAR('\'')) { return false; } } } SetPath(MoveTemp(ImportedPath)); #if WITH_EDITOR // Consider this a load, so Config string asset references get cooked if (FCoreUObjectDelegates::StringAssetReferenceLoaded.IsBound()) { FCoreUObjectDelegates::StringAssetReferenceLoaded.Execute(ToString()); } #endif // WITH_EDITOR return true; }
void Finalize() { TArray<uint8> FinalData; FMemoryWriter NameTableWriter(FinalData); int32 NumNames = FNameIndexLookup.Num(); check(NumNames <= MANIFEST_MAX_NAMES); NameTableWriter << NumNames; for (auto& MapEntry : FNameIndexLookup) { FName& Name = MapEntry.Key; int32& Index = MapEntry.Value; NameTableWriter << Name; NameTableWriter << Index; } FinalData.Append(Bytes); Bytes = MoveTemp(FinalData); }
bool FOnlineUserCloudOculus::WriteUserFile(const FUniqueNetId& UserId, const FString& FileName, TArray<uint8>& FileContents) { auto LoggedInPlayerId = OculusSubsystem.GetIdentityInterface()->GetUniquePlayerId(0); if (!LoggedInPlayerId.IsValid() || UserId != *LoggedInPlayerId) { UE_LOG_ONLINE(Warning, TEXT("Can only save data for logged in player")); return false; } FString BucketName; FString Key; if (!(FileName.Split(SEPARATOR, &BucketName, &Key))) { BucketName = DefaultBucket; Key = FileName; } // store the save data in a temporary buffer until the Oculus Platform threadpool can process the request TArray<uint8> *TmpBuffer = new TArray<uint8>(MoveTemp(FileContents)); auto DelegateLambda = FOculusMessageOnCompleteDelegate::CreateLambda([this, BucketName, Key, LoggedInPlayerId, FileName, TmpBuffer](ovrMessageHandle Message, bool bIsError) { check(BucketName == UTF8_TO_TCHAR(ovr_CloudStorageUpdateResponse_GetBucket(ovr_Message_GetCloudStorageUpdateResponse(Message)))); check(Key == UTF8_TO_TCHAR(ovr_CloudStorageUpdateResponse_GetKey(ovr_Message_GetCloudStorageUpdateResponse(Message)))); if (bIsError) { UE_LOG_ONLINE(Warning, TEXT("Failed to Save: %s%s%s"), *BucketName, *SEPARATOR, *Key); } delete TmpBuffer; TriggerOnWriteUserFileCompleteDelegates(!bIsError, *LoggedInPlayerId, FileName); }); OculusSubsystem.AddRequestDelegate( ovr_CloudStorage_Save(TCHAR_TO_UTF8(*BucketName), TCHAR_TO_UTF8(*Key), TmpBuffer->GetData(), TmpBuffer->Num(), 0, nullptr), std::move(DelegateLambda)); return true; }
void FContentDirectoryMonitor::Tick() { Cache.Tick(); // Immediately resolve any changes that we should not consider const FDateTime Threshold = FDateTime::UtcNow() - FTimespan(0, 0, GetDefault<UEditorLoadingSavingSettings>()->AutoReimportThreshold); TArray<DirectoryWatcher::FUpdateCacheTransaction> InsignificantTransactions = Cache.FilterOutstandingChanges([=](const DirectoryWatcher::FUpdateCacheTransaction& Transaction, const FDateTime& TimeOfChange){ return TimeOfChange <= Threshold && !ShouldConsiderChange(Transaction); }); for (DirectoryWatcher::FUpdateCacheTransaction& Transaction : InsignificantTransactions) { Cache.CompleteTransaction(MoveTemp(Transaction)); } const double Now = FPlatformTime::Seconds(); if (Now - LastSaveTime > ResaveIntervalS) { LastSaveTime = Now; Cache.WriteCache(); } }
void UAssetImportData::Serialize(FArchive& Ar) { if (Ar.UE4Ver() >= VER_UE4_ASSET_IMPORT_DATA_AS_JSON) { FString Json; if (Ar.IsLoading()) { Ar << Json; TOptional<FAssetImportInfo> Copy = FromJson(MoveTemp(Json)); if (Copy.IsSet()) { CopyFrom(Copy.GetValue()); } } else if (Ar.IsSaving()) { Json = ToJson(); Ar << Json; } } Super::Serialize(Ar); }
FArchive& FArchiveUObject::operator<<(struct FStringAssetReference& Value) { FString Path = Value.ToString(); *this << Path; if (IsLoading()) { if (UE4Ver() < VER_UE4_KEEP_ONLY_PACKAGE_NAMES_IN_STRING_ASSET_REFERENCES_MAP) { FString NormalizedPath = FPackageName::GetNormalizedObjectPath(Path); if (Value.ToString() != NormalizedPath) { Value.SetPath(NormalizedPath); } } else { Value.SetPath(MoveTemp(Path)); } } return *this; }
bool TestWithType(FAutomationTestBase* Test) { int32 NumLeaks = 0; // Test that move-assigning the expression node correctly assigns the data, and calls the destructors successfully { TGuardValue<int32*> LeakCounter(T::LeakCount, &NumLeaks); FExpressionNode Original(T(1)); FExpressionNode New = MoveTemp(Original); int32 ResultingId = New.Cast<T>()->Id; if (ResultingId != 1) { Test->AddError(FString::Printf(TEXT("Expression node move operator did not operate correctly. Expected moved-to state to be 1, it's actually %d."), ResultingId)); return false; } // Try assigning it over the top again Original = FExpressionNode(T(1)); New = MoveTemp(Original); ResultingId = New.Cast<T>()->Id; if (ResultingId != 1) { Test->AddError(FString::Printf(TEXT("Expression node move operator did not operate correctly. Expected moved-to state to be 1, it's actually %d."), ResultingId)); return false; } // Now try running it all through a parser FTokenDefinitions TokenDefs; FExpressionGrammar Grammar; FOperatorJumpTable JumpTable; // Only valid tokens are a, b, and + TokenDefs.DefineToken([](FExpressionTokenConsumer& Consumer){ auto Token = Consumer.GetStream().GenerateToken(1); if (Token.IsSet()) { switch(Consumer.GetStream().PeekChar()) { case 'a': Consumer.Add(Token.GetValue(), T(1)); break; case '+': Consumer.Add(Token.GetValue(), FOperator()); break; } } return TOptional<FExpressionError>(); }); Grammar.DefinePreUnaryOperator<FOperator>(); Grammar.DefineBinaryOperator<FOperator>(1); JumpTable.MapPreUnary<FOperator>([](const T& A) { return T(A.Id); }); JumpTable.MapBinary<FOperator>([](const T& A, const T& B) { return T(A.Id); }); ExpressionParser::Evaluate(TEXT("+a"), TokenDefs, Grammar, JumpTable); ExpressionParser::Evaluate(TEXT("a+a"), TokenDefs, Grammar, JumpTable); ExpressionParser::Evaluate(TEXT("+a++a"), TokenDefs, Grammar, JumpTable); } if (NumLeaks != 0) { Test->AddError(FString::Printf(TEXT("Expression node did not call wrapped type's destructors correctly. Potentially resulted in %d leaks."), NumLeaks)); return false; } return true; }
bool FPackageReader::ReadAssetRegistryData (TArray<FBackgroundAssetData*>& AssetDataList) { check(Loader); // Does the package contain asset registry tags if( PackageFileSummary.AssetRegistryDataOffset == 0 ) { // No Tag Table! return false; } // Seek the the part of the file where the asset registry tags live Seek( PackageFileSummary.AssetRegistryDataOffset ); // Determine the package name and path FString PackageName = FPackageName::FilenameToLongPackageName(PackageFilename); FString PackagePath = FPackageName::GetLongPackagePath(PackageName); const bool bIsMapPackage = (PackageFileSummary.PackageFlags & PKG_ContainsMap) != 0; // Assets do not show up in map packages unless we launch with -WorldAssets static const bool bUsingWorldAssets = FAssetRegistry::IsUsingWorldAssets(); if ( bIsMapPackage && !bUsingWorldAssets ) { return true; } // Load the object count int32 ObjectCount = 0; *this << ObjectCount; // Worlds that were saved before they were marked public do not have asset data so we will synthesize it here to make sure we see all legacy umaps // We will also do this for maps saved after they were marked public but no asset data was saved for some reason. A bug caused this to happen for some maps. if (bUsingWorldAssets && bIsMapPackage) { const bool bLegacyPackage = PackageFileSummary.GetFileVersionUE4() < VER_UE4_PUBLIC_WORLDS; const bool bNoMapAsset = (ObjectCount == 0); if (bLegacyPackage || bNoMapAsset) { FString AssetName = FPackageName::GetLongPackageAssetName(PackageName); AssetDataList.Add(new FBackgroundAssetData(PackageName, PackagePath, FString(), MoveTemp(AssetName), TEXT("World"), TMap<FString, FString>(), PackageFileSummary.ChunkIDs, PackageFileSummary.PackageFlags)); } } // UAsset files only have one object, but legacy or map packages may have more. for(int32 ObjectIdx = 0; ObjectIdx < ObjectCount; ++ObjectIdx) { FString ObjectPath; FString ObjectClassName; int32 TagCount = 0; *this << ObjectPath; *this << ObjectClassName; *this << TagCount; TMap<FString, FString> TagsAndValues; for(int32 TagIdx = 0; TagIdx < TagCount; ++TagIdx) { FString Key; FString Value; *this << Key; *this << Value; TagsAndValues.Add(Key, Value); } FString GroupNames; FString AssetName; if ( ObjectPath.Contains(TEXT("."), ESearchCase::CaseSensitive)) { ObjectPath.Split(TEXT("."), &GroupNames, &AssetName, ESearchCase::CaseSensitive, ESearchDir::FromEnd); } else { AssetName = ObjectPath; } // Before world were RF_Public, other non-public assets were added to the asset data table in map packages. // Here we simply skip over them if ( bIsMapPackage && PackageFileSummary.GetFileVersionUE4() < VER_UE4_PUBLIC_WORLDS ) { if ( AssetName != FPackageName::GetLongPackageAssetName(PackageName) ) { continue; } } // Create a new FBackgroundAssetData for this asset and update it with the gathered data AssetDataList.Add(new FBackgroundAssetData(PackageName, PackagePath, MoveTemp(GroupNames), MoveTemp(AssetName), MoveTemp(ObjectClassName), MoveTemp(TagsAndValues), PackageFileSummary.ChunkIDs, PackageFileSummary.PackageFlags)); } return true; }
/** Consume the text from the specified consumer's stream */ TOptional<FExpressionError> ConsumeTextImpl(FExpressionTokenConsumer& Consumer, const TFunctionRef<bool(TCHAR)> IsBreakingCharacter) { auto& Stream = Consumer.GetStream(); FString FinalString; FString CurrentQuotedString; TCHAR QuoteChar = 0; int32 NumConsecutiveSlashes = 0; TOptional<FStringToken> TextToken = Stream.ParseToken([&](TCHAR InC) { if (QuoteChar == 0) // Parsing a non-quoted string... { // Are we starting a quoted sub-string? if (InC == '"' || InC == '\'') { CurrentQuotedString.AppendChar(InC); QuoteChar = InC; NumConsecutiveSlashes = 0; } else { // Consume until we hit a breaking character if (IsBreakingCharacter(InC)) { return EParseState::StopBefore; } FinalString.AppendChar(InC); } } else // Parsing a quoted sub-string... { CurrentQuotedString.AppendChar(InC); // Are we ending a quoted sub-string? if (InC == QuoteChar && NumConsecutiveSlashes%2 == 0) { UnescapeQuotedString(CurrentQuotedString, QuoteChar); FinalString.Append(CurrentQuotedString); CurrentQuotedString.Reset(); QuoteChar = 0; } if (InC == '\\') { NumConsecutiveSlashes++; } else { NumConsecutiveSlashes = 0; } } return EParseState::Continue; }); if (TextToken.IsSet()) { Consumer.Add(TextToken.GetValue(), CreateTextTokenFromUnquotedString(MoveTemp(FinalString))); } return TOptional<FExpressionError>(); }
FExpressionResult Evaluate(const TArray<FCompiledToken>& CompiledTokens, const IOperatorEvaluationEnvironment& InEnvironment) { // Evaluation strategy: the supplied compiled tokens are const. To avoid copying the whole array, we store a separate array of // any tokens that are generated at runtime by the evaluator. The operand stack will consist of indices into either the CompiledTokens // array, or the RuntimeGeneratedTokens (where Index >= CompiledTokens.Num()) TArray<FExpressionToken> RuntimeGeneratedTokens; TArray<int32> OperandStack; /** Get the token pertaining to the specified operand index */ auto GetToken = [&](int32 Index) -> const FExpressionToken& { if (Index < CompiledTokens.Num()) { return CompiledTokens[Index]; } return RuntimeGeneratedTokens[Index - CompiledTokens.Num()]; }; /** Add a new token to the runtime generated array */ auto AddToken = [&](FExpressionToken&& In) -> int32 { auto Index = CompiledTokens.Num() + RuntimeGeneratedTokens.Num(); RuntimeGeneratedTokens.Emplace(MoveTemp(In)); return Index; }; for (int32 Index = 0; Index < CompiledTokens.Num(); ++Index) { const auto& Token = CompiledTokens[Index]; switch(Token.Type) { case FCompiledToken::Benign: continue; case FCompiledToken::Operand: OperandStack.Push(Index); continue; case FCompiledToken::BinaryOperator: if (OperandStack.Num() >= 2) { // Binary const auto& R = GetToken(OperandStack.Pop()); const auto& L = GetToken(OperandStack.Pop()); auto OpResult = InEnvironment.ExecBinary(Token, L, R); if (OpResult.IsValid()) { // Inherit the LHS context OperandStack.Push(AddToken(FExpressionToken(L.Context, MoveTemp(OpResult.GetValue())))); } else { return MakeError(OpResult.GetError()); } } else { FFormatOrderedArguments Args; Args.Add(FText::FromString(Token.Context.GetString())); return MakeError(FText::Format(LOCTEXT("SyntaxError_NotEnoughOperandsBinary", "Not enough operands for binary operator {0}"), Args)); } break; case FCompiledToken::PostUnaryOperator: case FCompiledToken::PreUnaryOperator: if (OperandStack.Num() >= 1) { const auto& Operand = GetToken(OperandStack.Pop()); FExpressionResult OpResult = (Token.Type == FCompiledToken::PreUnaryOperator) ? InEnvironment.ExecPreUnary(Token, Operand) : InEnvironment.ExecPostUnary(Token, Operand); if (OpResult.IsValid()) { // Inherit the LHS context OperandStack.Push(AddToken(FExpressionToken(Operand.Context, MoveTemp(OpResult.GetValue())))); } else { return MakeError(OpResult.GetError()); } } else { FFormatOrderedArguments Args; Args.Add(FText::FromString(Token.Context.GetString())); return MakeError(FText::Format(LOCTEXT("SyntaxError_NoUnaryOperand", "No operand for unary operator {0}"), Args)); } break; } } if (OperandStack.Num() == 1) { return MakeValue(GetToken(OperandStack[0]).Node.Copy()); } return MakeError(LOCTEXT("SyntaxError_InvalidExpression", "Could not evaluate expression")); }
/** * Run a Git show command to dump the binary content of a revision into a file. */ bool RunDumpToFile(const FString& InPathToGitBinary, const FString& InRepositoryRoot, const FString& InParameter, const FString& InDumpFileName) { bool bResult = false; FString FullCommand; if(!InRepositoryRoot.IsEmpty()) { // Specify the working copy (the root) of the git repository (before the command itself) FullCommand = TEXT("--work-tree=\""); FullCommand += InRepositoryRoot; // and the ".git" subdirectory in it (before the command itself) FullCommand += TEXT("\" --git-dir=\""); FullCommand += InRepositoryRoot; FullCommand += TEXT(".git\" "); } // then the git command itself FullCommand += TEXT("show "); // Append to the command the parameter FullCommand += InParameter; const bool bLaunchDetached = false; const bool bLaunchHidden = true; const bool bLaunchReallyHidden = bLaunchHidden; // Setup output redirection pipes, so that we can harvest compiler output and display it ourselves #if PLATFORM_LINUX int pipefd[2]; pipe(pipefd); void* PipeRead = &pipefd[0]; void* PipeWrite = &pipefd[1]; #else void* PipeRead = NULL; void* PipeWrite = NULL; #endif verify(FPlatformProcess::CreatePipe(PipeRead, PipeWrite)); // @todo temp debug log //UE_LOG(LogSourceControl, Log, TEXT("RunDumpToFile: 'git %s'"), *FullCommand); FProcHandle ProcessHandle = FPlatformProcess::CreateProc(*InPathToGitBinary, *FullCommand, bLaunchDetached, bLaunchHidden, bLaunchReallyHidden, NULL, 0, NULL, PipeWrite); //UE_LOG(LogSourceControl, Log, TEXT("RunDumpToFile: ProcessHandle=%x"), ProcessHandle.Get()); if(ProcessHandle.IsValid()) { FPlatformProcess::Sleep(0.01); TArray<uint8> BinaryFileContent; while(FPlatformProcess::IsProcRunning(ProcessHandle)) { TArray<uint8> BinaryData; FPlatformProcess::ReadPipeToArray(PipeRead, BinaryData); if(BinaryData.Num() > 0) { BinaryFileContent.Append(MoveTemp(BinaryData)); } } TArray<uint8> BinaryData; FPlatformProcess::ReadPipeToArray(PipeRead, BinaryData); if(BinaryData.Num() > 0) { BinaryFileContent.Append(MoveTemp(BinaryData)); } // Save buffer into temp file if(FFileHelper::SaveArrayToFile(BinaryFileContent, *InDumpFileName)) { UE_LOG(LogSourceControl, Log, TEXT("Writed '%s' (%do)"), *InDumpFileName, BinaryFileContent.Num()); bResult = true; } else { UE_LOG(LogSourceControl, Error, TEXT("Could not write %s"), *InDumpFileName); } } else { UE_LOG(LogSourceControl, Error, TEXT("Failed to launch 'git show'")); } #if PLATFORM_LINUX close(*(int*)PipeRead); close(*(int*)PipeWrite); #else FPlatformProcess::ClosePipe(PipeRead, PipeWrite); #endif return bResult; }
FCPPRichTextSyntaxHighlighterTextLayoutMarshaller::FCPPRichTextSyntaxHighlighterTextLayoutMarshaller(TSharedPtr< FSyntaxTokenizer > InTokenizer, const FSyntaxTextStyle& InSyntaxTextStyle) : FSyntaxHighlighterTextLayoutMarshaller(MoveTemp(InTokenizer)) , SyntaxTextStyle(InSyntaxTextStyle) { }
static FText Format(const FText& Pattern, FGetArgumentValue GetArgumentValue) { checkf(FInternationalization::Get().IsInitialized() == true, TEXT("FInternationalization is not initialized. An FText formatting method was likely used in static object initialization - this is not supported.")); //SCOPE_CYCLE_COUNTER( STAT_TextFormat ); const FString& PatternString = Pattern.ToString(); FString ResultString; EEscapeState::Type EscapeState = EEscapeState::None; EBlockState::Type BlockState = EBlockState::None; FString ArgumentName; for(int32 i = 0; i < PatternString.Len(); ++i) { switch( EscapeState ) { case EEscapeState::None: { switch( PatternString[i] ) { case '`': { EscapeState = EEscapeState::BeginEscaping; } break; } } break; case EEscapeState::BeginEscaping: { switch( PatternString[i] ) { // Only begin EEscapeState::Escaping if there's a syntax character. case '{': case '}': { EscapeState = EEscapeState::Escaping; ResultString += PatternString[i]; // Characters are escaped, copy over. } break; // Cancel beginning EEscapeState::Escaping if the escape is itself escaped. case '`': { EscapeState = EEscapeState::None; } break; // Cancel beginning EEscapeState::Escaping if not a syntax character. default: { EscapeState = EEscapeState::None; ResultString += '`'; // Insert previously ignored escape marker. } break; } } break; case EEscapeState::Escaping: { switch( PatternString[i] ) { case '`': { EscapeState = EEscapeState::EndEscaping; } break; default: { ResultString += PatternString[i]; } break; // Characters are escaped, copy over. } } break; case EEscapeState::EndEscaping: { switch( PatternString[i] ) { case '`': { EscapeState = EEscapeState::Escaping; ResultString += PatternString[i]; } break; // Cancel ending EEscapeState::Escaping if the escape is itself escaped, copy over escaped character. default: { EscapeState = EEscapeState::None; } break; } } break; } if(EscapeState == EEscapeState::None) { switch( BlockState ) { case EBlockState::None: { switch( PatternString[i] ) { case '{': { BlockState = EBlockState::InBlock; } break; default: { ResultString += PatternString[i]; // Copy over characters. } break; } } break; case EBlockState::InBlock: { switch( PatternString[i] ) { case '}': { const FFormatArgumentValue* const PossibleArgumentValue = GetArgumentValue.Execute(ArgumentName); if( PossibleArgumentValue ) { FString ArgumentValueAsString; const FFormatArgumentValue& ArgumentValue = *PossibleArgumentValue; switch(ArgumentValue.Type) { case EFormatArgumentType::Text: { ArgumentValueAsString = ArgumentValue.TextValue->ToString(); } break; case EFormatArgumentType::Int: { ArgumentValueAsString = FText::AsNumber(ArgumentValue.IntValue).ToString(); } break; case EFormatArgumentType::UInt: { ArgumentValueAsString = FText::AsNumber(ArgumentValue.UIntValue).ToString(); } break; case EFormatArgumentType::Float: { ArgumentValueAsString = FText::AsNumber(ArgumentValue.FloatValue).ToString(); } break; case EFormatArgumentType::Double: { ArgumentValueAsString = FText::AsNumber(ArgumentValue.DoubleValue).ToString(); } break; } ResultString += ArgumentValueAsString; } else { ResultString += FString("{") + ArgumentName + FString("}"); } ArgumentName.Empty(); BlockState = EBlockState::None; } break; default: { ArgumentName += PatternString[i]; } break; } } break; } } } FText Result = FText(MoveTemp(ResultString)); if (!GIsEditor) { Result.Flags = Result.Flags | ETextFlag::Transient; } return Result; }
FText UKismetTextLibrary::Format(FText InPattern, TArray<FFormatArgumentData> InArgs) { return FText::Format(MoveTemp(InPattern), MoveTemp(InArgs)); }
FHugeType(FHugeType&& In) : FMoveableType(MoveTemp(In)) {}
void ULandscapeEditorObject::RefreshImportLayersList() { UTexture2D* ThumbnailWeightmap = LoadObject<UTexture2D>(NULL, TEXT("/Engine/EditorLandscapeResources/LandscapeThumbnailWeightmap.LandscapeThumbnailWeightmap"), NULL, LOAD_None, NULL); UTexture2D* ThumbnailHeightmap = LoadObject<UTexture2D>(NULL, TEXT("/Engine/EditorLandscapeResources/LandscapeThumbnailHeightmap.LandscapeThumbnailHeightmap"), NULL, LOAD_None, NULL); UMaterialInterface* Material = NewLandscape_Material.Get(); TArray<FName> LayerNames = ALandscapeProxy::GetLayersFromMaterial(Material); const TArray<FLandscapeImportLayer> OldLayersList = MoveTemp(ImportLandscape_Layers); ImportLandscape_Layers.Reset(LayerNames.Num()); for (int32 i = 0; i < LayerNames.Num(); i++) { const FName& LayerName = LayerNames[i]; bool bFound = false; FLandscapeImportLayer NewImportLayer; for (int32 j = 0; j < OldLayersList.Num(); j++) { if (OldLayersList[j].LayerName == LayerName) { NewImportLayer = OldLayersList[j]; bFound = true; break; } } if (bFound) { UMaterialInstanceConstant* CombinationMaterialInstance = CastChecked<UMaterialInstanceConstant>(NewImportLayer.ThumbnailMIC->Parent); if (CombinationMaterialInstance->Parent != Material) { CombinationMaterialInstance->SetParentEditorOnly(Material); //NewImportLayer.ThumbnailMIC = ALandscapeProxy::GetLayerThumbnailMIC(Material, LayerName, ThumbnailWeightmap, ThumbnailHeightmap, NULL); } NewImportLayer.ImportError = ELandscapeImportLayerError::None; if (!NewImportLayer.SourceFilePath.IsEmpty()) { if (NewImportLayer.LayerInfo == NULL) { NewImportLayer.ImportError = ELandscapeImportLayerError::MissingLayerInfo; } else { if (NewImportLayer.SourceFilePath.EndsWith(".png")) { TArray<uint8> ImportData; if (!FFileHelper::LoadFileToArray(ImportData, *NewImportLayer.SourceFilePath, FILEREAD_Silent)) { NewImportLayer.ImportError = ELandscapeImportLayerError::FileNotFound; } else { IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>("ImageWrapper"); IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG); if (!ImageWrapper->SetCompressed(ImportData.GetData(), ImportData.Num())) { NewImportLayer.ImportError = ELandscapeImportLayerError::CorruptFile; } else if (ImageWrapper->GetWidth() != ImportLandscape_Width || ImageWrapper->GetHeight() != ImportLandscape_Height) { NewImportLayer.ImportError = ELandscapeImportLayerError::FileSizeMismatch; } else if (ImageWrapper->GetFormat() != ERGBFormat::Gray) { NewImportLayer.ImportError = ELandscapeImportLayerError::ColorPng; } } } else { int64 ImportFileSize = IFileManager::Get().FileSize(*NewImportLayer.SourceFilePath); if (ImportFileSize < 0) { NewImportLayer.ImportError = ELandscapeImportLayerError::FileNotFound; } else if (ImportFileSize != ImportLandscape_Width * ImportLandscape_Height) { NewImportLayer.ImportError = ELandscapeImportLayerError::FileSizeMismatch; } } } } } else { NewImportLayer.LayerName = LayerName; NewImportLayer.ThumbnailMIC = ALandscapeProxy::GetLayerThumbnailMIC(Material, LayerName, ThumbnailWeightmap, ThumbnailHeightmap, NULL); } ImportLandscape_Layers.Add(MoveTemp(NewImportLayer)); } }
FHugeType& operator=(FHugeType&& In) { MoveTemp(In); return *this; }
void FNativeClassHierarchyNode::AddChild(TSharedRef<FNativeClassHierarchyNode> ChildEntry) { check(Type == ENativeClassHierarchyNodeType::Folder); Children.Add(FNativeClassHierarchyNodeKey(ChildEntry->EntryName, ChildEntry->Type), MoveTemp(ChildEntry)); }
bool FPluginManager::ConfigureEnabledPlugins() { if(!bHaveConfiguredEnabledPlugins) { // Don't need to run this again bHaveConfiguredEnabledPlugins = true; // If a current project is set, check that we know about any plugin that's explicitly enabled const FProjectDescriptor *Project = IProjectManager::Get().GetCurrentProject(); const bool bHasProjectFile = Project != nullptr; // Get all the enabled plugin names TArray< FString > EnabledPluginNames; #if IS_PROGRAM // Programs can also define the list of enabled plugins in ini GConfig->GetArray(TEXT("Plugins"), TEXT("ProgramEnabledPlugins"), EnabledPluginNames, GEngineIni); #endif #if !IS_PROGRAM || HACK_HEADER_GENERATOR if (!FParse::Param(FCommandLine::Get(), TEXT("NoEnginePlugins"))) { FProjectManager::Get().GetEnabledPlugins(EnabledPluginNames); } #endif // Build a set from the array TSet< FString > AllEnabledPlugins; AllEnabledPlugins.Append(MoveTemp(EnabledPluginNames)); // Enable all the plugins by name for (const TSharedRef< FPlugin > Plugin : AllPlugins) { if (AllEnabledPlugins.Contains(Plugin->Name)) { Plugin->bEnabled = (!IS_PROGRAM || !bHasProjectFile) || IsPluginSupportedByCurrentTarget(Plugin); if (!Plugin->bEnabled) { AllEnabledPlugins.Remove(Plugin->Name); } } } if (bHasProjectFile) { // Take a copy of the Project's plugins as we may remove some TArray<FPluginReferenceDescriptor> PluginsCopy = Project->Plugins; for(const FPluginReferenceDescriptor& Plugin: PluginsCopy) { if ((Plugin.bEnabled && !FindPluginInstance(Plugin.Name).IsValid()) && (!IS_PROGRAM || AllEnabledPlugins.Contains(Plugin.Name))) // skip if this is a program and the plugin is not enabled { FText Caption(LOCTEXT("PluginMissingCaption", "Plugin missing")); if(Plugin.MarketplaceURL.Len() > 0) { if(FMessageDialog::Open(EAppMsgType::YesNo, FText::Format(LOCTEXT("PluginMissingError", "This project requires the {0} plugin.\n\nWould you like to download it from the the Marketplace?"), FText::FromString(Plugin.Name)), &Caption) == EAppReturnType::Yes) { FString Error; FPlatformProcess::LaunchURL(*Plugin.MarketplaceURL, nullptr, &Error); if(Error.Len() > 0) FMessageDialog::Open(EAppMsgType::Ok, FText::FromString(Error)); return false; } } else { FString Description = (Plugin.Description.Len() > 0) ? FString::Printf(TEXT("\n\n%s"), *Plugin.Description) : FString(); FMessageDialog::Open(EAppMsgType::Ok, FText::Format(LOCTEXT("PluginRequiredError", "This project requires the {0} plugin. {1}"), FText::FromString(Plugin.Name), FText::FromString(Description)), &Caption); if (FMessageDialog::Open(EAppMsgType::YesNo, FText::Format(LOCTEXT("PluginMissingDisable", "Would you like to disable {0}? You will no longer be able to open any assets created using it."), FText::FromString(Plugin.Name)), &Caption) == EAppReturnType::No) { return false; } FText FailReason; if (!IProjectManager::Get().SetPluginEnabled(*Plugin.Name, false, FailReason)) { FMessageDialog::Open(EAppMsgType::Ok, FailReason); } } } } } // If we made it here, we have all the required plugins bHaveAllRequiredPlugins = true; for(const TSharedRef<FPlugin>& Plugin: AllPlugins) { if (Plugin->bEnabled) { // Add the plugin binaries directory const FString PluginBinariesPath = FPaths::Combine(*FPaths::GetPath(Plugin->FileName), TEXT("Binaries"), FPlatformProcess::GetBinariesSubdirectory()); FModuleManager::Get().AddBinariesDirectory(*PluginBinariesPath, Plugin->LoadedFrom == EPluginLoadedFrom::GameProject); #if !IS_MONOLITHIC // Only check this when in a non-monolithic build where modules could be in separate binaries if (Project != NULL && Project->Modules.Num() == 0) { // Content only project - check whether any plugins are incompatible and offer to disable instead of trying to build them later TArray<FString> IncompatibleFiles; if (!FModuleDescriptor::CheckModuleCompatibility(Plugin->Descriptor.Modules, Plugin->LoadedFrom == EPluginLoadedFrom::GameProject, IncompatibleFiles)) { // Ask whether to disable plugin if incompatible FText Caption(LOCTEXT("IncompatiblePluginCaption", "Plugin missing or incompatible")); if (FMessageDialog::Open(EAppMsgType::YesNo, FText::Format(LOCTEXT("IncompatiblePluginText", "Missing or incompatible modules in {0} plugin - would you like to disable it? You will no longer be able to open any assets created using it."), FText::FromString(Plugin->Name)), &Caption) == EAppReturnType::No) { return false; } FText FailReason; if (!IProjectManager::Get().SetPluginEnabled(*Plugin->Name, false, FailReason)) { FMessageDialog::Open(EAppMsgType::Ok, FailReason); } } } #endif //!IS_MONOLITHIC // Build the list of content folders if (Plugin->Descriptor.bCanContainContent) { if (auto EngineConfigFile = GConfig->Find(GEngineIni, false)) { if (auto CoreSystemSection = EngineConfigFile->Find(TEXT("Core.System"))) { CoreSystemSection->AddUnique("Paths", Plugin->GetContentDir()); } } } // Load Default<PluginName>.ini config file if it exists FString PluginConfigDir = FPaths::GetPath(Plugin->FileName) / TEXT("Config/"); FConfigFile PluginConfig; FConfigCacheIni::LoadExternalIniFile(PluginConfig, *Plugin->Name, *FPaths::EngineConfigDir(), *PluginConfigDir, true); if (PluginConfig.Num() > 0) { FString PlaformName = FPlatformProperties::PlatformName(); FString PluginConfigFilename = FString::Printf(TEXT("%s%s/%s.ini"), *FPaths::GeneratedConfigDir(), *PlaformName, *Plugin->Name); FConfigFile& NewConfigFile = GConfig->Add(PluginConfigFilename, FConfigFile()); NewConfigFile.AddMissingProperties(PluginConfig); NewConfigFile.Write(PluginConfigFilename); } } } // Mount all the plugin content folders and pak files TArray<FString> FoundPaks; FPakFileSearchVisitor PakVisitor(FoundPaks); IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile(); for(TSharedRef<IPlugin> Plugin: GetEnabledPlugins()) { if (Plugin->CanContainContent() && ensure(RegisterMountPointDelegate.IsBound())) { FString ContentDir = Plugin->GetContentDir(); RegisterMountPointDelegate.Execute(Plugin->GetMountedAssetPath(), ContentDir); // Pak files are loaded from <PluginName>/Content/Paks/<PlatformName> if (FPlatformProperties::RequiresCookedData()) { FoundPaks.Reset(); PlatformFile.IterateDirectoryRecursively(*(ContentDir / TEXT("Paks") / FPlatformProperties::PlatformName()), PakVisitor); for (const auto& PakPath : FoundPaks) { if (FCoreDelegates::OnMountPak.IsBound()) { FCoreDelegates::OnMountPak.Execute(PakPath, 0); } } } } } } return bHaveAllRequiredPlugins; }