Skip to content

Instantly share code, notes, and snippets.

@nrichards
Created January 23, 2018 17:50
Show Gist options
  • Save nrichards/b0be5ffa72fbe2f43b01fd5c9f9225b8 to your computer and use it in GitHub Desktop.
Save nrichards/b0be5ffa72fbe2f43b01fd5c9f9225b8 to your computer and use it in GitHub Desktop.
Unity AdvertisementShowWait
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.Advertisements;
/// <summary>
/// I show an advertisement, waiting until it is ready. Waiting can be stopped.
/// </summary>
public class AdvertisementShowWait : MonoBehaviour
{
public enum DebugLevel
{
None, // No debugging
Info, // When advert is showing
Debug // Waiting and showing detail
}
public static DebugLevel debug = DebugLevel.None;
/// <summary>
/// Show a placement when ready, waiting until Advertisement system loads the placement.
/// </summary>
/// <param name="placementId"></param>
/// <returns>IsReadyWaiter</returns>
public static IsReadyWaiter ShowWhenReady(string placementId)
{
return Impl.Add(() =>
{
if (debug >= DebugLevel.Debug)
{
UnityEngine.Debug.LogFormat("Waiting for placementId {}", placementId);
}
return Advertisement.IsReady(placementId) == false;
}, () =>
{
if (debug >= DebugLevel.Info)
{
UnityEngine.Debug.LogFormat("Showing placementId {}", placementId);
}
Advertisement.Show(placementId);
});
}
/// <summary>
/// Use when the Advertisement is no longer desired. Will not show the pending advert if it is still loading.
/// </summary>
public class IsReadyWaiter
{
/// <summary>
/// Stop waiting for the advertisement
/// </summary>
public void Stop()
{
// Neutralize the async test and action, deallocating upon next update
continueAction = () => { };
completedAction = () => true;
}
internal Func<bool> completedAction { get; private set; }
internal Action continueAction { get; private set; }
internal IsReadyWaiter(Func<bool> completedAction, Action continueAction)
{
this.completedAction = completedAction;
this.continueAction = continueAction;
}
}
private static class Impl
{
private static readonly List<IsReadyWaiter> _jobs = new List<IsReadyWaiter>();
internal static IsReadyWaiter Add(Func<bool> completed, Action continueWith)
{
if (!_jobs.Any())
{
EditorApplication.update += EditorUpdate;
}
var job = new IsReadyWaiter(completed, continueWith);
_jobs.Add(job);
return job;
}
private static void EditorUpdate()
{
for (int i = 0; i >= 0; --i)
{
var it = _jobs[i];
if (it.completedAction())
{
it.continueAction();
_jobs.RemoveAt(i);
}
}
if (!_jobs.Any())
{
EditorApplication.update -= EditorUpdate;
}
}
}
}
using UnityEngine;
/// <summary>
/// Demonstrates delayed showing of an advertisement.
/// </summary>
public class AdvertisementShowWaitDemo : MonoBehaviour
{
private AdvertisementShowWait.IsReadyWaiter _loadingIsReady;
public void DemoStart()
{
// Debug noisily. Remove me to disable.
AdvertisementShowWait.debug = AdvertisementShowWait.DebugLevel.Debug;
// Start delayed showing of advert, waiting for advert to become ready.
_loadingIsReady = AdvertisementShowWait.ShowWhenReady("myPlacement");
}
public void DemoStop()
{
// Stop waiting for advert to be ready, and do not show it.
_loadingIsReady.Stop();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment