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();
}
Beispiel #2
0
	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);
		}
	}
Beispiel #3
0
	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?
	}
}