using System.Collections.Generic;
using ILRuntime.CLR.Method;
using ILRuntime.Runtime.Enviorment;
using ILRuntime.Runtime.Intepreter;
using UnityEngine;
///
/// 热更工程使用monovehavior的基础代理类
///
public class ILBehaviourProxy : WidgetBehavior
{
[SerializeField]
[Tooltip("Logic工程的代码,例:命名空间.类名")]
List classNames;
Dictionary ilBehaviourHolders = new Dictionary();
AppDomain appDomain {
get { return ILLauncherProxy.Instance.appdomain; }
}
private void Init()
{
InitWidgts();
ilBehaviourHolders.Clear();
var baseType = appDomain.LoadedTypes["ILBehaviour"];
foreach (var name in classNames)
{
if (ilBehaviourHolders.ContainsKey(name))
{
DebugEx.LogErrorFormat("ILBehaviour 脚本代码有重复项:{0}", name);
continue;
}
var obj = appDomain.Instantiate(name);
if (obj == null)
{
DebugEx.LogErrorFormat("ILBehaviour 脚本代码不存在:{0}", name);
continue;
}
var setProxy = baseType.GetMethod("SetProxy", 1);
appDomain.Invoke(setProxy, obj, this);//将当前代理对象传过去
var holder = new ILBehaviourHolder(obj);
//此处用type获取的方法,子类不定义是不会执行Logic工程父类的方法
var type = obj.Type;
holder.awake = type.GetMethod("Awake");
holder.start = type.GetMethod("Start");
holder.onEnable = type.GetMethod("OnEnable");
holder.onDisable = type.GetMethod("OnDisable");
holder.update = type.GetMethod("Update");
holder.fixedUpdate = type.GetMethod("FixedUpdate");
holder.lateUpdate = type.GetMethod("LateUpdate");
holder.onDestroy = type.GetMethod("OnDestroy", 0);
//baseType 获取的方法,才会执行父类Logic工程的父类方法,但同时也不会调用子类重写的方法
holder.dipose = baseType.GetMethod("Dipose", 0);
ilBehaviourHolders.Add(name, holder);
}
}
//获取IL热更工程的脚本实例,供热更工程调用,不要在主工程使用
public object GetILBehaviour(string name)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
return holder.instance;
else
return null;
}
private void Awake()
{
Init();
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.awake != null)
appDomain.Invoke(holder.awake, holder.instance);
}
}
}
private void Start()
{
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.start != null)
appDomain.Invoke(holder.start, holder.instance);
}
}
}
private void OnEnable()
{
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.onEnable != null)
appDomain.Invoke(holder.onEnable, holder.instance);
}
}
}
private void OnDisable()
{
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.onDisable != null)
{
appDomain.Invoke(holder.onDisable, holder.instance);
}
}
}
}
private void Update()
{
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.update != null)
appDomain.Invoke(holder.update, holder.instance);
}
}
}
private void FixedUpdate()
{
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.fixedUpdate != null)
appDomain.Invoke(holder.fixedUpdate, holder.instance);
}
}
}
private void LateUpdate()
{
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.lateUpdate != null)
appDomain.Invoke(holder.lateUpdate, holder.instance);
}
}
}
private void OnDestroy()
{
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (appDomain != null && holder.onDestroy != null)
appDomain?.Invoke(holder.onDestroy, holder.instance);
if (appDomain != null && holder.dipose != null)
appDomain?.Invoke(holder.dipose, holder.instance);
}
}
ilBehaviourHolders.Clear();
}
private class ILBehaviourHolder
{
public object instance;
public IMethod awake, start, onEnable, onDisable, update, fixedUpdate, lateUpdate, onDestroy;
public IMethod dipose;
public ILBehaviourHolder(object instance)
{
this.instance = instance;
}
}
}