void UK2Node_ActorBoundEvent::DestroyNode() { if( EventOwner ) { // If we have an event owner, remove the delegate referencing this event, if any const ULevel* TargetLevel = Cast<ULevel>(EventOwner->GetOuter()); if( TargetLevel ) { ALevelScriptActor* LSA = TargetLevel->GetLevelScriptActor(); if( LSA ) { // Create a delegate of the correct signature to remove FScriptDelegate Delegate; Delegate.BindUFunction(LSA, CustomFunctionName); // Attempt to remove it from the target's MC delegate if (FMulticastScriptDelegate* TargetDelegate = GetTargetDelegate()) { TargetDelegate->Remove(Delegate); } } } } Super::DestroyNode(); }
void Unbind(UJavascriptDelegate* DelegateObject) { static FName NAME_Fire("Fire"); if (WeakObject.IsValid()) { if (auto p = Cast<UMulticastDelegateProperty>(Property)) { FScriptDelegate Delegate; Delegate.BindUFunction(DelegateObject, NAME_Fire); auto Target = p->GetPropertyValuePtr_InContainer(WeakObject.Get()); Target->Remove(Delegate); } else if (auto p = Cast<UDelegateProperty>(Property)) { auto Target = p->GetPropertyValuePtr_InContainer(WeakObject.Get()); Target->Clear(); } } DelegateObject->JavascriptDelegate = nullptr; DelegateObject->RemoveFromRoot(); DelegateObjects.Remove(DelegateObject); if (!bAbandoned) { functions.Remove(DelegateObject->UniqueId); } }
void Bind(UJavascriptDelegate* DelegateObject, Local<Function> function) { static FName NAME_Fire("Fire"); if (WeakObject.IsValid()) { if (auto p = Cast<UMulticastDelegateProperty>(Property)) { FScriptDelegate Delegate; Delegate.BindUFunction(DelegateObject, NAME_Fire); auto Target = p->GetPropertyValuePtr_InContainer(WeakObject.Get()); Target->Add(Delegate); } else if (auto p = Cast<UDelegateProperty>(Property)) { auto Target = p->GetPropertyValuePtr_InContainer(WeakObject.Get()); Target->BindUFunction(DelegateObject, NAME_Fire); } } DelegateObject->JavascriptDelegate = this; DelegateObject->AddToRoot(); DelegateObjects.Add(DelegateObject); functions.Add( DelegateObject->UniqueId, UniquePersistent<Function>(isolate_, function) ); }
void UComponentDelegateBinding::BindDynamicDelegates(AActor* InInstance) const { for(int32 BindIdx=0; BindIdx<ComponentDelegateBindings.Num(); BindIdx++) { const FBlueprintComponentDelegateBinding& Binding = ComponentDelegateBindings[BindIdx]; // Get the function we want to bind UFunction* FunctionToBind = FindField<UFunction>(InInstance->GetClass(), Binding.FunctionNameToBind); // Get the property that points to the component we want to assign to UObjectProperty* ObjProp = FindField<UObjectProperty>(InInstance->GetClass(), Binding.ComponentPropertyName); // If we have both of those.. if(ObjProp != NULL && FunctionToBind != NULL) { // ..see if there is actually a component assigned UActorComponent* Component = Cast<UActorComponent>(ObjProp->GetObjectPropertyValue_InContainer(InInstance)); if(Component != NULL) { // If there is, find the delegate property on it UMulticastDelegateProperty* DelegateProp = FindField<UMulticastDelegateProperty>(Component->GetClass(), Binding.DelegatePropertyName); if(DelegateProp) { // Found that, finally bind function on the actor to this delegate FMulticastScriptDelegate* TargetDelegate = DelegateProp->GetPropertyValuePtr_InContainer(Component); FScriptDelegate Delegate; Delegate.SetFunctionName(Binding.FunctionNameToBind); Delegate.SetObject(InInstance); TargetDelegate->AddUnique(Delegate); } } } } }
void UDelegateProperty::ExportTextItem( FString& ValueStr, const void* PropertyValue, const void* DefaultValue, UObject* Parent, int32 PortFlags, UObject* ExportRootScope ) const { FScriptDelegate* ScriptDelegate = (FScriptDelegate*)PropertyValue; check(ScriptDelegate != NULL); bool bDelegateHasValue = ScriptDelegate->GetFunctionName() != NAME_None; ValueStr += FString::Printf( TEXT("%s.%s"), ScriptDelegate->GetUObject() != NULL ? *ScriptDelegate->GetUObject()->GetName() : TEXT("(null)"), *ScriptDelegate->GetFunctionName().ToString() ); }
bool UDelegateProperty::Identical( const void* A, const void* B, uint32 PortFlags ) const { bool bResult = false; FScriptDelegate* DA = (FScriptDelegate*)A; FScriptDelegate* DB = (FScriptDelegate*)B; if( DB == NULL ) { bResult = DA->GetFunctionName() == NAME_None; } else if ( DA->GetFunctionName() == DB->GetFunctionName() ) { if ( DA->GetUObject() == DB->GetUObject() ) { bResult = true; } else if ((DA->GetUObject() == NULL || DB->GetUObject() == NULL) && (PortFlags&PPF_DeltaComparison) != 0) { bResult = true; } } return bResult; }
void UWidgetBlueprintGeneratedClass::InitializeWidget(UUserWidget* UserWidget) const { #if WITH_EDITORONLY_DATA UWidgetTree* ClonedTree = DuplicateObject<UWidgetTree>(DesignerWidgetTree ? DesignerWidgetTree : WidgetTree, UserWidget); #else UWidgetTree* ClonedTree = DuplicateObject<UWidgetTree>(WidgetTree, UserWidget); #endif #if WITH_EDITOR UserWidget->WidgetGeneratedBy = ClassGeneratedBy; #endif if ( ClonedTree ) { ClonedTree->SetFlags(RF_Transactional); UserWidget->WidgetTree = ClonedTree; UClass* WidgetBlueprintClass = UserWidget->GetClass(); for(UWidgetAnimation* Animation : Animations) { UWidgetAnimation* Anim = DuplicateObject<UWidgetAnimation>( Animation, UserWidget ); if( Anim->MovieScene ) { // Find property with the same name as the template and assign the new widget to it. UObjectPropertyBase* Prop = FindField<UObjectPropertyBase>(WidgetBlueprintClass, Anim->MovieScene->GetFName()); if(Prop) { Prop->SetObjectPropertyValue_InContainer(UserWidget, Anim); } } } ClonedTree->ForEachWidget([&] (UWidget* Widget) { // Not fatal if NULL, but shouldn't happen if ( !ensure(Widget != nullptr) ) { return; } #if WITH_EDITOR Widget->WidgetGeneratedBy = ClassGeneratedBy; #endif // TODO UMG Make this an FName FString VariableName = Widget->GetName(); Widget->bCreatedByConstructionScript = true; // Indicate it comes from a blueprint so it gets cleared when we rerun construction scripts // Find property with the same name as the template and assign the new widget to it. UObjectPropertyBase* Prop = FindField<UObjectPropertyBase>(WidgetBlueprintClass, *VariableName); if ( Prop ) { Prop->SetObjectPropertyValue_InContainer(UserWidget, Widget); UObject* Value = Prop->GetObjectPropertyValue_InContainer(UserWidget); check(Value == Widget); } // Perform binding for ( const FDelegateRuntimeBinding& Binding : Bindings ) { //TODO UMG Make this faster. if ( Binding.ObjectName == VariableName ) { UDelegateProperty* DelegateProperty = FindField<UDelegateProperty>(Widget->GetClass(), FName(*( Binding.PropertyName.ToString() + TEXT("Delegate") ))); if ( !DelegateProperty ) { DelegateProperty = FindField<UDelegateProperty>(Widget->GetClass(), Binding.PropertyName); } if ( DelegateProperty ) { bool bSourcePathBound = false; if ( Binding.SourcePath.IsValid() ) { bSourcePathBound = Widget->AddBinding(DelegateProperty, UserWidget, Binding.SourcePath); } // If no native binder is found then the only possibility is that the binding is for // a delegate that doesn't match the known native binders available and so we // fallback to just attempting to bind to the function directly. if ( bSourcePathBound == false ) { FScriptDelegate* ScriptDelegate = DelegateProperty->GetPropertyValuePtr_InContainer(Widget); if ( ScriptDelegate ) { ScriptDelegate->BindUFunction(UserWidget, Binding.FunctionName); } } } } } // Initialize Navigation Data if (Widget->Navigation) { Widget->Navigation->ResolveExplictRules(ClonedTree); } #if WITH_EDITOR Widget->ConnectEditorData(); #endif }); // Bind any delegates on widgets BindDynamicDelegates(UserWidget); //TODO UMG Add OnWidgetInitialized? } }