You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
5.5 KiB
172 lines
5.5 KiB
/**
|
|
* Copyright 2015 IBM Corp. All Rights Reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*/
|
|
|
|
// Uncomment to enable debugging of the Runnable class.
|
|
//#define ENABLE_RUNNABLE_DEBUGGING
|
|
|
|
namespace Mapbox.Unity.Utilities
|
|
{
|
|
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
/// <summary>
|
|
/// Helper class for running co-routines without having to inherit from MonoBehavior.
|
|
/// </summary>
|
|
public class Runnable : MonoBehaviour
|
|
{
|
|
#region Public Properties
|
|
/// <summary>
|
|
/// Returns the Runnable instance.
|
|
/// </summary>
|
|
public static Runnable Instance { get { return Singleton<Runnable>.Instance; } }
|
|
#endregion
|
|
|
|
#region Public Interface
|
|
/// <summary>
|
|
/// Start a co-routine function.
|
|
/// </summary>
|
|
/// <param name="routine">The IEnumerator returns by the co-routine function the user is invoking.</param>
|
|
/// <returns>Returns a ID that can be passed into Stop() to halt the co-routine.</returns>
|
|
public static int Run(IEnumerator routine)
|
|
{
|
|
Routine r = new Routine(routine);
|
|
return r.ID;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stops a active co-routine.
|
|
/// </summary>
|
|
/// <param name="ID">THe ID of the co-routine to stop.</param>
|
|
public static void Stop(int ID)
|
|
{
|
|
Routine r = null;
|
|
if (Instance.m_Routines.TryGetValue(ID, out r))
|
|
r.Stop = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if a routine is still running.
|
|
/// </summary>
|
|
/// <param name="id">The ID returned by Run().</param>
|
|
/// <returns>Returns true if the routine is still active.</returns>
|
|
static public bool IsRunning(int id)
|
|
{
|
|
return Instance.m_Routines.ContainsKey(id);
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
private static bool sm_EditorRunnable = false;
|
|
|
|
/// <summary>
|
|
/// This function enables the Runnable in edit mode.
|
|
/// </summary>
|
|
public static void EnableRunnableInEditor()
|
|
{
|
|
if (!sm_EditorRunnable)
|
|
{
|
|
sm_EditorRunnable = true;
|
|
UnityEditor.EditorApplication.update += UpdateRunnable;
|
|
}
|
|
}
|
|
static void UpdateRunnable()
|
|
{
|
|
if (!Application.isPlaying)
|
|
{
|
|
Instance.UpdateRoutines();
|
|
}
|
|
}
|
|
|
|
#endif
|
|
#endregion
|
|
|
|
#region Private Types
|
|
/// <summary>
|
|
/// This class handles a running co-routine.
|
|
/// </summary>
|
|
private class Routine : IEnumerator
|
|
{
|
|
#region Public Properties
|
|
public int ID { get; private set; }
|
|
public bool Stop { get; set; }
|
|
#endregion
|
|
|
|
#region Private Data
|
|
private bool m_bMoveNext = false;
|
|
private IEnumerator m_Enumerator = null;
|
|
#endregion
|
|
|
|
public Routine(IEnumerator a_enumerator)
|
|
{
|
|
m_Enumerator = a_enumerator;
|
|
Runnable.Instance.StartCoroutine(this);
|
|
Stop = false;
|
|
ID = Runnable.Instance.m_NextRoutineId++;
|
|
|
|
Runnable.Instance.m_Routines[ID] = this;
|
|
#if ENABLE_RUNNABLE_DEBUGGING
|
|
Debug.Log( string.Format("Coroutine {0} started.", ID ) );
|
|
#endif
|
|
}
|
|
|
|
#region IEnumerator Interface
|
|
public object Current { get { return m_Enumerator.Current; } }
|
|
public bool MoveNext()
|
|
{
|
|
m_bMoveNext = m_Enumerator.MoveNext();
|
|
if (m_bMoveNext && Stop)
|
|
m_bMoveNext = false;
|
|
|
|
if (!m_bMoveNext)
|
|
{
|
|
Runnable.Instance.m_Routines.Remove(ID); // remove from the mapping
|
|
#if ENABLE_RUNNABLE_DEBUGGING
|
|
Debug.Log( string.Format("Coroutine {0} stopped.", ID ) );
|
|
#endif
|
|
}
|
|
|
|
return m_bMoveNext;
|
|
}
|
|
public void Reset() { m_Enumerator.Reset(); }
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region Private Data
|
|
private Dictionary<int, Routine> m_Routines = new Dictionary<int, Routine>();
|
|
private int m_NextRoutineId = 1;
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// THis can be called by the user to force all co-routines to get a time slice, this is usually
|
|
/// invoked from an EditorApplication.Update callback so we can use runnable in Editor mode.
|
|
/// </summary>
|
|
public void UpdateRoutines()
|
|
{
|
|
if (m_Routines.Count > 0)
|
|
{
|
|
// we are not in play mode, so we must manually update our co-routines ourselves
|
|
List<Routine> routines = new List<Routine>();
|
|
foreach (var kp in m_Routines)
|
|
routines.Add(kp.Value);
|
|
|
|
foreach (var r in routines)
|
|
r.MoveNext();
|
|
}
|
|
}
|
|
}
|
|
} |