Skip to content

Instantly share code, notes, and snippets.

@FNGgames
Created November 28, 2023 14:17
Show Gist options
  • Save FNGgames/8bfae62793dc860514f61f05ec35a50b to your computer and use it in GitHub Desktop.
Save FNGgames/8bfae62793dc860514f61f05ec35a50b to your computer and use it in GitHub Desktop.
Promises
using UnityEngine;
using RSG;
public class ExamplePromiseWithTimeout : MonoBehaviour
{
private void Start()
{
// The example promise never resolves so this will timeout after 5 seconds has passed
// NOTE: This timer only works if the Promise.Update(deltaTime) method is being called
// (make sure you have the PromiseManager script running somewhere)
ExamplePromise().Timeout(5).Done(OnPromiseResolved, OnPromiseRejected);
}
private IPromise ExamplePromise()
{
// return a promise that will never resolve
return new Promise();
}
private void OnPromiseResolved()
{
// this should never be called
Debug.Log("Promise Resolved");
}
private void OnPromiseRejected(Exception e)
{
// this is the callback for when the promise is timed out
Debug.LogError("Promise Rejected: " + e.Message);
}
}
using RSG;
using UnityEngine;
// Place this script on a game-object in your root scene to update the PromiseTimer
public class PromiseManager : MonoBehaviour
{
private void Awake() => DontDestroyOnLoad(gameObject);
private void Update() => Promises.Update(Time.deltaTime);
}
using RSG;
// This class manages a single instance of PromiseTimer and wraps the main methods of it in a static context.
// It must be updated in the game loop in order to keep track of time.
// It wraps the common methods available to the PromiseTimer class (WaitFor, WaitUntil etc)
// It adds a new extension method that can be called on an IPromise instance that acts as a Timeout,
// If the timeout expires before the original promise is resolved, the promise is rejected with a PromiseTimedOutException.
public static class Promises
{
private static readonly PromiseTimer _timer = new();
public static void Update(float deltaTime) => _timer.Update(deltaTime);
public static IPromise WaitFor(float seconds) => _timer.WaitFor(seconds);
public static IPromise WaitUntil(Func<TimeData, bool> predicate) => _timer.WaitUntil(predicate);
public static IPromise WaitWhile(Func<TimeData, bool> predicate) => _timer.WaitWhile(predicate);
public static IPromise Timeout(this IPromise initialPromise, float timeout)
{
var promise = new Promise();
var resolved = false;
WaitFor(timeout).Then(() =>
{
if (!resolved) promise.Reject(new PromiseTimedOutException(timeout));
});
initialPromise
.Then(() =>
{
resolved = true;
promise.Resolve();
})
.Catch(exception =>
{
resolved = true;
promise.Reject(exception);
});
return promise;
}
}
using System
// An exception to throw when a promise has timed out
public class PromiseTimedOutException : Exception
{
public PromiseTimedOutException(float time) : base($"Promise timed out after {time} seconds")
{ }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment