impl CoroutineManager

This commit is contained in:
in0finite 2022-01-21 00:14:22 +01:00
parent 4f16c2ef76
commit f2c330f6a5
4 changed files with 184 additions and 0 deletions

View file

@ -0,0 +1,57 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SanAndreasUnity.Utilities
{
public class CoroutineManager : StartupSingleton<CoroutineManager>
{
private static CoroutineRunner m_coroutineRunner = new CoroutineRunner();
#if UNITY_EDITOR
[UnityEditor.InitializeOnLoadMethod]
static void InitOnLoad()
{
UnityEditor.EditorApplication.update -= EditorUpdate;
UnityEditor.EditorApplication.update += EditorUpdate;
}
static void EditorUpdate()
{
if (!F.IsAppInEditTime)
return;
m_coroutineRunner.Update();
}
#endif
void Update()
{
m_coroutineRunner.Update();
}
public static CoroutineInfo Start(IEnumerator coroutine)
{
return m_coroutineRunner.StartCoroutine(coroutine, null, null);
}
public static CoroutineInfo Start(
IEnumerator coroutine,
System.Action onFinishSuccess,
System.Action<System.Exception> onFinishError)
{
return m_coroutineRunner.StartCoroutine(coroutine, onFinishSuccess, onFinishError);
}
public static void Stop(CoroutineInfo coroutineInfo)
{
m_coroutineRunner.StopCoroutine(coroutineInfo);
}
public static bool IsRunning(CoroutineInfo coroutineInfo)
{
return m_coroutineRunner.IsCoroutineRunning(coroutineInfo);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 81bcbcc6c7d0163408eea6ffa3732506
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,105 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SanAndreasUnity.Utilities
{
public class CoroutineInfo
{
private static long s_lastId = 0;
public long Id { get; } = ++s_lastId;
public IEnumerator coroutine { get; }
public System.Action onFinishSuccess { get; }
public System.Action<System.Exception> onFinishError { get; }
public CoroutineInfo(IEnumerator coroutine, Action onFinishSuccess, Action<Exception> onFinishError)
{
this.coroutine = coroutine;
this.onFinishSuccess = onFinishSuccess;
this.onFinishError = onFinishError;
}
}
public class CoroutineRunner
{
private List<CoroutineInfo> m_coroutines = new List<CoroutineInfo>();
private List<CoroutineInfo> m_newCoroutines = new List<CoroutineInfo>();
public CoroutineInfo StartCoroutine(IEnumerator coroutine, System.Action onFinishSuccess, System.Action<System.Exception> onFinishError)
{
var coroutineInfo = new CoroutineInfo(coroutine, onFinishSuccess, onFinishError);
m_newCoroutines.Add(coroutineInfo);
return coroutineInfo;
}
public void StopCoroutine(CoroutineInfo coroutineInfo)
{
if (null == coroutineInfo)
return;
int index = m_coroutines.IndexOf(coroutineInfo);
if (index >= 0)
m_coroutines[index] = null;
m_newCoroutines.Remove(coroutineInfo);
}
public bool IsCoroutineRunning(CoroutineInfo coroutineInfo)
{
if (null == coroutineInfo)
return false;
return m_coroutines.Contains(coroutineInfo);
}
public void Update()
{
m_coroutines.RemoveAll(c => null == c);
m_coroutines.AddRange(m_newCoroutines);
m_newCoroutines.Clear();
for (int i = 0; i < m_coroutines.Count; i++)
{
this.UpdateCoroutine(m_coroutines[i], i);
}
}
void UpdateCoroutine(CoroutineInfo coroutine, int coroutineIndex)
{
bool isFinished = false;
bool isSuccess = false;
System.Exception failureException = null;
try
{
if (!coroutine.coroutine.MoveNext())
{
isFinished = true;
isSuccess = true;
}
}
catch (System.Exception ex)
{
isFinished = true;
isSuccess = false;
failureException = ex;
Debug.LogException(ex);
}
if (isFinished)
{
m_coroutines[coroutineIndex] = null;
if (isSuccess)
F.RunExceptionSafe(coroutine.onFinishSuccess);
else
F.RunExceptionSafe(() => coroutine.onFinishError(failureException));
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 577a4c9d6ba16494f8bea1797e91fb73
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: