using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
///
/// 热更工程使用monovehavior的基础代理类
///
public class ILBehaviourProxy : WidgetBehavior
{
[SerializeField]
[Tooltip("Logic工程的代码,例:命名空间.类名")]
List classNames;
Dictionary ilBehaviourHolders = new Dictionary();
public object prefabScript;
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 = GetTypeFromAllAssemblies(name);
if (obj == null)
{
DebugEx.LogErrorFormat("ILBehaviour 脚本代码不存在:{0}", name);
continue;
}
ILBehaviour.SetProxy(this);
prefabScript = Activator.CreateInstance(obj);
if (prefabScript == null)
continue;
var holder = new ILBehaviourHolder(prefabScript);
//此处用type获取的方法,子类不定义是不会执行Logic工程父类的方法
var type = prefabScript.GetType();
//MethodInfo awakeMethod = myType.GetMethod("Awake", BindingFlags.NonPublic | BindingFlags.Instance);
holder.awake = type.GetMethod("Awake", BindingFlags.NonPublic | BindingFlags.Instance);
holder.start = type.GetMethod("Start", BindingFlags.NonPublic | BindingFlags.Instance);
holder.onEnable = type.GetMethod("OnEnable", BindingFlags.NonPublic | BindingFlags.Instance);
holder.onDisable = type.GetMethod("OnDisable", BindingFlags.NonPublic | BindingFlags.Instance);
holder.update = type.GetMethod("Update", BindingFlags.NonPublic | BindingFlags.Instance);
holder.fixedUpdate = type.GetMethod("FixedUpdate", BindingFlags.NonPublic | BindingFlags.Instance);
holder.lateUpdate = type.GetMethod("LateUpdate", BindingFlags.NonPublic | BindingFlags.Instance);
holder.onDestroy = type.GetMethod("OnDestroy", BindingFlags.NonPublic | BindingFlags.Instance);
holder.dipose = type.GetMethod("Dipose", BindingFlags.NonPublic | BindingFlags.Instance);
ilBehaviourHolders.Add(name, holder);
}
}
//获取IL热更工程的脚本实例,供热更工程调用,不要在主工程使用
public object GetILBehaviour(string name)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
return holder.instance;
else
return null;
}
void Awake()
{
Init();
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.awake == null)
return;
holder.awake.Invoke(holder.instance, null);
}
}
}
void Start()
{
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.start == null)
return;
holder.start.Invoke(holder.instance, null);
}
}
}
void OnEnable()
{
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.onEnable == null)
return;
holder.onEnable.Invoke(holder.instance, null);
}
}
}
void OnDisable()
{
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.onDisable == null)
return;
holder.onDisable.Invoke(holder.instance, null);
}
}
}
void Update()
{
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.update == null)
return;
holder.update.Invoke(holder.instance, null);
}
}
}
void FixedUpdate()
{
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.fixedUpdate == null)
return;
holder.fixedUpdate.Invoke(holder.instance, null);
}
}
}
void LateUpdate()
{
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.lateUpdate == null)
return;
holder.lateUpdate.Invoke(holder.instance, null);
}
}
}
void OnDestroy()
{
foreach (var name in classNames)
{
ILBehaviourHolder holder;
if (ilBehaviourHolders.TryGetValue(name, out holder))
{
if (holder.onDestroy == null)
return;
holder.onDestroy.Invoke(holder.instance, null);
if (holder.dipose == null)
return;
holder.dipose.Invoke(holder.instance, null);
}
}
ilBehaviourHolders.Clear();
}
private class ILBehaviourHolder
{
public object instance;
public MethodInfo awake, start, onEnable, onDisable, update, fixedUpdate, lateUpdate, onDestroy;
public MethodInfo dipose;
public ILBehaviourHolder(object instance)
{
this.instance = instance;
}
}
Type GetTypeFromAllAssemblies(string typeName)
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var type = assembly.GetType(typeName);
if (type != null)
return type;
}
return null;
}
}