84 lines
2.7 KiB
C#
84 lines
2.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
using Debug = UnityEngine.Debug;
|
|
|
|
namespace DanieleMarotta.RiversongCodeShowcase
|
|
{
|
|
public abstract class GameSystemGroup : IGameSystem, IInitializable, IUpdatable, IDisposable
|
|
{
|
|
private List<IInitializable> _initializables = new();
|
|
|
|
private List<IUpdatable> _updatables = new();
|
|
|
|
private List<IDisposable> _disposables = new();
|
|
|
|
public virtual string Name => GetType().Name;
|
|
|
|
public List<IGameSystem> Systems { get; } = new();
|
|
|
|
public IUpdateFilter UpdateFilter { get; set; }
|
|
|
|
public void Add(IGameSystem system)
|
|
{
|
|
Systems.Add(system);
|
|
if (system is IInitializable initializable) _initializables.Add(initializable);
|
|
if (system is IUpdatable updatable) _updatables.Add(updatable);
|
|
if (system is IDisposable disposable) _disposables.Add(disposable);
|
|
}
|
|
|
|
public virtual async UniTask InitializeAsync()
|
|
{
|
|
SystemSorter.InitializableSorter.Sort(_initializables);
|
|
SystemSorter.UpdatableSorter.Sort(_updatables);
|
|
SystemSorter.DisposableSorter.Sort(_disposables);
|
|
|
|
var batches = SystemSorter.InitializableSorter.CreateExecutionBatches(_initializables);
|
|
foreach (var batch in batches)
|
|
{
|
|
var tasks = new UniTask[batch.Count];
|
|
for (var i = 0; i < batch.Count; i++) tasks[i] = InitializeAndLogAsync(batch[i]);
|
|
|
|
await UniTask.WhenAll(tasks);
|
|
}
|
|
}
|
|
|
|
private static async UniTask InitializeAndLogAsync(IInitializable initializable)
|
|
{
|
|
var startTime = Time.unscaledTime;
|
|
|
|
await initializable.InitializeAsync();
|
|
|
|
LogInitializationTime(initializable, startTime);
|
|
}
|
|
|
|
private static void LogInitializationTime(IInitializable initializable, float startTime)
|
|
{
|
|
if (initializable is GameSystemGroup) return;
|
|
|
|
var elapsed = Time.unscaledTime - startTime;
|
|
|
|
var log = $"Initialized {((IGameSystem)initializable).Name} in {(int)(elapsed * 1000)} ms";
|
|
if (elapsed > 0.3f) log = $"<color=yellow>{log}</color>";
|
|
|
|
Debug.Log(log);
|
|
}
|
|
|
|
public virtual void Update()
|
|
{
|
|
foreach (var updatable in _updatables)
|
|
{
|
|
if (UpdateFilter != null && !UpdateFilter.CanUpdate(updatable)) continue;
|
|
|
|
updatable.Update();
|
|
}
|
|
}
|
|
|
|
public virtual void Dispose()
|
|
{
|
|
foreach (var disposable in _disposables) disposable.Dispose();
|
|
}
|
|
}
|
|
}
|