using System; using System.Collections.Generic; using UnityEngine; namespace Uigenx { /// /// Creates a screen instance from its key. The compiler emits one implementation per assembly /// with a plain switch, so there is no reflection at runtime. /// public interface IUgxScreenFactory { bool Contains(string key); /// Returns null when this factory does not own the key. UgxScreen Create(string key); } /// /// Where generated factories install themselves. Several assemblies can contribute screens; /// the most recently installed factory that owns a key wins. /// public static class UgxScreens { static readonly List Factories = new List(2); /// Static state survives a play mode exit when domain reload is disabled. [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] static void ResetOnLoad() => Factories.Clear(); /// Idempotent per factory type, so a repeated initialize callback cannot stack duplicates. public static void Install(IUgxScreenFactory factory) { if (factory == null) throw new ArgumentNullException(nameof(factory)); var type = factory.GetType(); for (int i = Factories.Count - 1; i >= 0; i--) if (Factories[i].GetType() == type) Factories.RemoveAt(i); Factories.Add(factory); } public static bool Remove(IUgxScreenFactory factory) => Factories.Remove(factory); public static void Clear() => Factories.Clear(); public static bool Contains(string key) { for (int i = Factories.Count - 1; i >= 0; i--) if (Factories[i].Contains(key)) return true; return false; } public static UgxScreen Create(string key) { if (string.IsNullOrEmpty(key)) return null; for (int i = Factories.Count - 1; i >= 0; i--) { // A generated factory is code from the game assembly. try { var screen = Factories[i].Create(key); if (screen != null) return screen; } catch (Exception e) { Debug.LogError("[ugx] screen factory " + Factories[i].GetType().Name + " threw for '" + key + "': " + e); } } return null; } public static UgxScreen CreateOrThrow(string key) { var screen = Create(key); if (screen != null) return screen; throw new InvalidOperationException( "no factory can create screen '" + key + "'. Re-export from UI Creator so " + "UgxScreenFactory.g.cs contains it, and check that the generated assembly compiled."); } } }