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.");
}
}
}