93 lines
2.8 KiB
C#
93 lines
2.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
using VContainer.Internal;
|
|
|
|
namespace VContainer.Unity
|
|
{
|
|
public sealed class VContainerParentTypeReferenceNotFound : Exception
|
|
{
|
|
public readonly Type ParentType;
|
|
|
|
public VContainerParentTypeReferenceNotFound(Type parentType, string message)
|
|
: base(message)
|
|
{
|
|
ParentType = parentType;
|
|
}
|
|
}
|
|
|
|
partial class LifetimeScope
|
|
{
|
|
static readonly List<LifetimeScope> WaitingList = new List<LifetimeScope>();
|
|
|
|
#if UNITY_2019_3_OR_NEWER
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
|
#else
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
|
#endif
|
|
static void SubscribeSceneEvents()
|
|
{
|
|
SceneManager.sceneLoaded -= OnSceneLoaded;
|
|
SceneManager.sceneLoaded += OnSceneLoaded;
|
|
}
|
|
|
|
static void EnqueueAwake(LifetimeScope lifetimeScope)
|
|
{
|
|
WaitingList.Add(lifetimeScope);
|
|
}
|
|
|
|
static void CancelAwake(LifetimeScope lifetimeScope)
|
|
{
|
|
WaitingList.Remove(lifetimeScope);
|
|
}
|
|
|
|
static void AwakeWaitingChildren(LifetimeScope awakenParent)
|
|
{
|
|
if (WaitingList.Count <= 0) return;
|
|
|
|
using (ListPool<LifetimeScope>.Get(out var buffer))
|
|
{
|
|
for (var i = WaitingList.Count - 1; i >= 0; i--)
|
|
{
|
|
var waitingScope = WaitingList[i];
|
|
if (waitingScope.parentReference.Type == awakenParent.GetType())
|
|
{
|
|
waitingScope.parentReference.Object = awakenParent;
|
|
WaitingList.RemoveAt(i);
|
|
buffer.Add(waitingScope);
|
|
}
|
|
}
|
|
|
|
foreach (var waitingScope in buffer)
|
|
{
|
|
waitingScope.Awake();
|
|
}
|
|
}
|
|
}
|
|
|
|
static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
|
{
|
|
if (WaitingList.Count <= 0)
|
|
return;
|
|
|
|
using (ListPool<LifetimeScope>.Get(out var buffer))
|
|
{
|
|
for (var i = WaitingList.Count - 1; i >= 0; i--)
|
|
{
|
|
var waitingScope = WaitingList[i];
|
|
if (waitingScope.gameObject.scene == scene)
|
|
{
|
|
WaitingList.RemoveAt(i);
|
|
buffer.Add(waitingScope);
|
|
}
|
|
}
|
|
|
|
foreach (var waitingScope in buffer)
|
|
{
|
|
waitingScope.Awake(); // Re-throw if parent not found
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |