using System.Collections.Generic; using Zenject; namespace FlappyBird.Gameplay.Pipes { /// /// Pure C# object pool for PipeView prefab instances. /// Pre-warming is deferred to Initialize() (called by Zenject after the /// container is fully built) to avoid a circular dependency: /// PipePool → Factory → PipeView → IPipePool → PipePool /// public sealed class PipePool : IPipePool, IInitializable { private readonly Stack _inactive = new Stack(); private readonly PipeSettings _settings; private readonly PipeView.Factory _factory; /// Constructor injection — no instantiation here. public PipePool(PipeSettings settings, PipeView.Factory factory) { _settings = settings; _factory = factory; } // ── IInitializable ───────────────────────────────────────────────── /// /// Called by Zenject after all bindings are resolved. /// Safe to call Factory.Create() here because IPipePool is already registered. /// public void Initialize() { Prewarm(_settings.InitialPoolSize); } // ── IPipePool ────────────────────────────────────────────────────── /// public PipeView Get() { PipeView pipe = _inactive.Count > 0 ? _inactive.Pop() : _factory.Create(); pipe.OnSpawn(); return pipe; } /// public void Return(PipeView pipe) { pipe.OnDespawn(); _inactive.Push(pipe); } // ── Private helpers ──────────────────────────────────────────────── private void Prewarm(int count) { for (int i = 0; i < count; i++) { PipeView pipe = _factory.Create(); pipe.OnDespawn(); _inactive.Push(pipe); } } } }