/**
 * Finds a child property node from the provided parent node (does not recurse into grandchildren)
 *
 * @param InParentNode	The parent node to locate the child from
 * @param PropertyName	The property name to find
 * @param Index			The index of the property if its in an array
 */
static TSharedPtr<FPropertyNode> FindChildPropertyNode( FPropertyNode& InParentNode, const FString& PropertyName, int32 Index )
{
	TSharedPtr<FPropertyNode> FoundNode(NULL);

	// search each child for a property with the provided name
	for( int32 ChildIndex = 0; ChildIndex < InParentNode.GetNumChildNodes(); ++ChildIndex )
	{
		TSharedPtr<FPropertyNode>& ChildNode = InParentNode.GetChildNode(ChildIndex);
		UProperty* Property = ChildNode->GetProperty();
		if( Property && Property->GetFName() == *PropertyName )
		{
			FoundNode = ChildNode;
			break;
		}
	}

	// Find the array element.
	if( FoundNode.IsValid() && Index != INDEX_NONE )
	{
		// The found node is the top array so get its child which is the actual node
		FoundNode = FoundNode->GetChildNode( Index );
	}

	return FoundNode;
}
bool FDetailWidgetExtensionHandler::IsPropertyExtendable(const UClass* InObjectClass, const IPropertyHandle& InPropertyHandle) const
{
	// TODO UMG make this work for multiple widgets.
	if ( InPropertyHandle.GetNumOuterObjects() == 1 )
	{
		TArray<UObject*> Objects;
		InPropertyHandle.GetOuterObjects(Objects);

		// We don't allow bindings on the CDO.
		if ( Objects[0]->HasAnyFlags(RF_ClassDefaultObject) )
		{
			return false;
		}

		UProperty* Property = InPropertyHandle.GetProperty();
		FString DelegateName = Property->GetName() + "Delegate";

		if ( UClass* ContainerClass = Cast<UClass>(Property->GetOuter()) )
		{
			UDelegateProperty* DelegateProperty = FindField<UDelegateProperty>(ContainerClass, FName(*DelegateName));
			if ( DelegateProperty )
			{
				return true;
			}
		}
	}

	return false;
}
void UUserDefinedStructEditorData::RecreateDefaultInstance(FString* OutLog)
{
	UStruct* ScriptStruct = GetOwnerStruct();
	DefaultStructInstance.Recreate(ScriptStruct);
	uint8* StructData = DefaultStructInstance.GetStructMemory();
	ensure(DefaultStructInstance.IsValid() && DefaultStructInstance.GetStruct() == ScriptStruct);
	if (DefaultStructInstance.IsValid() && StructData && ScriptStruct)
	{
		DefaultStructInstance.SetPackage(ScriptStruct->GetOutermost());

		for (TFieldIterator<UProperty> It(ScriptStruct); It; ++It)
		{
			UProperty* Property = *It;
			if (Property)
			{
				auto VarDesc = VariablesDescriptions.FindByPredicate(FStructureEditorUtils::FFindByNameHelper<FStructVariableDescription>(Property->GetFName()));
				if (VarDesc && !VarDesc->CurrentDefaultValue.IsEmpty())
				{
					if (!FBlueprintEditorUtils::PropertyValueFromString(Property, VarDesc->CurrentDefaultValue, StructData))
					{
						const FString Message = FString::Printf(TEXT("Cannot parse value. Property: %s String: \"%s\" ")
							, (Property ? *Property->GetDisplayNameText().ToString() : TEXT("None"))
							, *VarDesc->CurrentDefaultValue);
						UE_LOG(LogClass, Warning, TEXT("UUserDefinedStructEditorData::RecreateDefaultInstance %s Struct: %s "), *Message, *GetPathNameSafe(ScriptStruct));
						if (OutLog)
						{
							OutLog->Append(Message);
						}
					}
				}
			}
		}
	}
}
void UCanvasPanelSlot::PostEditChangeChainProperty(struct FPropertyChangedChainEvent& PropertyChangedEvent)
{
	SynchronizeProperties();

	static FName AnchorsProperty(TEXT("Anchors"));

	FEditPropertyChain::TDoubleLinkedListNode* AnchorNode = PropertyChangedEvent.PropertyChain.GetHead()->GetNextNode();
	if ( !AnchorNode )
	{
		return;
	}

	FEditPropertyChain::TDoubleLinkedListNode* LayoutDataNode = AnchorNode->GetNextNode();

	if ( !LayoutDataNode )
	{
		return;
	}

	UProperty* AnchorProperty = LayoutDataNode->GetValue();

	if ( AnchorProperty && AnchorProperty->GetFName() == AnchorsProperty )
	{
		RebaseLayout();
	}

	Super::PostEditChangeProperty(PropertyChangedEvent);
}
/** Finds a property by name, starting in the specified scope; Validates property type and returns NULL along with emitting an error if there is a mismatch. */
UProperty* FKismetCompilerUtilities::FindPropertyInScope(UStruct* Scope, UEdGraphPin* Pin, FCompilerResultsLog& MessageLog, const UEdGraphSchema_K2* Schema, UClass* SelfClass)
{
	while (Scope != NULL)
	{
		for (TFieldIterator<UProperty> It(Scope, EFieldIteratorFlags::IncludeSuper); It; ++It)
		{
			UProperty* Property = *It;

			if (Property->GetName() == Pin->PinName)
			{
				if (FKismetCompilerUtilities::IsTypeCompatibleWithProperty(Pin, Property, MessageLog, Schema, SelfClass))
				{
					return Property;
				}
				else
				{
					// Exit now, we found one with the right name but the type mismatched (and there was a type mismatch error)
					return NULL;
				}
			}
		}

		// Functions don't automatically check their class when using a field iterator
		UFunction* Function = Cast<UFunction>(Scope);
		Scope = (Function != NULL) ? Cast<UStruct>(Function->GetOuter()) : NULL;
	}

	// Couldn't find the name
	MessageLog.Error(*LOCTEXT("PropertyNotFound_Error", "The property associated with @@ could not be found").ToString(), Pin);
	return NULL;
}
void FNodeHandlingFunctor::ResolveAndRegisterScopedTerm(FKismetFunctionContext& Context, UEdGraphPin* Net, TIndirectArray<FBPTerminal>& NetArray)
{
	// Determine the scope this takes place in
	UStruct* SearchScope = Context.Function;

	UEdGraphPin* SelfPin = CompilerContext.GetSchema()->FindSelfPin(*(Net->GetOwningNode()), EGPD_Input);
	if (SelfPin != NULL)
	{
		SearchScope = Context.GetScopeFromPinType(SelfPin->PinType, Context.NewClass);
	}

	// Find the variable in the search scope
	UProperty* BoundProperty = FKismetCompilerUtilities::FindPropertyInScope(SearchScope, Net, CompilerContext.MessageLog, CompilerContext.GetSchema(), Context.NewClass);
	if (BoundProperty != NULL)
	{
		// Create the term in the list
		FBPTerminal* Term = new (NetArray) FBPTerminal();
		Term->CopyFromPin(Net, Net->PinName);
		Term->AssociatedVarProperty = BoundProperty;
		Context.NetMap.Add(Net, Term);

		// Read-only variables and variables in const classes are both const
		if (BoundProperty->HasAnyPropertyFlags(CPF_BlueprintReadOnly) || Context.IsConstFunction())
		{
			Term->bIsConst = true;
		}

		// Resolve the context term
		if (SelfPin != NULL)
		{
			FBPTerminal** pContextTerm = Context.NetMap.Find(FEdGraphUtilities::GetNetFromPin(SelfPin));
			Term->Context = (pContextTerm != NULL) ? *pContextTerm : NULL;
		}
	}
}
void UGatherTextFromMetaDataCommandlet::GatherTextFromUObjects(const TArray<FString>& IncludePaths, const TArray<FString>& ExcludePaths, const FGatherParameters& Arguments)
{
	const FFuzzyPathMatcher FuzzyPathMatcher = FFuzzyPathMatcher(IncludePaths, ExcludePaths);

	for(TObjectIterator<UField> It; It; ++It)
	{
		// Skip editor-only properties if we're not gathering for editor-only data.
		UProperty* Property = Cast<UProperty>(*It);
		if (Property && !ShouldGatherFromEditorOnlyData && Property->HasAnyPropertyFlags(CPF_EditorOnly))
		{
			continue;
		}

		FString SourceFilePath;
		FSourceCodeNavigation::FindClassHeaderPath(*It, SourceFilePath);
		SourceFilePath = FPaths::ConvertRelativePathToFull(SourceFilePath);

		check(!SourceFilePath.IsEmpty());

		const FFuzzyPathMatcher::EPathMatch PathMatch = FuzzyPathMatcher.TestPath(SourceFilePath);
		if (PathMatch != FFuzzyPathMatcher::Included)
		{
			continue;
		}

		GatherTextFromUObject(*It, Arguments);
	}
}
bool FStructureEditorUtils::Change3dWidgetEnabled(UUserDefinedStruct* Struct, FGuid VarGuid, bool bIsEnabled)
{
	FStructVariableDescription* VarDesc = GetVarDescByGuid(Struct, VarGuid);
	if (!VarDesc)
	{
		return false;
	}

	const UStruct* PropertyStruct = Cast<const UStruct>(VarDesc->SubCategoryObject.Get());
	if (FEdMode::CanCreateWidgetForStructure(PropertyStruct) && (VarDesc->bEnable3dWidget != bIsEnabled))
	{
		const FScopedTransaction Transaction(LOCTEXT("Change3dWidgetEnabled", "Change 3d Widget Enabled"));
		ModifyStructData(Struct);

		VarDesc->bEnable3dWidget = bIsEnabled;
		UProperty* Property = FindField<UProperty>(Struct, VarDesc->VarName);
		if (Property)
		{
			if (VarDesc->bEnable3dWidget)
			{
				Property->SetMetaData(FEdMode::MD_MakeEditWidget, TEXT("true"));
			}
			else
			{
				Property->RemoveMetaData(FEdMode::MD_MakeEditWidget);
			}
		}
		return true;
	}
	return false;
}
static UProperty *get_field_from_name(UScriptStruct *u_struct, char *name)
{
	FString attr = UTF8_TO_TCHAR(name);
	UProperty *u_property = u_struct->FindPropertyByName(FName(*attr));
	if (u_property)
		return u_property;

#if WITH_EDITOR
	static const FName DisplayNameKey(TEXT("DisplayName"));

	// if the property is not found, attempt to search for DisplayName
	for (TFieldIterator<UProperty> prop(u_struct); prop; ++prop)
	{
		UProperty *property = *prop;
		if (property->HasMetaData(DisplayNameKey))
		{
			FString display_name = property->GetMetaData(DisplayNameKey);
			if (display_name.Len() > 0 && attr.Equals(display_name))
			{
				return property;
			}
		}
	}
#endif

	return nullptr;
}
void GetKeyablePropertyPaths(UClass* Class, UStruct* PropertySource, TArray<UProperty*>& PropertyPath, FSequencer& Sequencer, TArray<TArray<UProperty*>>& KeyablePropertyPaths)
{
	//@todo need to resolve this between UMG and the level editor sequencer
	const bool bRecurseAllProperties = Sequencer.IsLevelEditorSequencer();

	for (TFieldIterator<UProperty> PropertyIterator(PropertySource); PropertyIterator; ++PropertyIterator)
	{
		UProperty* Property = *PropertyIterator;

		if (Property && !Property->HasAnyPropertyFlags(CPF_Deprecated))
		{
			PropertyPath.Add(Property);

			bool bIsPropertyKeyable = Sequencer.CanKeyProperty(FCanKeyPropertyParams(Class, PropertyPath));
			if (bIsPropertyKeyable)
			{
				KeyablePropertyPaths.Add(PropertyPath);
			}

			if (!bIsPropertyKeyable || bRecurseAllProperties)
			{
				UStructProperty* StructProperty = Cast<UStructProperty>(Property);
				if (StructProperty != nullptr)
				{
					GetKeyablePropertyPaths(Class, StructProperty->Struct, PropertyPath, Sequencer, KeyablePropertyPaths);
				}
			}

			PropertyPath.RemoveAt(PropertyPath.Num() - 1);
		}
	}
}
void UNavAreaMeta_SwitchByAgent::UpdateAgentConfig()
{
	Super::UpdateAgentConfig();

	const UNavigationSystem* DefNavSys = (UNavigationSystem*)(UNavigationSystem::StaticClass()->GetDefaultObject());
	check(DefNavSys);

	const int32 MaxAllowedAgents = 16;
	const int32 NumAgents = FMath::Min(DefNavSys->GetSupportedAgents().Num(), MaxAllowedAgents);
	if (DefNavSys->GetSupportedAgents().Num() > MaxAllowedAgents)
	{
		UE_LOG(LogNavigation, Error, TEXT("Navigation system supports %d agents, but only %d can be shown in %s properties!"),
			DefNavSys->GetSupportedAgents().Num(), MaxAllowedAgents, *GetClass()->GetName());
	}

	const FString CustomNameMeta = TEXT("DisplayName");
	for (int32 i = 0; i < MaxAllowedAgents; i++)
	{
		const FString PropName = FString::Printf(TEXT("Agent%dArea"), i);
		UProperty* Prop = FindField<UProperty>(UNavAreaMeta_SwitchByAgent::StaticClass(), *PropName);
		check(Prop);

		if (i < NumAgents && NumAgents > 1)
		{
			Prop->SetPropertyFlags(CPF_Edit);
			Prop->SetMetaData(*CustomNameMeta, *FString::Printf(TEXT("Area Class for: %s"), *DefNavSys->GetSupportedAgents()[i].Name.ToString()));
		}
		else
		{
			Prop->ClearPropertyFlags(CPF_Edit);
		}
	}
}
	/**
	 * Scans for changes to the value
	 *
	 * @param bRecacheNewValues	If true, recaches new values found
	 * @return true if any changes were found
	 */
	bool ScanForChanges( bool bRecacheNewValues )
	{
		FPropertyNode& PropertyNodeRef = *PropertyNode.Pin();
		UProperty* Property = PropertyNodeRef.GetProperty();

		bool bPropertyValid = true;
		bool bChanged = false;

		UArrayProperty* OuterArrayProperty = Cast<UArrayProperty>( Property->GetOuter() );
		if ( OuterArrayProperty != NULL )
		{
			// make sure we're not trying to compare against an element that doesn't exist
			if ( PropertyNodeRef.GetArrayIndex() >= FScriptArrayHelper::Num( PropertyValueBaseAddress ) )
			{
				bPropertyValid = false;
			}
		}

		if( bPropertyValid )
		{
			bChanged = !Property->Identical( PropertyValueAddress, Data.GetData() );
			if( bRecacheNewValues )
			{
				CacheValue();
			}
		}

		return bChanged;
	}
