using System; using System.Threading.Tasks; using Unity.Services.Mediation.Platform; namespace Unity.Services.Mediation { /// /// Class to be instantiated in order to show an Interstitial Ad. /// public sealed class InterstitialAd : IInterstitialAd { /// /// Event to be triggered by the adapter when an Ad is loaded. /// public event EventHandler OnLoaded; /// /// Event to be triggered by the adapter when an Ad fails to load. /// public event EventHandler OnFailedLoad; /// /// Event to be triggered by the adapter when an Ad is started. /// public event EventHandler OnShowed; /// /// Event to be triggered by the adapter when the user clicks on the Ad. /// public event EventHandler OnClicked; /// /// Event to be triggered by the adapter when the Ad is closed. /// public event EventHandler OnClosed; /// /// Event to be triggered by the adapter when the Ad has an error. /// public event EventHandler OnFailedShow; /// /// Get the current state of the ad. /// public AdState AdState => m_InterstitialAdImpl.AdState; /// /// Get the ad unit id set during construction. /// public string AdUnitId => m_InterstitialAdImpl.AdUnitId; IPlatformInterstitialAd m_InterstitialAdImpl; TaskCompletionSource m_LoadCompletionSource; TaskCompletionSource m_ShowCompletionSource; bool m_IsLoading; bool m_IsShowing; /// /// Constructor for managing a specific Interstitial Ad. /// /// Unique Id for the Ad you want to show. public InterstitialAd(string adUnitId) { #if UNITY_EDITOR && (UNITY_ANDROID || UNITY_IOS) m_InterstitialAdImpl = new EditorInterstitialAd(adUnitId); #elif UNITY_ANDROID m_InterstitialAdImpl = new AndroidInterstitialAd(adUnitId); #elif UNITY_IOS m_InterstitialAdImpl = new IosInterstitialAd(adUnitId); #else m_InterstitialAdImpl = new UnsupportedInterstitialAd(adUnitId); #endif InitializeCallbacks(); } internal InterstitialAd(IPlatformInterstitialAd interstitialAdImpl) { m_InterstitialAdImpl = interstitialAdImpl; InitializeCallbacks(); } void InitializeCallbacks() { m_InterstitialAdImpl.OnLoaded += (sender, args) => OnLoaded?.Invoke(this, args); m_InterstitialAdImpl.OnFailedLoad += (sender, args) => OnFailedLoad?.Invoke(this, args); m_InterstitialAdImpl.OnShowed += (sender, args) => OnShowed?.Invoke(this, args); m_InterstitialAdImpl.OnClicked += (sender, args) => OnClicked?.Invoke(this, args); m_InterstitialAdImpl.OnClosed += (sender, args) => OnClosed?.Invoke(this, args); m_InterstitialAdImpl.OnFailedShow += (sender, args) => OnFailedShow?.Invoke(this, args); } /// /// Method to tell the Mediation SDK to load an Ad. /// /// LoadAsync Task /// Thrown when the ad failed to load public Task LoadAsync() { if (!m_IsLoading) { SetupAsyncLoad(); m_InterstitialAdImpl.Load(); } return m_LoadCompletionSource?.Task ?? Task.CompletedTask; } void SetupAsyncLoad() { m_LoadCompletionSource = new TaskCompletionSource(); m_InterstitialAdImpl.OnLoaded += OnLoadCompleted; m_InterstitialAdImpl.OnFailedLoad += OnLoadFailed; m_IsLoading = true; } void OnLoadCompleted(object sender, EventArgs e) { m_LoadCompletionSource.TrySetResult(null); TearDownAsyncLoad(); } void OnLoadFailed(object sender, LoadErrorEventArgs args) { m_LoadCompletionSource.SetException(new LoadFailedException(args.Error, args.Message)); TearDownAsyncLoad(); } void TearDownAsyncLoad() { m_InterstitialAdImpl.OnFailedLoad -= OnLoadFailed; m_InterstitialAdImpl.OnLoaded -= OnLoadCompleted; m_IsLoading = false; } /// /// Method to tell the Mediation SDK to show the loaded Ad. /// /// Optional, allows setting optional parameters for showing an interstitial ad. /// ShowAsync Task /// Thrown when the ad failed to show public Task ShowAsync(InterstitialAdShowOptions showOptions = null) { if (!m_IsShowing) { SetupAsyncShow(); if (showOptions != null && showOptions.AutoReload) { m_InterstitialAdImpl.OnFailedShow += ReloadAd; m_InterstitialAdImpl.OnClosed += ReloadAd; } m_InterstitialAdImpl.Show(); } return m_ShowCompletionSource?.Task ?? Task.CompletedTask; } void SetupAsyncShow() { m_ShowCompletionSource = new TaskCompletionSource(); m_InterstitialAdImpl.OnClosed += OnShowCompleted; m_InterstitialAdImpl.OnFailedShow += OnShowFailed; m_IsShowing = true; } void OnShowCompleted(object sender, EventArgs e) { m_ShowCompletionSource.TrySetResult(null); TearDownAsyncShow(); } void OnShowFailed(object sender, ShowErrorEventArgs args) { m_ShowCompletionSource.TrySetException(new ShowFailedException(args.Error, args.Message)); TearDownAsyncShow(); } void TearDownAsyncShow() { m_InterstitialAdImpl.OnFailedShow -= OnShowFailed; m_InterstitialAdImpl.OnClosed -= OnShowCompleted; m_IsShowing = false; } void ReloadAd(object sender, EventArgs e) { m_InterstitialAdImpl.OnFailedShow -= ReloadAd; m_InterstitialAdImpl.OnClosed -= ReloadAd; try { LoadAsync(); } catch (LoadFailedException) {} } /// /// Dispose and release internal resources. /// public void Dispose() => m_InterstitialAdImpl.Dispose(); } }