In my current project, once a user has attempted to log in, a loading screen overlay pops up while several different operations are called via event in the background. I want to wait until all these background operations have ended before turning off the loading screen, but I don’t know how to do this because I’m running some asynchronous operations like downloading additional user specific data.
What would be the best way to implement this in a scalable way?
Ok this is great for learning in general, but i’m not certain how this would help me.
Maybe I should elaborate on what exactly is going on in my project. When a user successfully logs in, an event handler called UserChanged is invoked. This triggers several other scripts to run their respective methods, some of which involve downloading additional user data. The process of getting this data from the server and then processing it looks like this:
ServerRequestContent content = new ServerRequestContent(identifier, args);
content.ServerResponded += TaskToRun;
PostToServer.StartPostRequest(content);
ServerRequestContent is basically what it sounds, an object to create a server request: identifier is a string that lets the server identify what function it should run and args is a NameValueCollection which is used as additional data.
Inside StartPostRequest, a coroutine is triggered. The coroutine takes identifier and args to build a WWWForm which is sent to the server in UnityWebRequest.Post. Once the request is completed and the data is deserialized, the content.ServerResponded event is triggered. It is only THEN that whatever TaskToRun begins to actually run.
To summarize - When a user logs in, several server requests are triggered. Each server request eventually triggers its own ServerResponded event on completion, which then run some task. I want to know when all of these tasks are eventually completed so I can tell everything has loaded successfully. I don’t mind overhauling the code if that’s what it takes, as I was not the one to create the workflow described above, but the entire project is now mine to handle.
Okay, that was my intention of the link. You can pass a method as a parameter for another method.
Here is an simple example that should run if you copy paste.
public class Server {
private bool processCompleted;
public IEnumerator LoadUserData(System.Action onCompleted) {
while (!processCompleted) {
//do your work
yield return null;
processCompleted = true;
}
onCompleted?.Invoke();
}
}
public class RequestProvider : MonoBehaviour {
private Server server = new Server();
private void OnContentRequested() {
StartCoroutine(server.LoadUserData(OnRequestCompleted));
}
private void OnRequestCompleted() {
//Close your UI or whatelse.
Debug.Log("Request Completed and can close login window.");
}
}
You can pass Action with any object parameters, also.
Action<float> onCompleted
will require a method to be passed with same parameters like private void OnRequestCompleted(float seconds)