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("");
}
示例#5
0
// 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;
}
示例#15
0
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 );
	}
}
示例#18
0
/**
 * 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)
	];
}
示例#20
0
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();
}
示例#21
0
/**
 * 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;
}
示例#23
0
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));
	}
示例#27
0
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;
}
示例#28
0
/**
 * 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;
}
示例#29
0
/**
 * 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;
}
示例#30
0
	/**
	 * 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;
	}