void UDeveloperSettings::ImportConsoleVariableValues()
{
	for (UProperty* Property = GetClass()->PropertyLink; Property; Property = Property->PropertyLinkNext)
	{
		if (!Property->HasAnyPropertyFlags(CPF_Config))
		{
			continue;
		}

		FString CVarName = Property->GetMetaData(DeveloperSettingsConsoleVariableMetaFName);
		if (!CVarName.IsEmpty())
		{
			IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(*CVarName);
			if (CVar)
			{
				if (Property->ImportText(*CVar->GetString(), Property->ContainerPtrToValuePtr<uint8>(this, 0), PPF_ConsoleVariable, this) == NULL)
				{
					UE_LOG(LogTemp, Error, TEXT("%s import failed for %s on console variable %s (=%s)"), *GetClass()->GetName(), *Property->GetName(), *CVarName, *CVar->GetString());
				}
			}
			else
			{
				UE_LOG(LogTemp, Fatal, TEXT("%s failed to find console variable %s for %s"), *GetClass()->GetName(), *CVarName, *Property->GetName());
			}
		}
	}
}
	void CollectBlackboardSelectors(const UObject* Ob, const UClass* StopAtClass, TArray<FName>& KeyNames)
	{
		for (UProperty* TestProperty = Ob->GetClass()->PropertyLink; TestProperty; TestProperty = TestProperty->PropertyLinkNext)
		{
			// stop when reaching base class
			if (TestProperty->GetOuter() == StopAtClass)
			{
				break;
			}

			// skip properties without any setup data	
			if (TestProperty->HasAnyPropertyFlags(CPF_Transient) ||
				TestProperty->HasAnyPropertyFlags(CPF_DisableEditOnInstance))
			{
				continue;
			}

			const UStructProperty* StructProp = Cast<const UStructProperty>(TestProperty);
			if (StructProp && StructProp->GetCPPType(NULL, CPPF_None).Contains(GET_STRUCT_NAME_CHECKED(FBlackboardKeySelector)))
			{
				const FBlackboardKeySelector* PropData = TestProperty->ContainerPtrToValuePtr<FBlackboardKeySelector>(Ob);
				KeyNames.AddUnique(PropData->SelectedKeyName);
			}
		}
	}
