using System; using UnityEngine; using UnityEngine.SceneManagement; using VContainer.Internal; namespace VContainer.Unity { struct ComponentDestination { public Transform Parent; public Func ParentFinder; public bool DontDestroyOnLoad; public Transform GetParent(IObjectResolver resolver) { if (Parent != null) return Parent; if (ParentFinder != null) return ParentFinder(resolver); return null; } public void ApplyDontDestroyOnLoadIfNeeded(Component component) { if (DontDestroyOnLoad) { UnityEngine.Object.DontDestroyOnLoad(component); } } } public sealed class ComponentRegistrationBuilder : RegistrationBuilder { readonly object instance; readonly Func prefabFinder; readonly string gameObjectName; ComponentDestination destination; Scene scene; internal ComponentRegistrationBuilder(object instance) : base(instance.GetType(), Lifetime.Singleton) { this.instance = instance; } internal ComponentRegistrationBuilder(in Scene scene, Type implementationType) : base(implementationType, Lifetime.Singleton) { this.scene = scene; } internal ComponentRegistrationBuilder( Func prefabFinder, Type implementationType, Lifetime lifetime) : base(implementationType, lifetime) { this.prefabFinder = prefabFinder; } internal ComponentRegistrationBuilder( string gameObjectName, Type implementationType, Lifetime lifetime) : base(implementationType, lifetime) { this.gameObjectName = gameObjectName; } public override Registration Build() { IInstanceProvider provider; if (instance != null) { var injector = InjectorCache.GetOrBuild(ImplementationType); provider = new ExistingComponentProvider(instance, injector, Parameters, destination.DontDestroyOnLoad); } else if (scene.IsValid()) { provider = new FindComponentProvider(ImplementationType, Parameters, in scene, in destination); } else if (prefabFinder != null) { var injector = InjectorCache.GetOrBuild(ImplementationType); provider = new PrefabComponentProvider(prefabFinder, injector, Parameters, in destination); } else { var injector = InjectorCache.GetOrBuild(ImplementationType); provider = new NewGameObjectProvider(ImplementationType, injector, Parameters, in destination, gameObjectName); } return new Registration(ImplementationType, Lifetime, InterfaceTypes, provider); } public ComponentRegistrationBuilder UnderTransform(Transform parent) { destination.Parent = parent; return this; } public ComponentRegistrationBuilder UnderTransform(Func parentFinder) { destination.ParentFinder = _ => parentFinder(); return this; } public ComponentRegistrationBuilder UnderTransform(Func parentFinder) { destination.ParentFinder = parentFinder; return this; } public ComponentRegistrationBuilder DontDestroyOnLoad() { destination.DontDestroyOnLoad = true; return this; } } }