/** * 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); } } }
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; }
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(); } } }
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); } } }
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; }