Scripts/Runtime/Utilities/CoroutineUtility.cs (103 lines of code) (raw):
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
using System;
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using System.Collections.Generic;
namespace Facebook.WitAi.Utilities
{
public static class CoroutineUtility
{
// Start coroutine
public static CoroutinePerformer StartCoroutine(IEnumerator asyncMethod)
{
CoroutinePerformer performer = GetPerformer();
performer.CoroutineBegin(asyncMethod);
return performer;
}
// Get performer
private static CoroutinePerformer GetPerformer()
{
CoroutinePerformer performer = new GameObject("Coroutine").AddComponent<CoroutinePerformer>();
//performer.gameObject.hideFlags = HideFlags.DontSave;
performer.gameObject.hideFlags = HideFlags.HideAndDontSave;
return performer;
}
// Coroutine performer
public class CoroutinePerformer : MonoBehaviour
{
// Coroutine
public bool IsRunning { get; private set; }
private Coroutine _runtimeCoroutine;
// Dont destroy
private void Awake()
{
DontDestroyOnLoad(gameObject);
}
// Perform coroutine
public void CoroutineBegin(IEnumerator asyncMethod)
{
// Cannot call twice
if (IsRunning)
{
return;
}
// Begin running
IsRunning = true;
#if UNITY_EDITOR
// Editor mode
if (!Application.isPlaying)
{
_editorMethod = asyncMethod;
UnityEditor.EditorApplication.update += EditorCoroutineIterate;
return;
}
#endif
// Begin coroutine
_runtimeCoroutine = StartCoroutine(RuntimeCoroutineIterate(asyncMethod));
}
#if UNITY_EDITOR
// Editor iterate
private IEnumerator _editorMethod;
private void EditorCoroutineIterate()
{
if (_editorMethod != null)
{
if (!_editorMethod.MoveNext())
{
CoroutineComplete();
}
}
}
#endif
// Runtime iterate
private IEnumerator RuntimeCoroutineIterate(IEnumerator asyncMethod)
{
// Wait for completion
yield return StartCoroutine(asyncMethod);
// Complete
CoroutineComplete();
}
// Cancel on destroy
private void OnDestroy()
{
if (IsRunning)
{
CoroutineCancel();
}
}
// Cancel coroutine
public void CoroutineCancel()
{
if (IsRunning)
{
CoroutineComplete();
}
}
// Completed
private void CoroutineComplete()
{
// Ignore unless running
if (!IsRunning)
{
return;
}
// Done
IsRunning = false;
#if UNITY_EDITOR
// Complete
if (_editorMethod != null)
{
UnityEditor.EditorApplication.update -= EditorCoroutineIterate;
_editorMethod = null;
}
#endif
// Stop coroutine
if (_runtimeCoroutine != null)
{
StopCoroutine(_runtimeCoroutine);
_runtimeCoroutine = null;
}
// Destroy
DestroyImmediate(gameObject);
}
}
}
}