Example #15
0
bool UK2Node::CreatePinsForFunctionEntryExit(const UFunction* Function, bool bForFunctionEntry)
{
	const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();

	// Create the inputs and outputs
	bool bAllPinsGood = true;
	for (TFieldIterator<UProperty> PropIt(Function); PropIt && (PropIt->PropertyFlags & CPF_Parm); ++PropIt)
	{
		UProperty* Param = *PropIt;

		const bool bIsFunctionInput = !Param->HasAnyPropertyFlags(CPF_OutParm) || Param->HasAnyPropertyFlags(CPF_ReferenceParm);

		if (bIsFunctionInput == bForFunctionEntry)
		{
			const EEdGraphPinDirection Direction = bForFunctionEntry ? EGPD_Output : EGPD_Input;

			UEdGraphPin* Pin = CreatePin(Direction, TEXT(""), TEXT(""), NULL, false, false, Param->GetName());
			const bool bPinGood = K2Schema->ConvertPropertyToPinType(Param, /*out*/ Pin->PinType);
			K2Schema->SetPinDefaultValueBasedOnType(Pin);
			
			UK2Node_CallFunction::GeneratePinTooltipFromFunction(*Pin, Function);

			bAllPinsGood = bAllPinsGood && bPinGood;
		}
	}

	return bAllPinsGood;
}
uint8* UAnimSequenceBase::FindNotifyPropertyData(int32 NotifyIndex, UArrayProperty*& ArrayProperty)
{
	// initialize to NULL
	ArrayProperty = NULL;

	if(Notifies.IsValidIndex(NotifyIndex))
	{
		// find Notifies property start point
		UProperty* Property = FindField<UProperty>(GetClass(), TEXT("Notifies"));

		// found it and if it is array
		if(Property && Property->IsA(UArrayProperty::StaticClass()))
		{
			// find Property Value from UObject we got
			uint8* PropertyValue = Property->ContainerPtrToValuePtr<uint8>(this);

			// it is array, so now get ArrayHelper and find the raw ptr of the data
			ArrayProperty = CastChecked<UArrayProperty>(Property);
			FScriptArrayHelper ArrayHelper(ArrayProperty, PropertyValue);

			if(ArrayProperty->Inner && NotifyIndex < ArrayHelper.Num())
			{
				//Get property data based on selected index
				return ArrayHelper.GetRawPtr(NotifyIndex);
			}
		}
	}
	return NULL;
}
Example #17
0
void USoundWave::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);

	static FName CompressionQualityFName = FName( TEXT( "CompressionQuality" ) );
	static FName StreamingFName = GET_MEMBER_NAME_CHECKED(USoundWave, bStreaming);

	// Prevent constant re-compression of SoundWave while properties are being changed interactively
	if (PropertyChangedEvent.ChangeType != EPropertyChangeType::Interactive)
	{
		UProperty* PropertyThatChanged = PropertyChangedEvent.Property;
		// Regenerate on save any compressed sound formats
		if ( PropertyThatChanged && PropertyThatChanged->GetFName() == CompressionQualityFName )
		{
			InvalidateCompressedData();
			FreeResources();
			UpdatePlatformData();
			MarkPackageDirty();
		}
		else if (PropertyThatChanged && PropertyThatChanged->GetFName() == StreamingFName)
		{
			FreeResources();
			UpdatePlatformData();
			MarkPackageDirty();
		}
	}
}
Example #18
0
FPropertyEditor::FPropertyEditor( const TSharedRef<FPropertyNode>& InPropertyNode, const TSharedRef<IPropertyUtilities>& InPropertyUtilities )
	: PropertyEditConditions()
	, PropertyHandle( NULL )
	, PropertyNode( InPropertyNode )
	, PropertyUtilities( InPropertyUtilities )
	, EditConditionProperty( NULL )
{
	// FPropertyEditor isn't built to handle CategoryNodes
	check( InPropertyNode->AsCategoryNode() == NULL );

	UProperty* Property = InPropertyNode->GetProperty();

	if( Property )
	{
		//see if the property supports some kind of edit condition and this isn't the "parent" property of a static array
		const bool bStaticArray = Property->ArrayDim > 1 && InPropertyNode->GetArrayIndex() == INDEX_NONE;

		if ( Property->HasMetaData( TEXT( "EditCondition" ) ) && !bStaticArray ) 
		{
			if ( !GetEditConditionPropertyAddress( /*OUT*/EditConditionProperty, *InPropertyNode, PropertyEditConditions ) )
			{
				EditConditionProperty = NULL;
			}
		}
	}

	PropertyHandle = PropertyEditorHelpers::GetPropertyHandle( InPropertyNode, PropertyUtilities->GetNotifyHook(), PropertyUtilities );
	check( PropertyHandle.IsValid() && PropertyHandle->IsValidHandle() );
}
void FOnlineAsyncMsgSteam::Destroy()
{
	if (ResponseBuffer)
	{
		UFunction* Function = (*ResponseMessage)->OwnerFunc.Get();
		if (Function)
		{
			// Destroy the parameters.
			// warning: highly dependent on UObject::ProcessEvent freeing of parms!
			for(UProperty* Destruct = Function->DestructorLink; Destruct; Destruct = Destruct->DestructorLinkNext)
			{
				if(Destruct->IsInContainer(Function->ParmsSize))
				{
					Destruct->DestroyValue_InContainer(ResponseBuffer);
				}
			}
		}
        else
        {
            UE_LOG_ONLINE(Warning, TEXT("MsgDestroy: UFunction missing, unable to free buffer.")); 
        }

		delete [] ResponseBuffer;
		ResponseBuffer = NULL;
	}

	GProtoPool.ReturnToPool(Message);
	GProtoPool.ReturnToPool(ResponseMessage);
	ActorPtr = NULL;
}
void UParticleModuleTypeDataRibbon::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);

	UProperty* PropertyThatChanged = PropertyChangedEvent.Property;
	if (PropertyThatChanged && PropertyThatChanged->GetName() == TEXT("MaxTessellationBetweenParticles"))
	{
		if (MaxTessellationBetweenParticles < 0)
		{
			MaxTessellationBetweenParticles = 0;
		}
	}
	else if (PropertyThatChanged && PropertyThatChanged->GetName() == TEXT("SheetsPerTrail"))
	{
		if (SheetsPerTrail <= 0)
		{
			SheetsPerTrail = 1;
		}
	}
	else if (PropertyThatChanged && PropertyThatChanged->GetName() == TEXT("MaxTrailCount"))
	{
		if (MaxTrailCount <= 0)
		{
			MaxTrailCount = 1;
		}
	}
	else if (PropertyThatChanged && PropertyThatChanged->GetName() == TEXT("MaxParticleInTrailCount"))
	{
		if (MaxParticleInTrailCount < 0)
		{
			MaxParticleInTrailCount = 0;
		}
	}
}
FString FScriptCodeGeneratorBase::GenerateFunctionDispatch(UFunction* Function)
{
	FString Params;
	
	const bool bHasParamsOrReturnValue = (Function->Children != NULL);
	if (bHasParamsOrReturnValue)
	{
		Params += TEXT("\tstruct FDispatchParams\r\n\t{\r\n");

		for (TFieldIterator<UProperty> ParamIt(Function); ParamIt; ++ParamIt)
		{
			UProperty* Param = *ParamIt;
			Params += FString::Printf(TEXT("\t\t%s %s;\r\n"), *GetPropertyTypeCPP(Param, CPPF_ArgumentOrReturnValue), *Param->GetName());
		}
		Params += TEXT("\t} Params;\r\n");
		int32 ParamIndex = 0;
		for (TFieldIterator<UProperty> ParamIt(Function); ParamIt; ++ParamIt, ++ParamIndex)
		{
			UProperty* Param = *ParamIt;
			Params += FString::Printf(TEXT("\tParams.%s = %s;\r\n"), *Param->GetName(), *InitializeFunctionDispatchParam(Function, Param, ParamIndex));
		}
	}
	Params += FString::Printf(TEXT("\tstatic UFunction* Function = Obj->FindFunctionChecked(TEXT(\"%s\"));\r\n"), *Function->GetName());
	if (bHasParamsOrReturnValue)
	{
		Params += TEXT("\tcheck(Function->ParmsSize == sizeof(FDispatchParams));\r\n");
		Params += TEXT("\tObj->ProcessEvent(Function, &Params);\r\n");
	}
	else
	{
		Params += TEXT("\tObj->ProcessEvent(Function, NULL);\r\n");
	}	

	return Params;
}
	static bool AreIdentical(UObject* ObjectA, UObject* ObjectB)
	{
		if (!ObjectA || !ObjectB || (ObjectA->GetClass() != ObjectB->GetClass()))
		{
			return false;
		}

		bool Result = true;
		for (UProperty* Prop = ObjectA->GetClass()->PropertyLink; Prop && Result; Prop = Prop->PropertyLinkNext)
		{
			bool bConsiderProperty = Prop->ShouldDuplicateValue(); //Should the property be compared at all?
			if (bConsiderProperty)
			{
				for (int32 Idx = 0; (Idx < Prop->ArrayDim) && Result; Idx++)
				{
					if (!Prop->Identical_InContainer(ObjectA, ObjectB, Idx, PPF_DeepComparison))
					{
						Result = false;
					}
				}
			}
		}
		if (Result)
		{
			// Allow the component to compare its native/ intrinsic properties.
			Result = ObjectA->AreNativePropertiesIdenticalTo(ObjectB);
		}
		return Result;
	}
