Asynchronous Loading Assets Documentation - Erroneous Line?

I’ve been reading through the Asynchronous Asset Loading documentation page and at the bottom, as the following line states: “The delegate can be anything you want, so you can pass along payload information if you want.” However, the functions for loading request a FStreamableDelegate and FStreamableDelegate is declared as the following:


/** Defines FStreamableDelegate delegate interface */
DECLARE_DELEGATE( FStreamableDelegate );

From my understanding this means that the only functions that could be accepted by the delegate are functions with the following function signature:


void Function()

If I am incorrect them I would appreciate if someone could elucidate how its possible to pass a payload in this circumstance, otherwise, below is the link to the documentation that is in error:

https://docs.unrealengine.com/latest/INT/Programming/Assets/AsyncLoading/index.html

Here is an example:



DECLARE_DELEGATE_OneParam(FStreamableDelegate, FString);


Then you use it in some class:



class FYourClass
{
    FStreamableDelegate YourDelegate;
};


Then you have some method you want to call using this delegate which takes this type of a parameter you’ve specified (FString in this case) and a bunch of other parameters you want to pass as a payload:



void SomeMethod( FString, bool, int32, FSomeCustomData );


Now, you can bind your delegate:



YourDelegate.BindRaw(&SomeMethod, true, 1, SomeObjectOfTypeFCustomData);


If you’re working with UObjects, then it will look like this. Notice, that you don’t provide your delegate parameter as a payload. It will be passed on execution:



YourDelegate.BindUObject(SomeObject, &USomeClass::SomeMethod, true, 1, SomeObjectOfTypeFCustomData);


And execute with the provided parameters whenever you want. For instance, you have an async method and you pass some data into it and you want to do something with this data after this async call is done. So before you call this async method, you bind some other method to a delegate, provide the data you need and then inside of your async method you can execute this delegate.:



YourDelegate.ExecuteIfBound(FString YourRequiredParameter);


Which will actualy call:



SomeMethod(YourRequiredParameter, true, 1, SomeObjectOfTypeFCustomData);


Hope this helps! :slight_smile: If you have questions, please, ask.

Thank you so much, that was a really great explanation, I just want to make sure I understand a few things.

Firstly, FStreamableDelegate is an engine type, not something that I created, I assume you aren’t suggesting that you can overload a delegate, correct?

Secondly, I’m working with the function FStreamableManager::RequestAsyncLoad, with the function signature of:


void RequestAsyncLoad
(
    const FStringAssetReference & TargetToStream,
    FStreamableDelegate DelegateToCall
)

So I assume that I can pass in a payload by doing the following:


MyStreamableManager.RequestAsyncLoad(AssetReferenceToStream, FStreamableDelegate::CreateUObject(this, &MyClass::SomeFunctionWithParameters, Parameter1, Parameter2));

void MyClass::SomeFunctionWithParameters(SomeType Parameter1, SomeType Parameter2);

Is this correct? Or would I be using the CreateUObject function incorrectly in this case? The delegate doesn’t have any parameters so I would like to be passing a payload to my function through the delegate declaration in this case.

This is the link to the documentation page I’m looking at, at the bottom in the last code example you will see the code that I’m modeling the above function off of:
https://docs.unrealengine.com/latest/INT/Programming/Assets/AsyncLoading/index.html

Again thank you very much for the assistance IanBreeg!

No problems, Cidubic :slight_smile:

I’ve dig into the code of this particular method and in the end, it’s just a regular delegate call:



Existing->RelatedRequests*->CompletionDelegate.ExecuteIfBound()


And the templated CreateUObject() takes as much arguments as you need:



template <typename UserClass, typename... VarTypes>
    inline static TBaseDelegate<RetValType, ParamTypes...> CreateUObject(UserClass* InUserObject, typename TMemFunPtrType<false, UserClass, RetValType (ParamTypes..., VarTypes...)>::Type InFunc, **VarTypes... Vars**)
    {
        return TBaseUObjectMethodDelegateInstance<false, UserClass, TFuncType, VarTypes...>::Create(InUserObject, InFunc, Vars...);
    }


So you should be fine with the way you do things now. Do you get errors or crashes? What is the problem exactly?

Here is a not that relevant example, but it uses the same technique:



FSourceControlOperationComplete::CreateUObject(this, &UUnrealEdEngine::OnPackageCheckedOut, TWeakObjectPtr<UPackage>(Package))


FSourceControlOperationComplete takes two parameters



DECLARE_DELEGATE_TwoParams(FSourceControlOperationComplete, const FSourceControlOperationRef&, ECommandResult::Type);


And the &UUnrealEdEngine::OnPackageCheckedOut has the following signature. So, as you can see, it takes the Package as a payload parameter.



void OnPackageCheckedOut(const FSourceControlOperationRef& SourceControlOp, ECommandResult::Type ResultType, TWeakObjectPtr<UPackage> Package);