// MIT License - Copyright (c) 2025 wallstop
// Full license text: https://github.com/wallstop/unity-helpers/blob/main/LICENSE
#if ZENJECT_PRESENT
namespace WallstopStudios.UnityHelpers.Integrations.Zenject
{
using global::Zenject;
using UnityEngine;
using WallstopStudios.UnityHelpers.Core.Attributes;
using WallstopStudios.UnityHelpers.Tags;
///
/// Zenject installer that wires up the relational component assigner and optional scene
/// initializer.
///
///
/// Add this installer to your SceneContext to:
/// - Bind as a singleton (if nobody else already did)
/// - Optionally register to populate relational
/// fields after container construction
/// - Optionally register so additively loaded scenes
/// receive the same hydration pass
/// Serialized toggles expose these behaviours plus the shared
/// (include inactive objects, scan strategy).
///
///
///
/// // In your scene, add a SceneContext and this installer component.
/// // Toggle "Assign Scene On Initialize" to run the one-time scene scan on startup.
///
///
[AddComponentMenu("Wallstop Studios/Relational Components/Zenject Installer")]
public sealed class RelationalComponentsInstaller : MonoInstaller
{
[SerializeField]
[Tooltip(
"When enabled the installer will register a scene-level initializer that populates relational"
+ " fields immediately after Zenject finishes constructing the container."
)]
private bool _assignSceneOnInitialize = true;
[SerializeField]
[Tooltip(
"Include inactive GameObjects when scanning the active scene for relational fields during"
+ " initialization."
)]
private bool _includeInactiveObjects = true;
[SerializeField]
[Tooltip(
"When enabled, registers a listener that assigns relational fields for additively loaded"
+ " scenes as they are loaded."
)]
private bool _listenForAdditiveScenes = true;
public override void InstallBindings()
{
AttributeMetadataCache cacheInstance = AttributeMetadataCache.Instance;
if (cacheInstance != null && !Container.HasBinding(typeof(AttributeMetadataCache)))
{
Container.Bind().FromInstance(cacheInstance);
}
if (!Container.HasBinding(typeof(IRelationalComponentAssigner)))
{
Container
.Bind()
.To()
.AsSingle();
}
if (_assignSceneOnInitialize)
{
if (!Container.HasBinding(typeof(RelationalSceneAssignmentOptions)))
{
Container.BindInstance(
new RelationalSceneAssignmentOptions(_includeInactiveObjects)
);
}
Container.BindInterfacesTo().AsSingle();
}
if (_listenForAdditiveScenes)
{
if (!Container.HasBinding(typeof(RelationalSceneAssignmentOptions)))
{
Container.BindInstance(
new RelationalSceneAssignmentOptions(_includeInactiveObjects)
);
}
Container.BindInterfacesTo().AsSingle();
}
}
}
}
#endif