void SetCellValue( const TSharedRef< IPropertyTableCell >& Cell, FString Value )
{
	if ( Cell->IsReadOnly() )
	{
		return;
	}

	// We need to sanitize property name strings
	TSharedPtr<FPropertyNode> PropertyNode = Cell->GetNode();
	if (PropertyNode.IsValid())
	{
		UProperty* NodeProperty = PropertyNode->GetProperty();
		if (NodeProperty->IsA(UNameProperty::StaticClass()))
		{
			// Remove any pre-existing return characters
			Value = Value.TrimQuotes().Replace(TEXT("\n"), TEXT(""));
		}
	}

	FString CurrentValue = Cell->GetValueAsString();
	if ( CurrentValue != Value )
	{
		// Set value
		Cell->SetValueFromString( Value );
	}
}
void SPropertyEditorCombo::SendToObjects( const FString& NewValue )
{
	const TSharedRef< FPropertyNode > PropertyNode = PropertyEditor->GetPropertyNode();
	UProperty* Property = PropertyNode->GetProperty();

	FString Value;
	if ( bUsesAlternateDisplayValues && !Property->IsA(UStrProperty::StaticClass()))
	{
		// currently only enum properties can use alternate display values; this 
		// might change, so assert here so that if support is expanded to other 
		// property types without updating this block of code, we'll catch it quickly
		UEnum* Enum = CastChecked<UByteProperty>(Property)->Enum;
		check(Enum != nullptr);

		const int32 Index = FindEnumValueIndex(Enum, NewValue);
		check( Index != INDEX_NONE );

		Value = Enum->GetEnumName(Index);

		FText ToolTipValue = Enum->GetToolTipText(Index);
		FText ToolTipText = Property->GetToolTipText();
		if (!ToolTipValue.IsEmpty())
		{
			ToolTipText = FText::Format(FText::FromString(TEXT("{0}\n\n{1}")), ToolTipText, ToolTipValue);
		}
		SetToolTipText(ToolTipText);
	}
	else
	{
		Value = NewValue;
	}

	const TSharedRef< IPropertyHandle > PropertyHandle = PropertyEditor->GetPropertyHandle();
	PropertyHandle->SetValueFromFormattedString( Value );
}
	void CollectPropertyData(const UObject* Ob, const UClass* StopAtClass, TArray<UProperty*>& PropertyData)
	{
		UE_LOG(LogBehaviorTree, Verbose, TEXT("Looking for runtime properties of class: %s"), *GetNameSafe(Ob->GetClass()));

		PropertyData.Reset();
		for (UProperty* TestProperty = Ob->GetClass()->PropertyLink; TestProperty; TestProperty = TestProperty->PropertyLinkNext)
		{
			// stop when reaching base class
			if (TestProperty->GetOuter() == StopAtClass)
			{
				break;
			}

			// skip properties without any setup data
			if (TestProperty->HasAnyPropertyFlags(CPF_Transient) ||
				TestProperty->HasAnyPropertyFlags(CPF_DisableEditOnInstance) == false)
			{
				continue;
			}

			// serialize only simple types
			if (CanUsePropertyType(TestProperty))
			{
				UE_LOG(LogBehaviorTree, Verbose, TEXT("> name: '%s'"), *GetNameSafe(TestProperty));
				PropertyData.Add(TestProperty);
			}
		}
	}
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;
}
//------------------------------------------------------------------------------
static void BlueprintActionDatabaseImpl::AddClassPropertyActions(UClass const* const Class, FActionList& ActionListOut)
{
	using namespace FBlueprintNodeSpawnerFactory; // for MakeDelegateNodeSpawner()

	bool const bIsComponent  = Class->IsChildOf<UActorComponent>();
	bool const bIsActorClass = Class->IsChildOf<AActor>();
	
	// loop over all the properties in the specified class; exclude-super because 
	// we can always get the super properties by looking up that class separateHavely 
	for (TFieldIterator<UProperty> PropertyIt(Class, EFieldIteratorFlags::ExcludeSuper); PropertyIt; ++PropertyIt)
	{
		UProperty* Property = *PropertyIt;
		if (!IsPropertyBlueprintVisible(Property))
		{
			continue;
		}

 		bool const bIsDelegate = Property->IsA(UMulticastDelegateProperty::StaticClass());
 		if (bIsDelegate)
 		{
			UMulticastDelegateProperty* DelegateProperty = CastChecked<UMulticastDelegateProperty>(Property);
			if (DelegateProperty->HasAnyPropertyFlags(CPF_BlueprintAssignable))
			{
				UBlueprintNodeSpawner* AddSpawner = UBlueprintDelegateNodeSpawner::Create(UK2Node_AddDelegate::StaticClass(), DelegateProperty);
				ActionListOut.Add(AddSpawner);
				
				UBlueprintNodeSpawner* AssignSpawner = MakeAssignDelegateNodeSpawner(DelegateProperty);
				ActionListOut.Add(AssignSpawner);
			}
			
			if (DelegateProperty->HasAnyPropertyFlags(CPF_BlueprintCallable))
			{
				UBlueprintNodeSpawner* CallSpawner = UBlueprintDelegateNodeSpawner::Create(UK2Node_CallDelegate::StaticClass(), DelegateProperty);
				ActionListOut.Add(CallSpawner);
			}
			
			UBlueprintNodeSpawner* RemoveSpawner = UBlueprintDelegateNodeSpawner::Create(UK2Node_RemoveDelegate::StaticClass(), DelegateProperty);
			ActionListOut.Add(RemoveSpawner);
			UBlueprintNodeSpawner* ClearSpawner = UBlueprintDelegateNodeSpawner::Create(UK2Node_ClearDelegate::StaticClass(), DelegateProperty);
			ActionListOut.Add(ClearSpawner);

			if (bIsComponent)
			{
				ActionListOut.Add(MakeComponentBoundEventSpawner(DelegateProperty));
			}
			else if (bIsActorClass)
			{
				ActionListOut.Add(MakeActorBoundEventSpawner(DelegateProperty));
			}
 		}
		else
		{
			UBlueprintVariableNodeSpawner* GetterSpawner = UBlueprintVariableNodeSpawner::Create(UK2Node_VariableGet::StaticClass(), Property);
			ActionListOut.Add(GetterSpawner);
			UBlueprintVariableNodeSpawner* SetterSpawner = UBlueprintVariableNodeSpawner::Create(UK2Node_VariableSet::StaticClass(), Property);
			ActionListOut.Add(SetterSpawner);
		}
	}
}
Example #28
0
void UK2Node_Variable::GetNodeAttributes( TArray<TKeyValuePair<FString, FString>>& OutNodeAttributes ) const
{
	UProperty* VariableProperty = GetPropertyForVariable();
	const FString VariableName = VariableProperty ? VariableProperty->GetName() : TEXT( "InvalidVariable" );
	OutNodeAttributes.Add( TKeyValuePair<FString, FString>( TEXT( "Type" ), TEXT( "Variable" ) ));
	OutNodeAttributes.Add( TKeyValuePair<FString, FString>( TEXT( "Class" ), GetClass()->GetName() ));
	OutNodeAttributes.Add( TKeyValuePair<FString, FString>( TEXT( "Name" ), VariableName ));
}
void FCSharpWrapperGenerator::GenerateFunctionWrapper(const UFunction* Function)
{
	FString formalInteropArgs, actualInteropArgs, formalManagedArgs, actualManagedArgs;
	UProperty* returnValue = GetWrapperArgsAndReturnType(
		Function, formalInteropArgs, actualInteropArgs, formalManagedArgs, actualManagedArgs
	);
	const bool bHasReturnValue = (returnValue != nullptr);
	const bool bReturnsBool = (bHasReturnValue && returnValue->IsA(UBoolProperty::StaticClass()));
	const FString returnValueInteropTypeName = 
		bHasReturnValue ? GetPropertyInteropType(returnValue) : TEXT("void");
	const FString returnValueManagedTypeName =
		bHasReturnValue ? GetPropertyManagedType(returnValue) : TEXT("void");
	const FString delegateTypeName = GetDelegateTypeName(Function->GetName(), bHasReturnValue);
	const FString delegateName = GetDelegateName(Function->GetName());

	GeneratedGlue 
		// declare a managed delegate type matching the type of the native wrapper function
		<< UnmanagedFunctionPointerAttribute
		<< (bReturnsBool ? MarshalReturnedBoolAsUint8Attribute : FString())
		<< FString::Printf(
			TEXT("private delegate %s %s(%s);"),
			*returnValueInteropTypeName, *delegateTypeName, *formalInteropArgs
		)
		// declare a delegate instance that will be bound to the native wrapper function
		<< FString::Printf(
			TEXT("private static %s %s;"),
			*delegateTypeName, *delegateName
		)
		// define a managed method that calls the native wrapper function through the delegate 
		// declared above
		<< FString::Printf(
			TEXT("public %s %s(%s)"),
			*returnValueManagedTypeName, *Function->GetName(), *formalManagedArgs
		)
		<< FCodeFormatter::OpenBrace();

	// call the delegate bound to the native wrapper function
	if (bHasReturnValue)
	{
		GeneratedGlue 
			<< FString::Printf(TEXT("var value = %s(%s);"), *delegateName, *actualInteropArgs)
			<< GetReturnValueHandler(returnValue);
	}
	else
	{
		GeneratedGlue << FString::Printf(TEXT("%s(%s);"), *delegateName, *actualInteropArgs);
	}
		
	GeneratedGlue
		<< FCodeFormatter::CloseBrace()
		<< FCodeFormatter::LineTerminator();

	FExportedFunction funcInfo;
	funcInfo.DelegateName = delegateName;
	funcInfo.DelegateTypeName = delegateTypeName;
	ExportedFunctions.Add(funcInfo);
}
bool FPropertyTableColumn::CanSortBy() const
{
	TWeakObjectPtr< UObject > Object = DataSource->AsUObject();
	UProperty* Property = Cast< UProperty >( Object.Get() );

	TSharedPtr< FPropertyPath > Path = DataSource->AsPropertyPath();
	if ( Property == NULL && Path.IsValid() )
	{
		Property = Path->GetLeafMostProperty().Property.Get();
	}

	if ( Property != NULL )
	{
		return Property->IsA( UByteProperty::StaticClass() )  ||
			Property->IsA( UIntProperty::StaticClass() )   ||
			Property->IsA( UBoolProperty::StaticClass() )  ||
			Property->IsA( UFloatProperty::StaticClass() ) ||
			Property->IsA( UNameProperty::StaticClass() )  ||
			Property->IsA( UStrProperty::StaticClass() )   ||
			( Property->IsA( UObjectProperty::StaticClass() ) && !Property->HasAnyPropertyFlags(CPF_InstancedReference) );
			//Property->IsA( UTextProperty::StaticClass() );
	}

	return false;
}