Editor/GameLiftSynchronizationContext.cs (60 lines of code) (raw):

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 #nullable enable using System; using UnityEngine; using System.Threading; using AmazonGameLift.Editor; /** * Wrapper of 'System.Threading.SynchronizationContext' that provides additional functionality such as * debugging support. */ public class GameLiftSynchronizationContext { /** * Underlying context to access methods that have no other utility */ public SynchronizationContext Context { get; private set; } internal GameLiftSynchronizationContext(SynchronizationContext context) { Context = context; } /** * Starts a synchronous request to send a message. * Logs exceptions that occur to the Unity console and optionally trigger a callback. * For example, the callback can be used to display the exception in the UI. */ public void Send(SendOrPostCallback d, object? state, Action<Exception>? onException = null) { Context.Send(WrapWithExceptionHandling(d, onException), state); } /** * Starts an asynchronous request to post a message. * Logs exceptions that occur to the Unity console and optionally trigger a callback. */ public void Post(SendOrPostCallback d, object? state, Action<Exception>? onException = null) { Context.Post(WrapWithExceptionHandling(d, onException), state); } /** * Starts an asynchronous request to log a message to the Unity console. */ public void Log(string errorMessage) { Post(_ => UnityEngine.Debug.Log(errorMessage), null); } /** * Starts an asynchronous request to log an error to the Unity console. */ public void LogError(string errorMessage) { Post(_ => UnityEngine.Debug.LogError(errorMessage), null); } /** * Starts an asynchronous request to log an exception to the Unity console. */ public void LogException(Exception exception) { Post(_ => UnityEngine.Debug.LogException(exception), null); } /** * Wraps a SendOrPostCallback with an exception handler. * Exceptions are logged to the Unity console and optionally trigger a callback. */ private SendOrPostCallback WrapWithExceptionHandling(SendOrPostCallback callback, Action<Exception>? onException = null) { return state => { try { callback.Invoke(state); } catch (Exception e) { UnityEngine.Debug.LogError($"Unexpected exception in async context: {e}"); SafelyInvoke(onException, e, "failure callback"); } }; } /** * Attempts to invoke provided callback. If the callback is null, this is a no-op. * If the callback fails, will log the exception to the Unity console. */ private void SafelyInvoke(Action<Exception>? callback, Exception exception, string operation = "callback") { try { callback?.Invoke(exception); } catch (Exception e) { UnityEngine.Debug.LogError($"Unexpected exception in async context invoking {operation}: {e}"); } } /** * Gets the synchronization context for the current thread. */ public static GameLiftSynchronizationContext Current => new GameLiftSynchronizationContext(System.Threading.SynchronizationContext.Current); }