using System; using System.Threading.Tasks; using Unity.Services.Core.Internal; using Unity.Services.Core.Scheduler.Internal; using Unity.Services.Mediation.Platform; namespace Unity.Services.Mediation { /// /// Class to be instantiated in order to show a Rewarded Ad. /// public sealed class RewardedAd : IRewardedAd { internal const double k_ReloadDelay = 1.0; /// /// 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 a Rewarded Ad is shown. /// public event EventHandler OnShowed; /// /// Event to be triggered by the adapter when the user clicks on the RewardedAd. /// public event EventHandler OnClicked; /// /// Event to be triggered by the adapter when the RewardedAd is closed. /// public event EventHandler OnClosed; /// /// Event to be triggered by the adapter when the RewardedAd has an error. /// public event EventHandler OnFailedShow; /// /// Event to be triggered by the adapter when a reward needs to be issued. /// public event EventHandler OnUserRewarded; /// ///Gets the state of the RewardedAd. /// public AdState AdState => m_RewardedAdImpl.AdState; /// /// Gets the id of the ad unit. /// public string AdUnitId => m_RewardedAdImpl.AdUnitId; IPlatformRewardedAd m_RewardedAdImpl; TaskCompletionSource m_LoadCompletionSource; TaskCompletionSource m_ShowCompletionSource; bool m_IsLoading; bool m_IsShowing; /// /// Constructor for managing a specific Rewarded Ad. /// /// Unique Id for the Ad you want to show. public RewardedAd(string adUnitId) { #if UNITY_EDITOR && (UNITY_ANDROID || UNITY_IOS) m_RewardedAdImpl = new EditorRewardedAd(adUnitId); #elif UNITY_ANDROID m_RewardedAdImpl = new AndroidRewardedAd(adUnitId); #elif UNITY_IOS m_RewardedAdImpl = new IosRewardedAd(adUnitId); #else m_RewardedAdImpl = new UnsupportedRewardedAd(adUnitId); #endif InitializeCallbacks(); } internal RewardedAd(IPlatformRewardedAd rewardedAdImpl) { m_RewardedAdImpl = rewardedAdImpl; InitializeCallbacks(); } void InitializeCallbacks() { m_RewardedAdImpl.OnLoaded += (sender, args) => OnLoaded?.Invoke(this, args); m_RewardedAdImpl.OnFailedLoad += (sender, args) => OnFailedLoad?.Invoke(this, args); m_RewardedAdImpl.OnShowed += (sender, args) => OnShowed?.Invoke(this, args); m_RewardedAdImpl.OnClicked += (sender, args) => OnClicked?.Invoke(this, args); m_RewardedAdImpl.OnClosed += (sender, args) => OnClosed?.Invoke(this, args); m_RewardedAdImpl.OnFailedShow += (sender, args) => OnFailedShow?.Invoke(this, args); m_RewardedAdImpl.OnUserRewarded += (sender, args) => OnUserRewarded?.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_RewardedAdImpl.Load(); } return m_LoadCompletionSource?.Task ?? Task.CompletedTask; } void SetupAsyncLoad() { m_LoadCompletionSource = new TaskCompletionSource(); m_RewardedAdImpl.OnLoaded += OnLoadCompleted; m_RewardedAdImpl.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_RewardedAdImpl.OnFailedLoad -= OnLoadFailed; m_RewardedAdImpl.OnLoaded -= OnLoadCompleted; m_IsLoading = false; } /// /// Method to tell the Mediation SDK to show the loaded Ad. /// /// Optional, allows setting optional parameters for showing a rewarded ad. /// ShowAsync Task /// Thrown when the ad failed to show public Task ShowAsync(RewardedAdShowOptions showOptions = null) { if (!m_IsShowing) { SetupAsyncShow(); if (showOptions != null && showOptions.AutoReload) { m_RewardedAdImpl.OnFailedShow += ReloadAd; m_RewardedAdImpl.OnClosed += ReloadAd; } m_RewardedAdImpl.Show(showOptions); } return m_ShowCompletionSource?.Task ?? Task.CompletedTask; } void SetupAsyncShow() { m_ShowCompletionSource = new TaskCompletionSource(); m_RewardedAdImpl.OnClosed += OnShowCompleted; m_RewardedAdImpl.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_RewardedAdImpl.OnFailedShow -= OnShowFailed; m_RewardedAdImpl.OnClosed -= OnShowCompleted; m_IsShowing = false; } void ReloadAd(object sender, EventArgs e) { m_RewardedAdImpl.OnFailedShow -= ReloadAd; m_RewardedAdImpl.OnClosed -= ReloadAd; IActionScheduler actionScheduler = CoreRegistry.Instance.GetServiceComponent(); actionScheduler.ScheduleAction(() => { try { LoadAsync(); } catch (LoadFailedException) {} }, k_ReloadDelay); } /// /// Dispose and release internal resources. /// public void Dispose() => m_RewardedAdImpl.Dispose(); } }