BITFALL/Assets/BITKit/Core/Group/ActivableGroup.cs

129 lines
3.5 KiB
C#
Raw Normal View History

2023-08-12 01:43:24 +08:00
using System;
using System.Collections.Generic;
2023-10-20 19:31:12 +08:00
using System.Linq.Expressions;
using Cysharp.Threading.Tasks;
// ReSharper disable MethodHasAsyncOverload
2023-08-12 01:43:24 +08:00
namespace BITKit
{
2023-10-20 19:31:12 +08:00
public interface IEntryGroup
{
}
2023-08-12 01:43:24 +08:00
public interface IEntryElement
{
2023-10-20 19:31:12 +08:00
bool IsEntered { get; set; }
2023-08-12 01:43:24 +08:00
void Entry();
2023-10-20 19:31:12 +08:00
UniTask EntryAsync();
2023-11-15 23:54:54 +08:00
void Entered();
2023-08-12 01:43:24 +08:00
void Exit();
2023-10-20 19:31:12 +08:00
UniTask ExitAsync();
2023-11-15 23:54:54 +08:00
void Exited();
2023-08-12 01:43:24 +08:00
}
[System.Serializable]
public class EntryGroup<T> : IEntryGroup where T : IEntryElement
{
public int index = -1;
public List<T> list = new();
2023-10-20 19:31:12 +08:00
private int m_index = -1;
private bool completed=true;
public event Action<T> OnEntry;
public event Action<T> OnExit;
2023-08-12 01:43:24 +08:00
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();
2023-11-02 20:58:55 +08:00
if (m_index is not -1)
2023-08-12 01:43:24 +08:00
{
2023-11-02 20:58:55 +08:00
value = list[m_index];
2023-08-12 01:43:24 +08:00
return true;
}
value = default;
return false;
}
2023-10-20 19:31:12 +08:00
private async void EnsureConfiguration()
2023-08-12 01:43:24 +08:00
{
2023-10-20 19:31:12 +08:00
try
2023-08-12 01:43:24 +08:00
{
2023-10-20 19:31:12 +08:00
if(completed is false) return;
completed = false;
if (index == m_index)
2023-08-12 01:43:24 +08:00
{
2023-10-20 19:31:12 +08:00
2023-08-12 01:43:24 +08:00
}
2023-10-20 19:31:12 +08:00
else
2023-08-12 01:43:24 +08:00
{
2023-10-20 19:31:12 +08:00
var currentIndex = m_index;
2023-10-29 15:27:13 +08:00
if (currentIndex is not -1 && list.TryGetElementAt(currentIndex, out var currentElement))
2023-10-20 19:31:12 +08:00
{
2023-10-29 15:27:13 +08:00
currentElement.Exit();
2023-10-20 19:31:12 +08:00
try
{
2023-10-29 15:27:13 +08:00
await currentElement.ExitAsync();
2023-11-15 23:54:54 +08:00
currentElement.Exited();
2023-10-20 19:31:12 +08:00
}
catch (OperationCanceledException)
{
2023-11-21 18:05:18 +08:00
return;
2023-10-20 19:31:12 +08:00
}
2023-10-29 15:27:13 +08:00
currentElement.IsEntered = false;
OnExit?.Invoke(currentElement);
2023-10-20 19:31:12 +08:00
}
2023-11-02 20:58:55 +08:00
m_index = index;
2023-10-29 15:27:13 +08:00
if (index is not -1 && list.TryGetElementAt(index, out var nextElement))
2023-10-20 19:31:12 +08:00
{
2023-10-29 15:27:13 +08:00
nextElement.IsEntered = true;
nextElement.Entry();
2023-10-20 19:31:12 +08:00
try
{
2023-10-29 15:27:13 +08:00
await nextElement.EntryAsync();
2023-11-15 23:54:54 +08:00
nextElement.Entered();
2023-10-20 19:31:12 +08:00
}
catch (OperationCanceledException){}
2023-10-29 15:27:13 +08:00
OnEntry?.Invoke(nextElement);
2023-10-20 19:31:12 +08:00
}
2023-08-12 01:43:24 +08:00
}
2023-10-20 19:31:12 +08:00
completed = true;
}
catch (Exception e)
{
BIT4Log.LogException(e);
2023-08-12 01:43:24 +08:00
}
2023-10-20 19:31:12 +08:00
2023-08-12 01:43:24 +08:00
}
}
}