void FBlueprintNativeCodeGenModule::GenerateSingleAsset(UField* ForConversion, const TCHAR* PlatformName, TSharedPtr<FNativizationSummary> NativizationSummary)
{
	IBlueprintCompilerCppBackendModule& BackEndModule = (IBlueprintCompilerCppBackendModule&)IBlueprintCompilerCppBackendModule::Get();
	auto& BackendPCHQuery = BackEndModule.OnPCHFilenameQuery();
	const IAssetRegistry& Registry = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry").Get();
	FAssetData AssetInfo = Registry.GetAssetByObjectPath(*ForConversion->GetPathName());

	FBlueprintNativeCodeGenPaths TargetPaths = GetManifest(PlatformName).GetTargetPaths();
	BackendPCHQuery.BindLambda([TargetPaths]()->FString
	{
		return TargetPaths.RuntimePCHFilename();
	});

	FConvertedAssetRecord& ConversionRecord = GetManifest(PlatformName).CreateConversionRecord(*ForConversion->GetPathName(), AssetInfo);
	TSharedPtr<FString> HeaderSource(new FString());
	TSharedPtr<FString> CppSource(new FString());

	FBlueprintNativeCodeGenUtils::GenerateCppCode(ForConversion, HeaderSource, CppSource, NativizationSummary);
	bool bSuccess = !HeaderSource->IsEmpty() || !CppSource->IsEmpty();
	// Run the cpp first, because we cue off of the presence of a header for a valid conversion record (see
	// FConvertedAssetRecord::IsValid)
	if (!CppSource->IsEmpty())
	{
		if (!FFileHelper::SaveStringToFile(*CppSource, *ConversionRecord.GeneratedCppPath, ForcedEncoding()))
		{
			bSuccess &= false;
			ConversionRecord.GeneratedCppPath.Empty();
		}
		CppSource->Empty(CppSource->Len());
	}
	else
	{
		ConversionRecord.GeneratedCppPath.Empty();
	}

	if (bSuccess && !HeaderSource->IsEmpty())
	{
		if (!FFileHelper::SaveStringToFile(*HeaderSource, *ConversionRecord.GeneratedHeaderPath, ForcedEncoding()))
		{
			bSuccess &= false;
			ConversionRecord.GeneratedHeaderPath.Empty();
		}
		HeaderSource->Empty(HeaderSource->Len());
	}
	else
	{
		ConversionRecord.GeneratedHeaderPath.Empty();
	}

	if (bSuccess)
	{
		GetManifest(PlatformName).GatherModuleDependencies(ForConversion->GetOutermost());
	}
	else
	{
		UE_LOG(LogBlueprintCodeGen, Error, TEXT("FBlueprintNativeCodeGenModule::GenerateSingleAsset error: %s"), *GetPathNameSafe(ForConversion));
	}

	BackendPCHQuery.Unbind();
}
void FBlueprintNativeCodeGenModule::GenerateSingleStub(UBlueprint* BP, const TCHAR* PlatformName)
{
	if (!ensure(BP))
	{
		return;
	}

	UClass* Class = BP->GeneratedClass;
	if (!ensure(Class))
	{
		return;
	}

	// no PCHFilename should be necessary
	const IAssetRegistry& Registry = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry").Get();
	FAssetData AssetInfo = Registry.GetAssetByObjectPath(*Class->GetPathName());
	FString FileContents;
	TUniquePtr<IBlueprintCompilerCppBackend> Backend_CPP(IBlueprintCompilerCppBackendModuleInterface::Get().Create());
	// Apparently we can only generate wrappers for classes, so any logic that results in non classes requesting
	// wrappers will fail here:

	FileContents = Backend_CPP->GenerateWrapperForClass(Class);

	if (!FileContents.IsEmpty())
	{
		FFileHelper::SaveStringToFile(FileContents
			, *(GetManifest(PlatformName).CreateUnconvertedDependencyRecord(AssetInfo.PackageName, AssetInfo).GeneratedWrapperPath)
			, ForcedEncoding());
	}
	// The stub we generate still may have dependencies on other modules, so make sure the module dependencies are 
	// still recorded so that the .build.cs is generated correctly. Without this you'll get include related errors 
	// (or possibly linker errors) in stub headers:
	GetManifest(PlatformName).GatherModuleDependencies(BP->GetOutermost());
}
void FBlueprintNativeCodeGenModule::FinalizeManifest()
{
	for(auto& PlatformName : TargetPlatformNames)
	{
		GetManifest(*PlatformName).Save(-1);
		check(FBlueprintNativeCodeGenUtils::FinalizePlugin(GetManifest(*PlatformName)));
	}
}
void FBlueprintNativeCodeGenModule::InitializeForRerunDebugOnly(const TArray< TPair< FString, FString > >& CodegenTargets)
{
	ReadConfig();
	IBlueprintNativeCodeGenCore::Register(this);
	FillTargetedForReplacementQuery();
	FillIsFunctionUsedInADelegate();

	for (const auto& Platform : CodegenTargets)
	{
		// load the old manifest:
		const TCHAR* TargetDirectory = *Platform.Value;
		FString OutputPath = FPaths::Combine(TargetDirectory, NativizationCookControllerImpl::DefaultPluginName, *FBlueprintNativeCodeGenPaths::GetDefaultManifestPath());
		Manifests.Add(FString(*Platform.Key), TUniquePtr<FBlueprintNativeCodeGenManifest>(new FBlueprintNativeCodeGenManifest(FPaths::ConvertRelativePathToFull(OutputPath))));
		//FBlueprintNativeCodeGenManifest OldManifest(FPaths::ConvertRelativePathToFull(OutputPath));
		// reconvert every assets listed in the manifest:
		for (const auto& ConversionTarget : GetManifest(*Platform.Key).GetConversionRecord())
		{
			// load the package:
			UPackage* Package = LoadPackage(nullptr, *ConversionTarget.Value.TargetObjPath, LOAD_None);

			if (!Package)
			{
				UE_LOG(LogBlueprintCodeGen, Error, TEXT("Unable to load the package: %s"), *ConversionTarget.Value.TargetObjPath);
				continue;
			}

			// reconvert it
			Convert(Package, ESavePackageResult::ReplaceCompletely, *Platform.Key);
		}

		// reconvert every unconverted dependency listed in the manifest:
		for (const auto& ConversionTarget : GetManifest(*Platform.Key).GetUnconvertedDependencies())
		{
			// load the package:
			UPackage* Package = LoadPackage(nullptr, *ConversionTarget.Key.GetPlainNameString(), LOAD_None);

			UStruct* Struct = nullptr;
			UEnum* Enum = nullptr;
			GetFieldFormPackage(Package, Struct, Enum);
			UBlueprint* BP = Cast<UBlueprint>(CastChecked<UClass>(Struct)->ClassGeneratedBy);
			if (ensure(BP))
			{
				CollectBoundFunctions(BP);
				GenerateSingleStub(BP, *Platform.Key);
			}
		}

		for (TAssetPtr<UBlueprint>& BPPtr : ToGenerate)
		{
			UBlueprint* BP = BPPtr.LoadSynchronous();
			if (ensure(BP))
			{
				GenerateSingleAsset(BP->GeneratedClass, *Platform.Key);
			}
		}
	}
}
void FBlueprintNativeCodeGenModule::SaveManifest(int32 Id )
{
	for (auto& PlatformName : TargetPlatformNames)
	{
		GetManifest(*PlatformName).Save(Id);
	}
}
void FBlueprintNativeCodeGenModule::Initialize(const FNativeCodeGenInitData& InitData)
{
	ReadConfig();

	IBlueprintNativeCodeGenCore::Register(this);

	// Each platform will need a manifest, because each platform could cook different assets:
	for (auto& Platform : InitData.CodegenTargets)
	{
		const TCHAR* TargetDirectory = *Platform.Value;
		FString OutputPath = FPaths::Combine(TargetDirectory, NativizationCookControllerImpl::DefaultPluginName);

		Manifests.Add(FString(*Platform.Key), TUniquePtr<FBlueprintNativeCodeGenManifest>(new FBlueprintNativeCodeGenManifest(NativizationCookControllerImpl::DefaultPluginName, OutputPath)));

		TargetPlatformNames.Add(Platform.Key);

		// Clear source code folder
		const FString SourceCodeDir = GetManifest(*Platform.Key).GetTargetPaths().PluginSourceDir();
		UE_LOG(LogBlueprintCodeGen, Log, TEXT("Clear nativized source code directory: %s"), *SourceCodeDir);
		IFileManager::Get().DeleteDirectory(*SourceCodeDir, false, true);
	}

	FillTargetedForReplacementQuery();

	FillIsFunctionUsedInADelegate();
}
void FBlueprintNativeCodeGenModule::MergeManifest(int32 ManifestIdentifier)
{
	for (auto& PlatformName : TargetPlatformNames)
	{
		FBlueprintNativeCodeGenManifest& CurrentManifest = GetManifest(*PlatformName);
		FBlueprintNativeCodeGenManifest OtherManifest = FBlueprintNativeCodeGenManifest(CurrentManifest.GetTargetPaths().ManifestFilePath() + FString::FromInt(ManifestIdentifier));
		CurrentManifest.Merge(OtherManifest);
	}
} 
Esempio n. 8
0
	void ViewManager::RemoveQuark (const QUrl& url)
	{
		for (int i = 0; i < ViewItemsModel_->rowCount (); ++i)
		{
			auto item = ViewItemsModel_->item (i);
			if (item->data (ViewItemsModel::Role::SourceURL) != url)
				continue;

			ViewItemsModel_->removeRow (i);
		}

		auto mgr = Quark2Manager_.take (url);
		AddToRemoved (mgr->GetManifest ().GetID ());

		SaveQuarkOrder ();
	}
Esempio n. 9
0
	void ViewManager::RemoveQuark (const QString& id)
	{
		QUrl url;
		for (int i = 0; i < ViewItemsModel_->rowCount (); ++i)
		{
			auto item = ViewItemsModel_->item (i);
			if (item->data (ViewItemsModel::Role::QuarkClass) != id)
				continue;

			url = item->data (ViewItemsModel::Role::SourceURL).toUrl ();
			ViewItemsModel_->removeRow (i);
		}

		if (!url.isValid ())
			return;

		auto mgr = Quark2Manager_.take (url);
		AddToRemoved (mgr->GetManifest ().GetID ());
	}