147 lines
5.7 KiB
C#

using System;
using System.Collections.Generic;
using VContainer.Internal;
#if VCONTAINER_ECS_INTEGRATION
using Unity.Entities;
#endif
namespace VContainer.Unity
{
public sealed class EntryPointDispatcher : IDisposable
{
readonly IObjectResolver container;
readonly CompositeDisposable disposable = new CompositeDisposable();
[Inject]
public EntryPointDispatcher(IObjectResolver container)
{
this.container = container;
}
public void Dispatch()
{
PlayerLoopHelper.EnsureInitialized();
var exceptionHandler = container.ResolveOrDefault<EntryPointExceptionHandler>();
var initializables = container.Resolve<ContainerLocal<IReadOnlyList<IInitializable>>>().Value;
for (var i = 0; i < initializables.Count; i++)
{
try
{
initializables[i].Initialize();
}
catch (Exception ex)
{
if (exceptionHandler != null)
exceptionHandler.Publish(ex);
else
UnityEngine.Debug.LogException(ex);
}
}
var postInitializables = container.Resolve<ContainerLocal<IReadOnlyList<IPostInitializable>>>().Value;
for (var i = 0; i < postInitializables.Count; i++)
{
try
{
postInitializables[i].PostInitialize();
}
catch (Exception ex)
{
if (exceptionHandler != null)
exceptionHandler.Publish(ex);
else
UnityEngine.Debug.LogException(ex);
}
}
var startables = container.Resolve<ContainerLocal<IReadOnlyList<IStartable>>>().Value;
if (startables.Count > 0)
{
var loopItem = new StartableLoopItem(startables, exceptionHandler);
disposable.Add(loopItem);
PlayerLoopHelper.Dispatch(PlayerLoopTiming.Startup, loopItem);
}
var postStartables = container.Resolve<ContainerLocal<IReadOnlyList<IPostStartable>>>().Value;
if (postStartables.Count > 0)
{
var loopItem = new PostStartableLoopItem(postStartables, exceptionHandler);
disposable.Add(loopItem);
PlayerLoopHelper.Dispatch(PlayerLoopTiming.PostStartup, loopItem);
}
var fixedTickables = container.Resolve<ContainerLocal<IReadOnlyList<IFixedTickable>>>().Value;
if (fixedTickables.Count > 0)
{
var loopItem = new FixedTickableLoopItem(fixedTickables, exceptionHandler);
disposable.Add(loopItem);
PlayerLoopHelper.Dispatch(PlayerLoopTiming.FixedUpdate, loopItem);
}
var postFixedTickables = container.Resolve<ContainerLocal<IReadOnlyList<IPostFixedTickable>>>().Value;
if (postFixedTickables.Count > 0)
{
var loopItem = new PostFixedTickableLoopItem(postFixedTickables, exceptionHandler);
disposable.Add(loopItem);
PlayerLoopHelper.Dispatch(PlayerLoopTiming.PostFixedUpdate, loopItem);
}
var tickables = container.Resolve<ContainerLocal<IReadOnlyList<ITickable>>>().Value;
if (tickables.Count > 0)
{
var loopItem = new TickableLoopItem(tickables, exceptionHandler);
disposable.Add(loopItem);
PlayerLoopHelper.Dispatch(PlayerLoopTiming.Update, loopItem);
}
var postTickables = container.Resolve<ContainerLocal<IReadOnlyList<IPostTickable>>>().Value;
if (postTickables.Count > 0)
{
var loopItem = new PostTickableLoopItem(postTickables, exceptionHandler);
disposable.Add(loopItem);
PlayerLoopHelper.Dispatch(PlayerLoopTiming.PostUpdate, loopItem);
}
var lateTickables = container.Resolve<ContainerLocal<IReadOnlyList<ILateTickable>>>().Value;
if (lateTickables.Count > 0)
{
var loopItem = new LateTickableLoopItem(lateTickables, exceptionHandler);
disposable.Add(loopItem);
PlayerLoopHelper.Dispatch(PlayerLoopTiming.LateUpdate, loopItem);
}
var postLateTickables = container.Resolve<ContainerLocal<IReadOnlyList<IPostLateTickable>>>().Value;
if (postLateTickables.Count > 0)
{
var loopItem = new PostLateTickableLoopItem(postLateTickables, exceptionHandler);
disposable.Add(loopItem);
PlayerLoopHelper.Dispatch(PlayerLoopTiming.PostLateUpdate, loopItem);
}
#if VCONTAINER_UNITASK_INTEGRATION || UNITY_2021_3_OR_NEWER
var asyncStartables = container.Resolve<ContainerLocal<IReadOnlyList<IAsyncStartable>>>().Value;
if (asyncStartables.Count > 0)
{
var loopItem = new AsyncStartableLoopItem(asyncStartables, exceptionHandler);
disposable.Add(loopItem);
PlayerLoopHelper.Dispatch(PlayerLoopTiming.Startup, loopItem);
}
#endif
#if VCONTAINER_ECS_INTEGRATION
container.Resolve<ContainerLocal<IEnumerable<ComponentSystemBase>>>();
var worldHelpers = container.Resolve<ContainerLocal<IReadOnlyList<WorldConfigurationHelper>>>().Value;
for (var i = 0; i < worldHelpers.Count; i++)
{
worldHelpers[i].SortSystems();
}
#endif
}
public void Dispose() => disposable.Dispose();
}
}