FText FSimpleAssetEditor::GetToolkitName() const { const TArray<UObject*>& EditingObjs = GetEditingObjects(); check( EditingObjs.Num() > 0 ); FFormatNamedArguments Args; Args.Add( TEXT("ToolkitName"), GetBaseToolkitName() ); if( EditingObjs.Num() == 1 ) { const UObject* EditingObject = EditingObjs[ 0 ]; const bool bDirtyState = EditingObject->GetOutermost()->IsDirty(); Args.Add( TEXT("ObjectName"), FText::FromString( EditingObject->GetName() ) ); Args.Add( TEXT("DirtyState"), bDirtyState ? FText::FromString( TEXT( "*" ) ) : FText::GetEmpty() ); return FText::Format( LOCTEXT("ToolkitTitle", "{ObjectName}{DirtyState} - {ToolkitName}"), Args ); } else { bool bDirtyState = false; UClass* SharedBaseClass = nullptr; for( int32 x = 0; x < EditingObjs.Num(); ++x ) { UObject* Obj = EditingObjs[ x ]; check( Obj ); UClass* ObjClass = Cast<UClass>(Obj); if (ObjClass == nullptr) { ObjClass = Obj->GetClass(); } check( ObjClass ); // Initialize with the class of the first object we encounter. if( SharedBaseClass == nullptr ) { SharedBaseClass = ObjClass; } // If we've encountered an object that's not a subclass of the current best baseclass, // climb up a step in the class hierarchy. while( !ObjClass->IsChildOf( SharedBaseClass ) ) { SharedBaseClass = SharedBaseClass->GetSuperClass(); } // If any of the objects are dirty, flag the label bDirtyState |= Obj->GetOutermost()->IsDirty(); } check(SharedBaseClass); Args.Add( TEXT("NumberOfObjects"), EditingObjs.Num() ); Args.Add( TEXT("ClassName"), FText::FromString( SharedBaseClass->GetName() ) ); Args.Add( TEXT("DirtyState"), bDirtyState ? FText::FromString( TEXT( "*" ) ) : FText::GetEmpty() ); return FText::Format( LOCTEXT("ToolkitTitle_EditingMultiple", "{NumberOfObjects} {ClassName}{DirtyState} - {ToolkitName}"), Args ); } }
FString UMaterialGraphNode::GetDocumentationExcerptName() const { // Default the node to searching for an excerpt named for the C++ node class name, including the U prefix. // This is done so that the excerpt name in the doc file can be found by find-in-files when searching for the full class name. UClass* MyClass = (MaterialExpression != NULL) ? MaterialExpression->GetClass() : this->GetClass(); return FString::Printf(TEXT("%s%s"), MyClass->GetPrefixCPP(), *MyClass->GetName()); }
FName FClassIconFinder::FindIconNameForClass(UClass* InClass, const FName& InDefaultName ) { FName BrushName = InDefaultName; const FSlateBrush* Brush = NULL; if ( InClass != NULL ) { // walk up class hierarchy until we find an icon UClass* ActorClass = InClass; while( (Brush == NULL || Brush == FEditorStyle::GetDefaultBrush()) && ActorClass && (ActorClass != AActor::StaticClass()) ) { BrushName = *FString::Printf( TEXT( "ClassIcon.%s" ), *ActorClass->GetName() ); Brush = FEditorStyle::GetBrush( BrushName ); ActorClass = ActorClass->GetSuperClass(); } } if( Brush == NULL || Brush == FEditorStyle::GetDefaultBrush() ) { // If we didn't supply an override name for the default icon use default class icon. if( InDefaultName == "" ) { BrushName = TEXT( "ClassIcon.Default" ); } else { BrushName = InDefaultName; } } return BrushName; }
FString UK2Node_BaseMCDelegate::GetDocumentationLink() const { UClass* ParentClass = NULL; if (DelegateReference.IsSelfContext()) { if (HasValidBlueprint()) { UField* Delegate = FindField<UField>(GetBlueprint()->GeneratedClass, DelegateReference.GetMemberName()); if (Delegate != NULL) { ParentClass = Delegate->GetOwnerClass(); } } } else { ParentClass = DelegateReference.GetMemberParentClass(this); } if ( ParentClass != NULL ) { return FString( TEXT("Shared/") ) + ParentClass->GetName(); } return TEXT(""); }
// Disassemble all functions in any classes that have matching names. void FKismetBytecodeDisassembler::DisassembleAllFunctionsInClasses(FOutputDevice& Ar, const FString& ClassnameSubstring) { FKismetBytecodeDisassembler Disasm(Ar); for (TObjectIterator<UClass> ClassIter; ClassIter; ++ClassIter) { UClass* Class = *ClassIter; FString ClassName = Class->GetName(); if (FCString::Strfind(*ClassName, *ClassnameSubstring)) { Ar.Logf(TEXT("Processing class %s"), *ClassName); for (TFieldIterator<UFunction> FunctionIter(Class, EFieldIteratorFlags::ExcludeSuper); FunctionIter; ++FunctionIter) { UFunction* Function = *FunctionIter; FString FunctionName = Function->GetName(); Ar.Logf(TEXT(" Processing function %s (%d bytes)"), *FunctionName, Function->Script.Num()); Disasm.DisassembleStructure(Function); Ar.Logf(TEXT("")); } Ar.Logf(TEXT("")); Ar.Logf(TEXT("-----------")); Ar.Logf(TEXT("")); } } }
FArchive& FArchiveDescribeReference::operator<<( class UObject*& Obj ) { if (Obj == Target) { if (GSerializedProperty) { Output.Logf(TEXT(" [%s]"), *GSerializedProperty->GetFullName()); } else { Output.Logf(TEXT(" [native]")); } PTRINT BigOffset = ((uint8*)&Obj) - (uint8*)Source; if (BigOffset > 0 && BigOffset < Source->GetClass()->GetPropertiesSize()) { int32 Offset = int32(BigOffset); UClass* UseClass = Source->GetClass(); UClass* SuperClass = UseClass->GetSuperClass(); while (1) { if (!SuperClass || Offset >= SuperClass->GetPropertiesSize()) { break; } UseClass = SuperClass; SuperClass = UseClass->GetSuperClass(); } Output.Logf(TEXT(" class %s offset %d, offset from UObject %d "), *UseClass->GetName(), SuperClass ? Offset - SuperClass->GetPropertiesSize() : Offset, Offset); } } return *this; }
FString SPropertyEditorAsset::OnGetAssetClassName() const { UClass* Class = GetDisplayedClass(); if(Class) { return Class->GetName(); } return FString(); }
void UK2Node_SpawnActor::GetNodeAttributes( TArray<TKeyValuePair<FString, FString>>& OutNodeAttributes ) const { UClass* ClassToSpawn = GetClassToSpawn(); const FString ClassToSpawnStr = ClassToSpawn ? ClassToSpawn->GetName() : TEXT( "InvalidClass" ); OutNodeAttributes.Add( TKeyValuePair<FString, FString>( TEXT( "Type" ), TEXT( "SpawnActor" ) )); OutNodeAttributes.Add( TKeyValuePair<FString, FString>( TEXT( "Class" ), GetClass()->GetName() )); OutNodeAttributes.Add( TKeyValuePair<FString, FString>( TEXT( "Name" ), GetName() )); OutNodeAttributes.Add( TKeyValuePair<FString, FString>( TEXT( "ActorClass" ), ClassToSpawnStr )); }
/** * Gathers all blueprints for the actors in question, outputting them to the classes array */ void GatherBlueprintsForActors( TArray< AActor* >& Actors, TArray< FMenuBlueprintClass >& Classes ) { struct Local { static void AddBlueprint( TArray< FMenuBlueprintClass >& InClasses, const FString& ClassName, UBlueprint* Blueprint = NULL ) { check( !ClassName.IsEmpty() ); // Check to see if we already have this class name in our list FMenuBlueprintClass* FoundClass = NULL; for( int32 CurClassIndex = 0; CurClassIndex < InClasses.Num(); ++CurClassIndex ) { FMenuBlueprintClass& CurClass = InClasses[ CurClassIndex ]; if( CurClass.Name == ClassName ) { FoundClass = &CurClass; break; } } // Add a new class to our list if we need to if( FoundClass == NULL ) { FoundClass = new( InClasses ) FMenuBlueprintClass(); FoundClass->Name = ClassName; FoundClass->Blueprint = Blueprint; } else { check(FoundClass->Blueprint.Get() == Blueprint); } } }; for( TArray< AActor* >::TIterator It( Actors ); It; ++It ) { AActor* Actor = static_cast<AActor*>( *It ); checkSlow( Actor->IsA(AActor::StaticClass()) ); // Grab the class of this actor UClass* ActorClass = Actor->GetClass(); check( ActorClass != NULL ); // Walk the inheritance hierarchy for this class for( UClass* CurClass = ActorClass; CurClass != NULL; CurClass = CurClass->GetSuperClass() ) { if (UBlueprint* Blueprint = Cast<UBlueprint>(CurClass->ClassGeneratedBy)) { // Class was created by a blueprint, so don't offer C++ editing of functions declared in it // Instead offer to edit the events and graphs of the blueprint Local::AddBlueprint( Classes, CurClass->GetName(), Blueprint ); } } } }
FText SPropertyEditorAsset::OnGetAssetClassName() const { UClass* Class = GetDisplayedClass(); if(Class) { return FText::FromString(Class->GetName()); } return FText::GetEmpty(); }
static UMulticastDelegateProperty* FindAndCheckDelegateProperty(FKismetFunctionContext& Context, UK2Node_BaseMCDelegate * DelegateNode, FCompilerResultsLog& MessageLog, const UEdGraphSchema_K2* Schema) { check(NULL != DelegateNode); UEdGraphPin* Pin = Schema->FindSelfPin(*DelegateNode, EEdGraphPinDirection::EGPD_Input); UStruct* DelegateScope = Pin ? Context.GetScopeFromPinType(Pin->PinType, Context.NewClass) : NULL; // Early out if we have no pin. That means the delegate is no longer valid, and we need to terminate gracefully if (!Pin || !DelegateScope) { MessageLog.Error(*LOCTEXT("NoDelegateProperty", "Event Dispatcher has no property @@").ToString(), DelegateNode); return NULL; } // Don't use DelegateNode->GetProperty(), because we don't want any property from skeletal class UClass* PropertyOwnerClass = CastChecked<UClass>(DelegateScope); UMulticastDelegateProperty* BoundProperty = NULL; for (TFieldIterator<UMulticastDelegateProperty> It(PropertyOwnerClass); It; ++It) { UMulticastDelegateProperty* Prop = *It; if (DelegateNode->GetPropertyName() == Prop->GetFName()) { BoundProperty = Prop; break; } } if (!BoundProperty) { FString const OwnerName = PropertyOwnerClass->GetName(); FString const PropName = DelegateNode->GetPropertyName().ToString(); FText const ErrorFormat = LOCTEXT("DelegateNotFound", "Could not find an event-dispatcher named \"%s\" in '%s'.\nMake sure '%s' has been compiled for @@"); MessageLog.Error(*FString::Printf(*ErrorFormat.ToString(), *PropName, *OwnerName, *OwnerName), DelegateNode); return NULL; } { // MulticastDelegateProperty from NewClass may have empty signature, but property from skeletal class should have it. const UFunction* OrgSignature = DelegateNode->GetDelegateSignature(); if(const UEdGraphPin* DelegatePin = DelegateNode->GetDelegatePin()) { const UFunction* PinSignature = FMemberReference::ResolveSimpleMemberReference<UFunction>(DelegatePin->PinType.PinSubCategoryMemberReference); if (!OrgSignature || !PinSignature || !OrgSignature->IsSignatureCompatibleWith(PinSignature)) { MessageLog.Error(*LOCTEXT("WrongDelegate", "Wrong Event Dispatcher. Refresh node @@").ToString(), DelegateNode); return NULL; } } CheckOutputsParametersInDelegateSignature(OrgSignature, DelegateNode, MessageLog); } return BoundProperty; }
void UK2Node_LiveEditObject::GetNodeAttributes( TArray<TKeyValuePair<FString, FString>>& OutNodeAttributes ) const { UClass* ClassToSpawn = GetClassToSpawn(); const FString ClassToSpawnStr = ClassToSpawn ? ClassToSpawn->GetName() : TEXT( "UnknownClass" ); OutNodeAttributes.Add( TKeyValuePair<FString, FString>( TEXT( "Type" ), TEXT( "LiveEditObject" ) )); OutNodeAttributes.Add( TKeyValuePair<FString, FString>( TEXT( "Class" ), GetClass()->GetName() )); OutNodeAttributes.Add( TKeyValuePair<FString, FString>( TEXT( "Name" ), GetName() )); OutNodeAttributes.Add( TKeyValuePair<FString, FString>( TEXT( "ClassToSpawn" ), ClassToSpawnStr )); OutNodeAttributes.Add( TKeyValuePair<FString, FString>( TEXT( "EventName" ), GetEventName() )); }
void UK2Node_AddComponent::ValidateNodeDuringCompilation(FCompilerResultsLog& MessageLog) const { Super::ValidateNodeDuringCompilation(MessageLog); UActorComponent* Template = GetTemplateFromNode(); if (Template) { UClass* TemplateClass = Template->GetClass(); if (!TemplateClass->IsChildOf(UActorComponent::StaticClass()) || TemplateClass->HasAnyClassFlags(CLASS_Abstract) || !TemplateClass->HasMetaData(FBlueprintMetadata::MD_BlueprintSpawnableComponent) ) { FFormatNamedArguments Args; Args.Add(TEXT("TemplateClass"), FText::FromString(TemplateClass->GetName())); Args.Add(TEXT("NodeTitle"), GetNodeTitle(ENodeTitleType::FullTitle)); MessageLog.Error(*FText::Format(NSLOCTEXT("KismetCompiler", "InvalidComponentTemplate_Error", "Invalid class '{TemplateClass}' used as template by '{NodeTitle}' for @@"), Args).ToString(), this); } if (UChildActorComponent const* ChildActorComponent = Cast<UChildActorComponent const>(Template)) { UBlueprint const* Blueprint = GetBlueprint(); UClass const* ChildActorClass = ChildActorComponent->GetChildActorClass(); if (ChildActorClass == Blueprint->GeneratedClass) { UEdGraph const* ParentGraph = GetGraph(); UEdGraphSchema_K2 const* K2Schema = GetDefault<UEdGraphSchema_K2>(); if (K2Schema->IsConstructionScript(ParentGraph)) { FFormatNamedArguments Args; Args.Add(TEXT("ChildActorClass"), FText::FromString(ChildActorClass->GetName())); MessageLog.Error(*FText::Format(NSLOCTEXT("KismetCompiler", "AddSelfComponent_Error", "@@ cannot add a '{ChildActorClass}' component in the construction script (could cause infinite recursion)."), Args).ToString(), this); } } else if (ChildActorClass != nullptr) { AActor const* ChildActor = Cast<AActor>(ChildActorClass->ClassDefaultObject); check(ChildActor != nullptr); USceneComponent* RootComponent = ChildActor->GetRootComponent(); if ((RootComponent != nullptr) && (RootComponent->Mobility == EComponentMobility::Static) && (ChildActorComponent->Mobility != EComponentMobility::Static)) { FFormatNamedArguments Args; Args.Add(TEXT("ChildActorClass"), FText::FromString(ChildActorClass->GetName())); MessageLog.Error(*FText::Format(NSLOCTEXT("KismetCompiler", "AddStaticChildActorComponent_Error", "@@ cannot add a '{ChildActorClass}' component as it has static mobility, and the ChildActorComponent does not."), Args).ToString(), this); } } } } else { FFormatNamedArguments Args; Args.Add(TEXT("NodeTitle"), GetNodeTitle(ENodeTitleType::FullTitle)); MessageLog.Error(*FText::Format(NSLOCTEXT("KismetCompiler", "MissingComponentTemplate_Error", "Unknown template referenced by '{NodeTitle}' for @@"), Args).ToString(), this); } }
FString FLuaScriptCodeGenerator::ExportFunction(const FString& ClassNameCPP, UClass* Class, UFunction* Function) { FString GeneratedGlue = GenerateWrapperFunctionDeclaration(ClassNameCPP, Class, Function); GeneratedGlue += TEXT("\r\n{\r\n"); UProperty* ReturnValue = NULL; UClass* FuncSuper = NULL; if (Function->GetOwnerClass() != Class) { // Find the base definition of the function if (ExportedClasses.Contains(Function->GetOwnerClass()->GetFName())) { FuncSuper = Function->GetOwnerClass(); } } FString FunctionBody; if (FuncSuper == NULL) { FunctionBody += FString::Printf(TEXT("\t%s\r\n"), *GenerateObjectDeclarationFromContext(ClassNameCPP, Class)); FunctionBody += GenerateFunctionDispatch(Function); FString FunctionCallArguments; FString ReturnValueDeclaration; for (TFieldIterator<UProperty> ParamIt(Function); !ReturnValue && ParamIt; ++ParamIt) { UProperty* Param = *ParamIt; if (Param->GetPropertyFlags() & CPF_ReturnParm) { ReturnValue = Param; } } FString ReturnValueName; if (ReturnValue) { ReturnValueName = FString::Printf(TEXT("Params.%s"), *ReturnValue->GetName()); } FunctionBody += FString::Printf(TEXT("\t%s\r\n"), *GenerateReturnValueHandler(ClassNameCPP, Class, Function, ReturnValue, *ReturnValueName)); } else { FunctionBody = FString::Printf(TEXT("\treturn %s_%s(InScriptContext);\r\n"), *FuncSuper->GetName(), *Function->GetName()); } GeneratedGlue += FunctionBody; GeneratedGlue += TEXT("}\r\n\r\n"); auto& Exports = ClassExportedFunctions.FindOrAdd(Class); Exports.Add(Function->GetFName()); return GeneratedGlue; }
FString UInterfaceProperty::GetCPPTypeForwardDeclaration() const { checkSlow(InterfaceClass); UClass* ExportClass = InterfaceClass; while (ExportClass && !ExportClass->HasAnyClassFlags(CLASS_Native)) { ExportClass = ExportClass->GetSuperClass(); } check(ExportClass); check(ExportClass->HasAnyClassFlags(CLASS_Interface)); return FString::Printf(TEXT("class I%s;"), *ExportClass->GetName()); }
const FString& AActor::GetActorLabel() const { // If the label string is empty then we'll use the default actor label (usually the actor's class name.) // We actually cache the default name into our ActorLabel property. This will be saved out with the // actor if the actor gets saved. The reasons we like caching the name here is: // // a) We can return it by const& (performance) // b) Calling GetDefaultActorLabel() is slow because of FName stuff (performance) // c) If needed, we could always empty the ActorLabel string if it matched the default // // Remember, ActorLabel is currently an editor-only property. if( ActorLabel.IsEmpty() ) { // Treating ActorLabel as mutable here (no 'mutable' keyword in current script compiler) AActor* MutableThis = const_cast< AActor* >( this ); // Get the class UClass* ActorClass = GetClass(); // NOTE: Calling GetName() is actually fairly slow (does ANSI->Wide conversion, lots of copies, etc.) FString DefaultActorLabel = ActorClass->GetName(); // Strip off the ugly "_C" suffix for Blueprint class actor instances UBlueprint* GeneratedByClassBlueprint = Cast<UBlueprint>( ActorClass->ClassGeneratedBy ); if( GeneratedByClassBlueprint != nullptr && DefaultActorLabel.EndsWith( TEXT( "_C" ) ) ) { DefaultActorLabel.RemoveFromEnd( TEXT( "_C" ) ); } // We want the actor's label to be initially unique, if possible, so we'll use the number of the // actor's FName when creating the initially. It doesn't actually *need* to be unique, this is just // an easy way to tell actors apart when observing them in a list. The user can always go and rename // these labels such that they're no longer unique. { // Don't bother adding a suffix for number '0' const int32 NameNumber = NAME_INTERNAL_TO_EXTERNAL( GetFName().GetNumber() ); if( NameNumber != 0 ) { DefaultActorLabel.AppendInt(NameNumber); } } // Remember, there could already be an actor with the same label in the level. But that's OK, because // actor labels aren't supposed to be unique. We just try to make them unique initially to help // disambiguate when opening up a new level and there are hundreds of actors of the same type. MutableThis->ActorLabel = DefaultActorLabel; } return ActorLabel; }
FText FSimpleAssetEditor::GetToolkitToolTipText() const { const TArray<UObject*>& EditingObjs = GetEditingObjects(); check( EditingObjs.Num() > 0 ); FFormatNamedArguments Args; Args.Add( TEXT("ToolkitName"), GetBaseToolkitName() ); if( EditingObjs.Num() == 1 ) { const UObject* EditingObject = EditingObjs[ 0 ]; return FAssetEditorToolkit::GetToolTipTextForObject(EditingObject); } else { UClass* SharedBaseClass = NULL; for( int32 x = 0; x < EditingObjs.Num(); ++x ) { UObject* Obj = EditingObjs[ x ]; check( Obj ); UClass* ObjClass = Cast<UClass>(Obj); if (ObjClass == nullptr) { ObjClass = Obj->GetClass(); } check( ObjClass ); // Initialize with the class of the first object we encounter. if( SharedBaseClass == nullptr ) { SharedBaseClass = ObjClass; } // If we've encountered an object that's not a subclass of the current best baseclass, // climb up a step in the class hierarchy. while( !ObjClass->IsChildOf( SharedBaseClass ) ) { SharedBaseClass = SharedBaseClass->GetSuperClass(); } } check(SharedBaseClass); Args.Add( TEXT("NumberOfObjects"), EditingObjs.Num() ); Args.Add( TEXT("ClassName"), FText::FromString( SharedBaseClass->GetName() ) ); return FText::Format( LOCTEXT("ToolkitTitle_EditingMultipleToolTip", "{NumberOfObjects} {ClassName} - {ToolkitName}"), Args ); } }
/** * Returns the text to use for exporting this property to header file. * * @param ExtendedTypeText for property types which use templates, will be filled in with the type * @param CPPExportFlags flags for modifying the behavior of the export */ FString UInterfaceProperty::GetCPPMacroType( FString& ExtendedTypeText ) const { checkSlow(InterfaceClass); UClass* ExportClass = InterfaceClass; while ( ExportClass && !ExportClass->HasAnyClassFlags(CLASS_Native) ) { ExportClass = ExportClass->GetSuperClass(); } check(ExportClass); check(ExportClass->HasAnyClassFlags(CLASS_Interface)); ExtendedTypeText = FString::Printf(TEXT("I%s"), *ExportClass->GetName()); return TEXT("TINTERFACE"); }
void SGAAttributeWidget::Construct(const FArguments& InArgs) { AttributesList.Empty(); AttributesNodes.Empty(); OnAttributeSelected = InArgs._OnAttributeSelectedIn; for (TObjectIterator<UClass> ClassIt; ClassIt; ++ClassIt) { UClass* Class = *ClassIt; if (Class->IsChildOf(UGAAttributesBase::StaticClass()) && !FKismetEditorUtilities::IsClassABlueprintSkeleton(Class)) { FString className = Class->GetName(); if (!className.Contains(TEXT("REINST_"))) { TSharedPtr<FGAAttributeNode> attributeNode = MakeShareable(new FGAAttributeNode()); attributeNode->Attribute = className; for (TFieldIterator<UProperty> PropertyIt(Class, EFieldIteratorFlags::ExcludeSuper); PropertyIt; ++PropertyIt) { UProperty* Prop = *PropertyIt; //I need array within array, one for list of attributes, and one for class names. // TSharedPtr<FString> attribute = MakeShareable(new FString(Prop->GetName())); attributeNode->AttributeNames.Add(Prop->GetName()); //AttributesList.Add(attribute); } AttributesNodes.Add(attributeNode); } } } ChildSlot [ SAssignNew(AttributeTreeWidget, STreeView<TSharedPtr<FGAAttributeNode>>) .OnSelectionChanged(this, &SGAAttributeWidget::OnItemSelected) .TreeItemsSource(&AttributesNodes) .OnGenerateRow(this, &SGAAttributeWidget::OnGenerateRow) .OnGetChildren(this, &SGAAttributeWidget::OnGetChildren) .OnExpansionChanged(this, &SGAAttributeWidget::OnExpansionChanged) .SelectionMode(ESelectionMode::Single) ]; }
FText UFactory::GetDisplayName() const { FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools"); UClass* LocalSupportedClass = GetSupportedClass(); if ( LocalSupportedClass ) { TWeakPtr<IAssetTypeActions> AssetTypeActions = AssetToolsModule.Get().GetAssetTypeActionsForClass(LocalSupportedClass); if ( AssetTypeActions.IsValid() ) { // @todo AssetTypeActions should be returning a FText so we dont have to do this conversion here. return AssetTypeActions.Pin()->GetName(); } // Factories whose classes do not have asset type actions should just display the sanitized class name return FText::FromString( FName::NameToDisplayString(*LocalSupportedClass->GetName(), false) ); } // Factories that have no supported class have no display name. return FText(); }
/** * Returns the text to use for exporting this property to header file. * * @param ExtendedTypeText for property types which use templates, will be filled in with the type * @param CPPExportFlags flags for modifying the behavior of the export */ FString UInterfaceProperty::GetCPPType( FString* ExtendedTypeText/*=NULL*/, uint32 CPPExportFlags/*=0*/ ) const { checkSlow(InterfaceClass); if ( ExtendedTypeText != NULL ) { UClass* ExportClass = InterfaceClass; if (0 == (CPPF_BlueprintCppBackend & CPPExportFlags)) { while (ExportClass && !ExportClass->HasAnyClassFlags(CLASS_Native)) { ExportClass = ExportClass->GetSuperClass(); } } check(ExportClass); check(ExportClass->HasAnyClassFlags(CLASS_Interface) || 0 != (CPPF_BlueprintCppBackend & CPPExportFlags)); *ExtendedTypeText = FString::Printf(TEXT("<I%s>"), *ExportClass->GetName()); } return TEXT("TScriptInterface"); }
FString FClassData::ToString() const { UClass* MyClass = Class.Get(); if (MyClass) { FString ClassDesc = MyClass->GetName(); if (MyClass->HasAnyClassFlags(CLASS_CompiledFromBlueprint)) { return ClassDesc.LeftChop(2); } const int32 ShortNameIdx = ClassDesc.Find(TEXT("_")); if (ShortNameIdx != INDEX_NONE) { ClassDesc = ClassDesc.Mid(ShortNameIdx + 1); } return ClassDesc; } return AssetName; }
wstring UObject::GetNameCPP() { wstring R; if( this->IsA( UClass::StaticClass() ) ) { UClass *pClass = ( UClass* )this; while( pClass ) { wstring className = pClass->GetName(); if( className.compare( L"Actor" ) == 0 ) { R = wstring( L"A" ); break; } else if( className.compare( L"Object" ) == 0 ) { R = wstring( L"U" ); break; } pClass = ( UClass* ) pClass->SuperField; } } else { R = wstring( L"F" ); } R += this->GetName(); return R; }
void UChildActorComponent::DestroyChildActor() { // If we own an Actor, kill it now unless we don't have authority on it, for that we rely on the server // If the level that the child actor is being removed then don't destory the child actor so re-adding it doesn't // need to create a new actor if (ChildActor && ChildActor->HasAuthority() && !GetOwner()->GetLevel()->bIsBeingRemoved) { if (!GExitPurge) { // if still alive, destroy, otherwise just clear the pointer if (!ChildActor->IsPendingKillOrUnreachable()) { #if WITH_EDITOR if (CachedInstanceData) { delete CachedInstanceData; CachedInstanceData = nullptr; } #else check(!CachedInstanceData); #endif // If we're already tearing down we won't be needing this if (!HasAnyFlags(RF_BeginDestroyed) && !IsUnreachable()) { CachedInstanceData = new FChildActorComponentInstanceData(this); } UWorld* World = ChildActor->GetWorld(); // World may be nullptr during shutdown if (World != nullptr) { UClass* ChildClass = ChildActor->GetClass(); // We would like to make certain that our name is not going to accidentally get taken from us while we're destroyed // so we increment ClassUnique beyond our index to be certain of it. This is ... a bit hacky. int32& ClassUnique = ChildActor->GetOutermost()->ClassUniqueNameIndexMap.FindOrAdd(ChildClass->GetFName()); ClassUnique = FMath::Max(ClassUnique, ChildActor->GetFName().GetNumber()); // If we are getting here due to garbage collection we can't rename, so we'll have to abandon this child actor name and pick up a new one if (!IsGarbageCollecting()) { const FString ObjectBaseName = FString::Printf(TEXT("DESTROYED_%s_CHILDACTOR"), *ChildClass->GetName()); const ERenameFlags RenameFlags = ((GetWorld()->IsGameWorld() || IsLoading()) ? REN_DoNotDirty | REN_ForceNoResetLoaders : REN_DoNotDirty); ChildActor->Rename(*MakeUniqueObjectName(ChildActor->GetOuter(), ChildClass, *ObjectBaseName).ToString(), nullptr, RenameFlags); } else { ChildActorName = NAME_None; if (CachedInstanceData) { CachedInstanceData->ChildActorName = NAME_None; } } World->DestroyActor(ChildActor); } } } ChildActor = nullptr; } }
void SGraphNodeK2Timeline::GetNodeInfoPopups(FNodeInfoContext* Context, TArray<FGraphInformationPopupInfo>& Popups) const { FKismetNodeInfoContext* K2Context = (FKismetNodeInfoContext*)Context; // Display the timeline status bubble if (UObject* ActiveObject = K2Context->ActiveObjectBeingDebugged) { UProperty* NodeProperty = FKismetDebugUtilities::FindClassPropertyForNode(K2Context->SourceBlueprint, GraphNode); if (UObjectProperty* TimelineProperty = Cast<UObjectProperty>(NodeProperty)) { UClass* ContainingClass = TimelineProperty->GetTypedOuter<UClass>(); if (!ActiveObject->IsA(ContainingClass)) { const FString ErrorText = FString::Printf(*LOCTEXT("StaleDebugData", "Stale debug data\nProperty is on %s\nDebugging a %s").ToString(), *ContainingClass->GetName(), *ActiveObject->GetClass()->GetName()); new (Popups) FGraphInformationPopupInfo(NULL, TimelineBubbleColor, ErrorText); } else if (UTimelineComponent* Timeline = Cast<UTimelineComponent>(TimelineProperty->GetObjectPropertyValue(TimelineProperty->ContainerPtrToValuePtr<void>(ActiveObject)))) { // Current state const FString State = Timeline->IsPlaying() ? LOCTEXT("Playing", "Playing").ToString() : LOCTEXT("Paused", "Paused").ToString(); // Play direction, only shown if playing FString Direction; if (Timeline->IsReversing()) { Direction = LOCTEXT("InReverse", " (in reverse)").ToString(); } // Position const float Percentage = Timeline->GetTimelineLength() > 0.0f ? Timeline->GetPlaybackPosition() / Timeline->GetTimelineLength() * 100.0f : 0.0f; const FString Position = FString::Printf(TEXT(" @ %.2f s (%.1f %%)"), Timeline->GetPlaybackPosition(), Percentage); // Looping status, only shown if playing FString Looping; if (Timeline->IsPlaying() && Timeline->IsLooping()) { Looping = LOCTEXT("Looping", " (looping)").ToString(); } // Putting it all together FString TimelineText = FString::Printf(TEXT("%s\n%s%s%s%s"), *(UEditorEngine::GetFriendlyName(TimelineProperty)), *State, *Direction, *Position, *Looping); new (Popups) FGraphInformationPopupInfo(NULL, TimelineBubbleColor, TimelineText); } } } SGraphNodeK2Default::GetNodeInfoPopups(Context, Popups); }
static void AddStaticFunctionsForDependencies(FEmitterLocalContext& Context) { auto SourceClass = Context.GetCurrentlyGeneratedClass(); auto OriginalClass = Context.Dependencies.FindOriginalClass(SourceClass); const FString CppClassName = FEmitHelper::GetCppName(OriginalClass); // __StaticDependenciesAssets Context.AddLine(FString::Printf(TEXT("void %s::__StaticDependenciesAssets(TArray<FBlueprintDependencyData>& AssetsToLoad)"), *CppClassName)); Context.AddLine(TEXT("{")); Context.IncreaseIndent(); auto CreateAssetToLoadString = [&](const UObject* AssetObj) -> FString { UClass* AssetType = AssetObj->GetClass(); if (AssetType->IsChildOf<UUserDefinedEnum>()) { AssetType = UEnum::StaticClass(); } else if (AssetType->IsChildOf<UUserDefinedStruct>()) { AssetType = UScriptStruct::StaticClass(); } else if (AssetType->IsChildOf<UBlueprintGeneratedClass>() && Context.Dependencies.WillClassBeConverted(CastChecked<UBlueprintGeneratedClass>(AssetObj))) { AssetType = UDynamicClass::StaticClass(); } return FString::Printf(TEXT("AssetsToLoad.Add({FName(TEXT(\"%s\")), FName(TEXT(\"%s\")), FName(TEXT(\"%s\")), FName(TEXT(\"%s\"))});") , *AssetObj->GetOutermost()->GetPathName() , *AssetObj->GetName() , *AssetType->GetOutermost()->GetPathName() , *AssetType->GetName()); }; for (UObject* LocAsset : Context.Dependencies.Assets) { Context.AddLine(CreateAssetToLoadString(LocAsset)); } for (UObject* LocAsset : Context.Dependencies.ConvertedClasses) { if (!Context.Dependencies.Assets.Contains(LocAsset)) { Context.AddLine(CreateAssetToLoadString(LocAsset)); } } Context.DecreaseIndent(); Context.AddLine(TEXT("}")); // Register Helper Struct const FString RegisterHelperName = FString::Printf(TEXT("FRegisterHelper__%s"), *CppClassName); Context.AddLine(FString::Printf(TEXT("struct %s"), *RegisterHelperName)); Context.AddLine(TEXT("{")); Context.IncreaseIndent(); Context.AddLine(FString::Printf(TEXT("%s()"), *RegisterHelperName)); Context.AddLine(TEXT("{")); Context.IncreaseIndent(); Context.AddLine(FString::Printf( TEXT("FConvertedBlueprintsDependencies::Get().RegisterClass(TEXT(\"%s\"), &%s::__StaticDependenciesAssets);") , *OriginalClass->GetOutermost()->GetPathName() , *CppClassName)); Context.DecreaseIndent(); Context.AddLine(TEXT("}")); Context.AddLine(FString::Printf(TEXT("static %s Instance;"), *RegisterHelperName)); Context.DecreaseIndent(); Context.AddLine(TEXT("};")); Context.AddLine(FString::Printf(TEXT("%s %s::Instance;"), *RegisterHelperName, *RegisterHelperName)); }
bool FJsonObjectConverter::UStructToJsonObject(const UStruct* StructDefinition, const void* Struct, TSharedRef<FJsonObject> OutJsonObject, int64 CheckFlags, int64 SkipFlags) { for(TFieldIterator<UProperty> It(StructDefinition); It; ++It) { UProperty* Property = *It; // Check to see if we should ignore this property if (CheckFlags != 0 && !Property->HasAnyPropertyFlags(CheckFlags)) { continue; } if (Property->HasAnyPropertyFlags(SkipFlags)) { continue; } FString VariableName = StandardizeCase(Property->GetName()); const void* Value = Property->ContainerPtrToValuePtr<uint8>(Struct); // convert the property to a FJsonValue TSharedPtr<FJsonValue> JsonValue = UPropertyToJsonValue(Property, Value, CheckFlags, SkipFlags); if (!JsonValue.IsValid()) { UClass* PropClass = Property->GetClass(); UE_LOG(LogJson, Error, TEXT("UStructToJsonObject - Unhandled property type '%s': %s"), *PropClass->GetName(), *Property->GetPathName()); return false; } // set the value on the output object OutJsonObject->SetField(VariableName, JsonValue); } return true; }
/** * Deserialize the data contained within a message using the parameter fields of a given UStruct * @param Message message containing the data to retrieve * @param Object structure containing reflection information that matches message * @param Parms memory layout to store the message's data * @param PropFlags any flags relevant to the field iteration * * @return TRUE if successful, FALSE otherwise */ bool DeserializeRPCParams(const google::protobuf::Message* Message, UStruct* Object, void* Parms, int64 PropFlags) { bool bSuccess = true; const google::protobuf::Descriptor* Desc = Message->GetDescriptor(); const google::protobuf::Reflection* Refl = Message->GetReflection(); for(TFieldIterator<UProperty> It(Object); It && (It->PropertyFlags & PropFlags); ++It) { UProperty* Property = *It; UClass* PropClass = Property->GetClass(); const google::protobuf::FieldDescriptor* FieldDesc = Desc->FindFieldByName(TCHAR_TO_UTF8(*Property->GetNameCPP())); if (FieldDesc) { if (FieldDesc->is_repeated()) { int32 NumElements = Refl->FieldSize(*Message, FieldDesc); FScriptArrayHelper* ArrayHelper = NULL; if (PropClass == UArrayProperty::StaticClass()) { void* Value = Property->ContainerPtrToValuePtr<uint8>(Parms); UArrayProperty* ArrayProperty = Cast<UArrayProperty>(Property); Property = ArrayProperty->Inner; PropClass = Property->GetClass(); ArrayHelper = new FScriptArrayHelper(ArrayProperty, Value); ArrayHelper->EmptyAndAddValues(NumElements); } else { if (Property->ArrayDim < NumElements) { UE_LOG_ONLINE(Error, TEXT("DeserializeRPCParams - Static array mismatch (%d != %d) property type '%s': %s"), NumElements, Property->ArrayDim, *PropClass->GetName(), *Property->GetPathName()); NumElements = Property->ArrayDim; } } for (int32 i = 0; i < NumElements; i++) { void* Value = ArrayHelper ? ArrayHelper->GetRawPtr(i) : Property->ContainerPtrToValuePtr<uint8>(Parms, i); if (PropClass == UIntProperty::StaticClass()) { *(int32*)Value = Refl->GetRepeatedInt32(*Message, FieldDesc, i); } else if (PropClass == UFloatProperty::StaticClass()) { *(float*)Value = Refl->GetRepeatedFloat(*Message, FieldDesc, i); } else if (PropClass == UBoolProperty::StaticClass() && CastChecked<UBoolProperty>(Property)->IsNativeBool()) { *(bool*)Value = Refl->GetRepeatedBool(*Message, FieldDesc, i); } else if (PropClass == UByteProperty::StaticClass() && CastChecked<UByteProperty>(Property)->Enum == NULL) { const google::protobuf::string& String = Refl->GetRepeatedStringReference(*Message, FieldDesc, i, NULL); if (ArrayHelper) { // Message only contains one string, but we need an array of bytes ArrayHelper->AddValues(String.size() - 1); Value = ArrayHelper->GetRawPtr(i); } FMemory::Memcpy(Value, String.c_str(), String.size()); break; } else if (PropClass == UStrProperty::StaticClass()) { const google::protobuf::string& String = Refl->GetRepeatedStringReference(*Message, FieldDesc, i, NULL); *(FString*)Value = UTF8_TO_TCHAR(String.c_str()); } else if (PropClass == UStructProperty::StaticClass()) { UStructProperty* StructProperty = Cast<UStructProperty>(Property); const google::protobuf::Message& SubMessage = Refl->GetRepeatedMessage(*Message, FieldDesc, i); DeserializeRPCParams(&SubMessage, StructProperty->Struct, Value, CPF_AllFlags); } else { bSuccess = false; UE_LOG_ONLINE(Error, TEXT("DeserializeRPCParams - Unhandled property type '%s': %s"), *PropClass->GetName(), *Property->GetPathName()); } } if (ArrayHelper) { delete ArrayHelper; } } else { if (Property->ArrayDim == 1) { void* Value = Property->ContainerPtrToValuePtr<uint8>(Parms); if (PropClass == UIntProperty::StaticClass()) { *(int32*)Value = Refl->GetInt32(*Message, FieldDesc); } else if (PropClass == UFloatProperty::StaticClass()) { *(float*)Value = Refl->GetFloat(*Message, FieldDesc); } else if (PropClass == UBoolProperty::StaticClass() && CastChecked<UBoolProperty>(Property)->IsNativeBool()) { *(bool*)Value = Refl->GetBool(*Message, FieldDesc); } else if (PropClass == UByteProperty::StaticClass() && CastChecked<UByteProperty>(Property)->Enum == NULL) { int32 NumBytes = Refl->FieldSize(*Message, FieldDesc); google::protobuf::string Bytes = Refl->GetString(*Message, FieldDesc); FMemory::Memcpy(Value, Bytes.c_str(), NumBytes); } else if (PropClass == UStrProperty::StaticClass()) { google::protobuf::string String = Refl->GetString(*Message, FieldDesc); *(FString*)Value = UTF8_TO_TCHAR(String.c_str()); } else if (PropClass == UStructProperty::StaticClass()) { UStructProperty* StructProperty = Cast<UStructProperty>(Property); const google::protobuf::Message& SubMessage = Refl->GetMessage(*Message, FieldDesc); DeserializeRPCParams(&SubMessage, StructProperty->Struct, Value, CPF_AllFlags); } else { bSuccess = false; UE_LOG_ONLINE(Error, TEXT("DeserializeRPCParams - Unhandled property type '%s': %s"), *PropClass->GetName(), *Property->GetPathName()); } } else { bSuccess = false; UE_LOG_ONLINE(Error, TEXT("DeserializeRPCParams - Property reflection mismatch type '%s': %s"), *PropClass->GetName(), *Property->GetPathName()); } } } else { bSuccess = false; UE_LOG_ONLINE(Error, TEXT("DeserializeRPCParams - Property reflection missing type '%s': %s"), *PropClass->GetName(), *Property->GetPathName()); } } return bSuccess; }
/** * Serialize the parameter fields of a given UStruct into a message object * @param NewMessage message to fill * @param Object structure containing reflection information that matches message * @param Parms data to serialize into the new message * @param PropFlags any flags relevant to the field iteration * * @return TRUE if successful, FALSE otherwise */ bool SerializeRPCParams(google::protobuf::Message* NewMessage, UStruct* Object, void* Parms, int64 PropFlags) { bool bSuccess = true; const google::protobuf::Descriptor* Desc = NewMessage->GetDescriptor(); const google::protobuf::Reflection* Refl = NewMessage->GetReflection(); for(TFieldIterator<UProperty> It(Object); It && (It->PropertyFlags & PropFlags); ++It) { UProperty* Property = *It; UClass* PropClass = Property->GetClass(); const google::protobuf::FieldDescriptor* FieldDesc = Desc->FindFieldByName(TCHAR_TO_UTF8(*Property->GetNameCPP())); if (FieldDesc) { if (FieldDesc->is_repeated()) { int32 NumElements = Property->ArrayDim; FScriptArrayHelper* ArrayHelper = NULL; if (PropClass == UArrayProperty::StaticClass()) { void* Value = Property->ContainerPtrToValuePtr<uint8>(Parms); UArrayProperty* ArrayProperty = Cast<UArrayProperty>(Property); Property = ArrayProperty->Inner; PropClass = Property->GetClass(); ArrayHelper = new FScriptArrayHelper(ArrayProperty, Value); NumElements = ArrayHelper->Num(); } for (int32 i = 0; i < NumElements; i++) { void* Value = ArrayHelper ? ArrayHelper->GetRawPtr(i) : Property->ContainerPtrToValuePtr<void>(Parms, i); if (PropClass == UIntProperty::StaticClass()) { Refl->AddInt32(NewMessage, FieldDesc, *(int32*)Value); } else if (PropClass == UFloatProperty::StaticClass()) { Refl->AddFloat(NewMessage, FieldDesc, *(float*)Value); } else if (PropClass == UBoolProperty::StaticClass() && CastChecked<UBoolProperty>(Property)->IsNativeBool()) { Refl->AddBool(NewMessage, FieldDesc, *(bool*)Value); } else if (PropClass == UByteProperty::StaticClass() && CastChecked<UByteProperty>(Property)->Enum == NULL) { // All bytes are stored in a single string google::protobuf::string Bytes((ANSICHAR*)Value, NumElements); Refl->AddString(NewMessage, FieldDesc, Bytes); break; } else if (PropClass == UStrProperty::StaticClass()) { Refl->AddString(NewMessage, FieldDesc, TCHAR_TO_UTF8(**(FString*)Value)); } else if (PropClass == UStructProperty::StaticClass()) { UStructProperty* StructProperty = Cast<UStructProperty>(Property); google::protobuf::Message* SubMessage = Refl->AddMessage(NewMessage, FieldDesc, NULL); SerializeRPCParams(SubMessage, StructProperty->Struct, Value, CPF_AllFlags); } else { bSuccess = false; UE_LOG_ONLINE(Error, TEXT("SerializeRPCParams - Unhandled property type '%s': %s"), *PropClass->GetName(), *Property->GetPathName()); } } if (ArrayHelper) { delete ArrayHelper; } } else { if (Property->ArrayDim == 1) { void* Value = Property->ContainerPtrToValuePtr<uint8>(Parms); if (PropClass == UIntProperty::StaticClass()) { Refl->SetInt32(NewMessage, FieldDesc, *(int32*)Value); } else if (PropClass == UFloatProperty::StaticClass()) { Refl->SetFloat(NewMessage, FieldDesc, *(float*)Value); } else if (PropClass == UBoolProperty::StaticClass() && CastChecked<UBoolProperty>(Property)->IsNativeBool()) { Refl->SetBool(NewMessage, FieldDesc, *(bool*)Value); } else if (PropClass == UByteProperty::StaticClass() && CastChecked<UByteProperty>(Property)->Enum == NULL) { google::protobuf::string Bytes((ANSICHAR*)Value, 1); Refl->SetString(NewMessage, FieldDesc, Bytes); } else if (PropClass == UStrProperty::StaticClass()) { Refl->SetString(NewMessage, FieldDesc, TCHAR_TO_UTF8(**(FString*)Value)); } else if (PropClass == UStructProperty::StaticClass()) { UStructProperty* StructProperty = Cast<UStructProperty>(Property); google::protobuf::Message* SubMessage = Refl->MutableMessage(NewMessage, FieldDesc, NULL); SerializeRPCParams(SubMessage, StructProperty->Struct, Value, CPF_AllFlags); } else { bSuccess = false; UE_LOG_ONLINE(Error, TEXT("SerializeRPCParams - Unhandled property type '%s': %s"), *PropClass->GetName(), *Property->GetPathName()); } } else { bSuccess = false; UE_LOG_ONLINE(Error, TEXT("SerializeRPCParams - Property reflection mismatch type '%s': %s"), *PropClass->GetName(), *Property->GetPathName()); } } } else { bSuccess = false; UE_LOG_ONLINE(Error, TEXT("SerializeRPCParams - Property reflection missing type '%s': %s"), *PropClass->GetName(), *Property->GetPathName()); } } return bSuccess; }
/** * Creates a message definition for a group of properties * @param MsgProtoDesc descriptor to fill with the definition * @param FieldIt grouping of properties to define * @param PropertyFlags flags properties must have to be considered for the message * * @return TRUE on successful creation, FALSE otherwise */ bool CreateProtoDeclaration(google::protobuf::DescriptorProto* MsgProtoDesc, UStruct* Object, uint64 PropertyFlags) { bool bSuccess = true; int32 FieldIdx = 1; TFieldIterator<UProperty> FieldIt(Object); for(; FieldIt && (FieldIt->PropertyFlags & PropertyFlags); ++FieldIt) { UProperty* Property = *FieldIt; UClass* PropClass = Property->GetClass(); if (PropClass != UInterfaceProperty::StaticClass() && PropClass != UObjectProperty::StaticClass()) { bool bIsRepeated = false; UArrayProperty* ArrayProperty = Cast<UArrayProperty>(Property); if (ArrayProperty != NULL) { UClass* InnerPropClass = ArrayProperty->Inner->GetClass(); if (InnerPropClass != UInterfaceProperty::StaticClass() && InnerPropClass != UObjectProperty::StaticClass()) { Property = ArrayProperty->Inner; bIsRepeated = true; } else { UE_LOG_ONLINE(Error, TEXT("CreateProtoDeclaration - Unhandled property type '%s': %s"), *PropClass->GetName(), *Property->GetPathName()); bSuccess = false; break; } } else if(Property->ArrayDim != 1) { bIsRepeated = true; } FString SubMsgName; UStructProperty* StructProperty = Cast<UStructProperty>(Property); if (StructProperty != NULL) { FString TypeText, ExtendedTypeText; TypeText = Property->GetCPPType(&ExtendedTypeText, CPPF_None); google::protobuf::DescriptorProto* StructProtDesc = MsgProtoDesc->add_nested_type(); SubMsgName = FString::Printf(TEXT("%s%sMessage"), *TypeText, *ExtendedTypeText); StructProtDesc->set_name(TCHAR_TO_UTF8(*SubMsgName)); if (!CreateProtoDeclaration(StructProtDesc, StructProperty->Struct, CPF_AllFlags)) { StructProtDesc->Clear(); bSuccess = false; break; } } int32 Type = GetTypeFromProperty(Property); if (google::protobuf::FieldDescriptorProto_Type_IsValid(Type)) { google::protobuf::FieldDescriptorProto* MsgFieldProto = MsgProtoDesc->add_field(); MsgFieldProto->set_name(TCHAR_TO_UTF8(*Property->GetNameCPP())); MsgFieldProto->set_number(FieldIdx); MsgFieldProto->set_type((google::protobuf::FieldDescriptorProto_Type)Type); if (SubMsgName.Len() > 0) { MsgFieldProto->set_type_name(TCHAR_TO_UTF8(*SubMsgName)); } if (bIsRepeated) { MsgFieldProto->set_label(google::protobuf::FieldDescriptorProto_Label_LABEL_REPEATED); } else { MsgFieldProto->set_label(google::protobuf::FieldDescriptorProto_Label_LABEL_OPTIONAL); } FieldIdx++; } else { UE_LOG_ONLINE(Error, TEXT("CreateProtoDeclaration - Unhandled property mapping '%s': %s"), *PropClass->GetName(), *Property->GetPathName()); bSuccess = false; break; } } else { UE_LOG_ONLINE(Error, TEXT("CreateProtoDeclaration - Unhandled property type '%s': %s"), *PropClass->GetName(), *Property->GetPathName()); bSuccess = false; break; } } return bSuccess; }