void FKismet2CompilerModule::CompileStructure(class UUserDefinedStruct* Struct, FCompilerResultsLog& Results) { Results.SetSourceName(Struct->GetName()); BP_SCOPED_COMPILER_EVENT_STAT(EKismetCompilerStats_CompileTime); FUserDefinedStructureCompilerUtils::CompileStruct(Struct, Results, true); }
// Compiles a blueprint. void FKismet2CompilerModule::CompileBlueprint(class UBlueprint* Blueprint, const FKismetCompilerOptions& CompileOptions, FCompilerResultsLog& Results, FBlueprintCompileReinstancer* ParentReinstancer, TArray<UObject*>* ObjLoaded) { SCOPE_SECONDS_COUNTER(GBlueprintCompileTime); BP_SCOPED_COMPILER_EVENT_STAT(EKismetCompilerStats_CompileTime); Results.SetSourceName(Blueprint->GetName()); const bool bIsBrandNewBP = (Blueprint->SkeletonGeneratedClass == NULL) && (Blueprint->GeneratedClass == NULL) && (Blueprint->ParentClass != NULL) && !CompileOptions.bIsDuplicationInstigated; for ( IBlueprintCompiler* Compiler : Compilers ) { Compiler->PreCompile(Blueprint); } if (CompileOptions.CompileType != EKismetCompileType::Cpp) { BP_SCOPED_COMPILER_EVENT_STAT(EKismetCompilerStats_CompileSkeletonClass); FBlueprintCompileReinstancer SkeletonReinstancer(Blueprint->SkeletonGeneratedClass); FCompilerResultsLog SkeletonResults; SkeletonResults.bSilentMode = true; FKismetCompilerOptions SkeletonCompileOptions; SkeletonCompileOptions.CompileType = EKismetCompileType::SkeletonOnly; CompileBlueprintInner(Blueprint, SkeletonCompileOptions, SkeletonResults, ObjLoaded); } // If this was a full compile, take appropriate actions depending on the success of failure of the compile if( CompileOptions.IsGeneratedClassCompileType() ) { BP_SCOPED_COMPILER_EVENT_STAT(EKismetCompilerStats_CompileGeneratedClass); // Perform the full compile CompileBlueprintInner(Blueprint, CompileOptions, Results, ObjLoaded); if (Results.NumErrors == 0) { // Blueprint is error free. Go ahead and fix up debug info Blueprint->Status = (0 == Results.NumWarnings) ? BS_UpToDate : BS_UpToDateWithWarnings; Blueprint->BlueprintSystemVersion = UBlueprint::GetCurrentBlueprintSystemVersion(); // Reapply breakpoints to the bytecode of the new class for (int32 Index = 0; Index < Blueprint->Breakpoints.Num(); ++Index) { UBreakpoint* Breakpoint = Blueprint->Breakpoints[Index]; FKismetDebugUtilities::ReapplyBreakpoint(Breakpoint); } } else { // Should never get errors from a brand new blueprint! ensure(!bIsBrandNewBP || (Results.NumErrors == 0)); // There were errors. Compile the generated class to have function stubs Blueprint->Status = BS_Error; static const FBoolConfigValueHelper ReinstanceOnlyWhenNecessary(TEXT("Kismet"), TEXT("bReinstanceOnlyWhenNecessary"), GEngineIni); // Reinstance objects here, so we can preserve their memory layouts to reinstance them again if( ParentReinstancer != NULL ) { ParentReinstancer->UpdateBytecodeReferences(); if(!Blueprint->bIsRegeneratingOnLoad) { ParentReinstancer->ReinstanceObjects(!ReinstanceOnlyWhenNecessary); } } FBlueprintCompileReinstancer StubReinstancer(Blueprint->GeneratedClass); // Toss the half-baked class and generate a stubbed out skeleton class that can be used FCompilerResultsLog StubResults; StubResults.bSilentMode = true; FKismetCompilerOptions StubCompileOptions(CompileOptions); StubCompileOptions.CompileType = EKismetCompileType::StubAfterFailure; CompileBlueprintInner(Blueprint, StubCompileOptions, StubResults, ObjLoaded); StubReinstancer.UpdateBytecodeReferences(); if( !Blueprint->bIsRegeneratingOnLoad ) { StubReinstancer.ReinstanceObjects(!ReinstanceOnlyWhenNecessary); } } } for ( IBlueprintCompiler* Compiler : Compilers ) { Compiler->PostCompile(Blueprint); } UPackage* Package = Blueprint->GetOutermost(); if( Package ) { UMetaData* MetaData = Package->GetMetaData(); MetaData->RemoveMetaDataOutsidePackage(); } }