139 lines
3.8 KiB
C#
139 lines
3.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq.Expressions;
|
|
using Cysharp.Threading.Tasks;
|
|
// ReSharper disable MethodHasAsyncOverload
|
|
|
|
namespace BITKit
|
|
{
|
|
public interface IEntryGroup
|
|
{
|
|
|
|
}
|
|
public interface IEntryElement
|
|
{
|
|
bool IsEntered { get; set; }
|
|
void Entry();
|
|
UniTask EntryAsync();
|
|
void Entered();
|
|
void Exit();
|
|
UniTask ExitAsync();
|
|
void Exited();
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class EntryGroup<T> : IEntryGroup where T : IEntryElement
|
|
{
|
|
public int index = -1;
|
|
public List<T> list = new();
|
|
private int m_index = -1;
|
|
private bool completed=true;
|
|
|
|
public event Action<T> OnEntry;
|
|
public event Action<T> OnExit;
|
|
public void Entry(T t)
|
|
{
|
|
if (t is not null)
|
|
{
|
|
list.TryAdd(t);
|
|
|
|
}
|
|
index = list.IndexOf(t);
|
|
EnsureConfiguration();
|
|
}
|
|
public void Entry(int index)
|
|
{
|
|
if (index < list.Count)
|
|
{
|
|
this.index = index;
|
|
}
|
|
}
|
|
public void Entry(Func<T,bool> entryFactory)
|
|
{
|
|
var index = list.FindIndex(x => entryFactory.Invoke(x));
|
|
Entry(index);
|
|
}
|
|
public void Entry()
|
|
{
|
|
index = 0;
|
|
EnsureConfiguration();
|
|
}
|
|
|
|
public void Exit()
|
|
{
|
|
index = -1;
|
|
EnsureConfiguration();
|
|
}
|
|
public bool TryGetEntried(out T value)
|
|
{
|
|
EnsureConfiguration();
|
|
if (m_index is not -1)
|
|
{
|
|
value = list[m_index];
|
|
return true;
|
|
}
|
|
value = default;
|
|
return false;
|
|
}
|
|
private async void EnsureConfiguration()
|
|
{
|
|
try
|
|
{
|
|
if(completed is false) return;
|
|
completed = false;
|
|
if (index == m_index)
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
var currentIndex = m_index;
|
|
if (currentIndex is not -1 && list.TryGetElementAt(currentIndex, out var currentElement))
|
|
{
|
|
currentElement.Exit();
|
|
try
|
|
{
|
|
await currentElement.ExitAsync();
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
return;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
BIT4Log.LogException(e);
|
|
}
|
|
currentElement.Exited();
|
|
currentElement.IsEntered = false;
|
|
OnExit?.Invoke(currentElement);
|
|
}
|
|
m_index = index;
|
|
if (index is not -1 && list.TryGetElementAt(index, out var nextElement))
|
|
{
|
|
nextElement.IsEntered = true;
|
|
OnEntry?.Invoke(nextElement);
|
|
nextElement.Entry();
|
|
try
|
|
{
|
|
await nextElement.EntryAsync();
|
|
nextElement.Entered();
|
|
}
|
|
catch (OperationCanceledException){}
|
|
|
|
}
|
|
}
|
|
completed = true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
#if UNITY_EDITOR
|
|
UnityEngine.Debug.LogException(e);
|
|
#else
|
|
BIT4Log.LogException(e);
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
} |