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();
}
}