using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ILRuntime.CLR.Method;
using ILRuntime.Runtime.Intepreter;
using UnityEngine;
namespace Model
{
public class IILUIFactoryMethod: IUIFactory
{
private readonly ILRuntime.Runtime.Enviorment.AppDomain appDomain;
private readonly ILTypeInstance instance;
private readonly IMethod method;
private readonly object[] params3 = new object[3];
public IILUIFactoryMethod(Type type)
{
appDomain = Game.EntityEventManager.AppDomain;
this.instance = this.appDomain.Instantiate(type.FullName);
this.method = this.instance.Type.GetMethod("Create", 3);
}
public UI Create(Scene scene, int type, UI parent)
{
this.params3[0] = scene;
this.params3[1] = type;
this.params3[2] = parent;
object obj = this.appDomain.Invoke(this.method, this.instance, this.params3);
return (UI) obj;
}
}
public class IMonoUIFactoryMethod : IUIFactory
{
private readonly object instance;
private readonly MethodInfo methodInfo;
private readonly object[] params3 = new object[3];
public IMonoUIFactoryMethod(Type type)
{
this.instance = Activator.CreateInstance(type);
this.methodInfo = type.GetMethod("Create");
}
public UI Create(Scene scene, int type, UI parent)
{
this.params3[0] = scene;
this.params3[1] = type;
this.params3[2] = parent;
return (UI)this.methodInfo.Invoke(this.instance, params3);
}
}
///
/// 管理所有UI
///
[EntityEvent(EntityEventId.UIComponent)]
public class UIComponent: Component
{
private UI Root;
private Dictionary UiTypes;
private readonly Dictionary uis = new Dictionary();
public override void Dispose()
{
if (this.Id == 0)
{
return;
}
base.Dispose();
foreach (int type in uis.Keys.ToArray())
{
UI ui;
if (!uis.TryGetValue(type, out ui))
{
continue;
}
uis.Remove(type);
ui.Dispose();
}
}
private void Awake()
{
GameObject uiCanvas = GameObject.Find("Global/UI/UICanvas");
this.Root = new UI(this.GetOwner(), UIType.Root, null, uiCanvas);
this.Load();
}
private void Load()
{
this.UiTypes = new Dictionary();
#if ILRuntime
Type[] types = DllHelper.GetHotfixTypes();
#else
Type[] types = DllHelper.GetMonoTypes();
#endif
foreach (Type type in types)
{
object[] attrs = type.GetCustomAttributes(typeof (UIFactoryAttribute), false);
if (attrs.Length == 0)
{
continue;
}
UIFactoryAttribute attribute = attrs[0] as UIFactoryAttribute;
if (this.UiTypes.ContainsKey(attribute.Type))
{
throw new GameException($"已经存在同类UI Factory: {attribute.Type}");
}
#if ILRuntime
IUIFactory iuiFactory = new IILUIFactoryMethod(type);
#else
IUIFactory iuiFactory = new IMonoUIFactoryMethod(type);
#endif
this.UiTypes.Add(attribute.Type, iuiFactory);
}
}
public UI Create(int type)
{
try
{
UI ui = this.UiTypes[type].Create(this.GetOwner(), type, this.Root);
this.uis.Add(type, ui);
// 假如UI有配置行为树,执行之
UIConfig uiConfig = ui.GameObject.GetComponent();
if (uiConfig != null)
{
BehaviorTree behaviorTree = Game.Scene.GetComponent().CreateTree(this.GetOwner(), uiConfig.CreateBT);
BTEnv env = new BTEnv
{
{"UI", ui}
};
behaviorTree.Run(env);
}
return ui;
}
catch (Exception e)
{
throw new Exception($"{type} UI 错误: {e}");
}
}
public void Add(int type, UI ui)
{
this.uis.Add(type, ui);
}
public void Remove(int type)
{
UI ui;
if (!this.uis.TryGetValue(type, out ui))
{
return;
}
this.uis.Remove(type);
ui.Dispose();
}
public void RemoveAll()
{
foreach (int type in this.uis.Keys.ToArray())
{
UI ui;
if (!this.uis.TryGetValue(type, out ui))
{
continue;
}
this.uis.Remove(type);
ui.Dispose();
}
}
public UI Get(int type)
{
UI ui;
this.uis.TryGetValue(type, out ui);
return ui;
}
public List GetUITypeList()
{
return new List(this.uis.Keys);
}
}
}