Update ProcedureLoadAssembly.cs

This commit is contained in:
ALEXTANG
2023-04-24 23:29:34 +08:00
parent 72ffc58030
commit 90c22db2d2

View File

@@ -1,9 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
#if HybridCLR_Enable
using HybridCLR; using HybridCLR;
#endif
using UnityEngine; using UnityEngine;
using TEngine; using TEngine;
using System.Reflection; using System.Reflection;
@@ -21,287 +19,264 @@ namespace GameMain
/// </summary> /// </summary>
public bool NeedLoadDll => GameModule.Resource.playMode == EPlayMode.HostPlayMode || GameModule.Resource.playMode == EPlayMode.OfflinePlayMode; public bool NeedLoadDll => GameModule.Resource.playMode == EPlayMode.HostPlayMode || GameModule.Resource.playMode == EPlayMode.OfflinePlayMode;
private bool m_enableAddressable;
public override bool UseNativeDialog => true; public override bool UseNativeDialog => true;
// private int m_LoadAssetCount; private int m_LoadAssetCount;
// private int m_LoadMetadataAssetCount; private int m_LoadMetadataAssetCount;
// private int m_FailureAssetCount; private int m_FailureAssetCount;
// private int m_FailureMetadataAssetCount; private int m_FailureMetadataAssetCount;
// private bool m_LoadAssemblyComplete; private bool m_LoadAssemblyComplete;
// private bool m_LoadMetadataAssemblyComplete; private bool m_LoadMetadataAssemblyComplete;
// private bool m_LoadAssemblyWait; private bool m_LoadAssemblyWait;
// private bool m_LoadMetadataAssemblyWait; private bool m_LoadMetadataAssemblyWait;
// private System.Reflection.Assembly m_MainLogicAssembly; private Assembly m_MainLogicAssembly;
// private List<System.Reflection.Assembly> m_HotfixAssemblys; private List<Assembly> m_HotfixAssemblys;
// private IFsm<IProcedureManager> m_procedureOwner; private IFsm<IProcedureManager> m_procedureOwner;
//
// protected override void OnEnter(IFsm<IProcedureManager> procedureOwner) protected override void OnEnter(IFsm<IProcedureManager> procedureOwner)
// { {
// base.OnEnter(procedureOwner); base.OnEnter(procedureOwner);
// Log.Debug("HyBridCLR ProcedureLoadAssembly OnEnter"); Log.Debug("HyBridCLR ProcedureLoadAssembly OnEnter");
// m_procedureOwner = procedureOwner; m_procedureOwner = procedureOwner;
// m_LoadAssemblyComplete = false; m_LoadAssemblyComplete = false;
// m_HotfixAssemblys = new List<Assembly>(); m_HotfixAssemblys = new List<Assembly>();
//
// if (!NeedLoadDll || GameModule.Resource.playMode == EPlayMode.EditorSimulateMode) if (!NeedLoadDll || GameModule.Resource.playMode == EPlayMode.EditorSimulateMode)
// { {
// m_MainLogicAssembly = GetMainLogicAssembly(); m_MainLogicAssembly = GetMainLogicAssembly();
// } }
// else else
// { {
// if (SettingsUtils.HybridCLRCustomGlobalSettings.Enable) if (SettingsUtils.HybridCLRCustomGlobalSettings.Enable)
// { {
// m_LoadAssetCallbacks ??= new LoadAssetCallbacks(LoadAssetSuccess, LoadAssetFailure); foreach (string hotUpdateDllName in SettingsUtils.HybridCLRCustomGlobalSettings.HotUpdateAssemblies)
// foreach (var hotUpdateDllName in SettingsUtils.HybridCLRCustomGlobalSettings.HotUpdateAssemblies) {
// { var assetLocation = hotUpdateDllName;
// var assetPath = Utility.Path.GetRegularPath( if (!m_enableAddressable)
// Path.Combine( {
// "Assets", assetLocation = Utility.Path.GetRegularPath(
// SettingsUtils.HybridCLRCustomGlobalSettings.AssemblyTextAssetPath, Path.Combine(
// $"{hotUpdateDllName}{SettingsUtils.HybridCLRCustomGlobalSettings.AssemblyTextAssetExtension}")); "Assets",
// Log.Debug($"LoadAsset: [ {assetPath} ]"); SettingsUtils.HybridCLRCustomGlobalSettings.AssemblyTextAssetPath,
// m_LoadAssetCount++; $"{hotUpdateDllName}{SettingsUtils.HybridCLRCustomGlobalSettings.AssemblyTextAssetExtension}"));
// GameModule.Resource.LoadAssetAsync(assetPath,typeof(UnityEngine.TextAsset), m_LoadAssetCallbacks, hotUpdateDllName); }
// }
// Log.Debug($"LoadAsset: [ {assetLocation} ]");
// m_LoadAssemblyWait = true; m_LoadAssetCount++;
// } GameModule.Resource.LoadAssetAsync<TextAsset>(assetLocation,LoadAssetSuccess);
// else }
// {
// m_MainLogicAssembly = GetMainLogicAssembly(); m_LoadAssemblyWait = true;
// } }
// } else
// {
// if (SettingsUtils.HybridCLRCustomGlobalSettings.Enable) m_MainLogicAssembly = GetMainLogicAssembly();
// { }
// #if !UNITY_EDITOR }
// m_LoadMetadataAssemblyComplete = false;
// LoadMetadataForAOTAssembly(); if (SettingsUtils.HybridCLRCustomGlobalSettings.Enable)
// #else {
// m_LoadMetadataAssemblyComplete = true; #if !UNITY_EDITOR
// #endif m_LoadMetadataAssemblyComplete = false;
// } LoadMetadataForAOTAssembly();
// else #else
// { m_LoadMetadataAssemblyComplete = true;
// m_LoadMetadataAssemblyComplete = true; #endif
// } }
// else
// if (m_LoadAssetCount == 0) {
// { m_LoadMetadataAssemblyComplete = true;
// m_LoadAssemblyComplete = true; }
// }
// } if (m_LoadAssetCount == 0)
// {
// protected override void OnUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds, float realElapseSeconds) m_LoadAssemblyComplete = true;
// { }
// base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds); }
// if (!m_LoadAssemblyComplete)
// { protected override void OnUpdate(IFsm<IProcedureManager> procedureOwner, float elapseSeconds, float realElapseSeconds)
// return; {
// } base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);
// if (!m_LoadMetadataAssemblyComplete) if (!m_LoadAssemblyComplete)
// { {
// return; return;
// } }
// AllAssemblyLoadComplete(); if (!m_LoadMetadataAssemblyComplete)
// } {
// return;
// private void AllAssemblyLoadComplete() }
// { AllAssemblyLoadComplete();
// if (GameModule.Resource.playMode == EPlayMode.EditorSimulateMode) }
// {
// ChangeState<ProcedureStartGame>(m_procedureOwner); private void AllAssemblyLoadComplete()
// return; {
// } if (GameModule.Resource.playMode == EPlayMode.EditorSimulateMode)
// if (m_MainLogicAssembly == null) {
// { ChangeState<ProcedureStartGame>(m_procedureOwner);
// Log.Fatal($"Main logic assembly missing."); return;
// return; }
// } if (m_MainLogicAssembly == null)
// var appType = m_MainLogicAssembly.GetType("GameMain"); {
// if (appType == null) Log.Fatal($"Main logic assembly missing.");
// { return;
// Log.Fatal($"Main logic type 'GameMain' missing."); }
// return; var appType = m_MainLogicAssembly.GetType("GameMain");
// } if (appType == null)
// var entryMethod = appType.GetMethod("Entrance"); {
// if (entryMethod == null) Log.Fatal($"Main logic type 'GameMain' missing.");
// { return;
// Log.Fatal($"Main logic entry method 'Entrance' missing."); }
// return; var entryMethod = appType.GetMethod("Entrance");
// } if (entryMethod == null)
// object[] objects = new object[] { new object[] { m_HotfixAssemblys } }; {
// entryMethod.Invoke(appType, objects); Log.Fatal($"Main logic entry method 'Entrance' missing.");
// ChangeState<ProcedureStartGame>(m_procedureOwner); return;
// } }
// object[] objects = new object[] { new object[] { m_HotfixAssemblys } };
// private Assembly GetMainLogicAssembly() entryMethod.Invoke(appType, objects);
// { ChangeState<ProcedureStartGame>(m_procedureOwner);
// Assembly mainLogicAssembly = null; }
// foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
// { private Assembly GetMainLogicAssembly()
// if (string.Compare(SettingsUtils.HybridCLRCustomGlobalSettings.LogicMainDllName, $"{assembly.GetName().Name}.dll", {
// StringComparison.Ordinal) == 0) Assembly mainLogicAssembly = null;
// { foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
// mainLogicAssembly = assembly; {
// } if (string.Compare(SettingsUtils.HybridCLRCustomGlobalSettings.LogicMainDllName, $"{assembly.GetName().Name}.dll",
// StringComparison.Ordinal) == 0)
// foreach (var hotUpdateDllName in SettingsUtils.HybridCLRCustomGlobalSettings.HotUpdateAssemblies) {
// { mainLogicAssembly = assembly;
// if (hotUpdateDllName == $"{assembly.GetName().Name}.dll") }
// {
// m_HotfixAssemblys.Add(assembly); foreach (var hotUpdateDllName in SettingsUtils.HybridCLRCustomGlobalSettings.HotUpdateAssemblies)
// } {
// } if (hotUpdateDllName == $"{assembly.GetName().Name}.dll")
// {
// if (mainLogicAssembly != null && m_HotfixAssemblys.Count == SettingsUtils.HybridCLRCustomGlobalSettings.HotUpdateAssemblies.Count) m_HotfixAssemblys.Add(assembly);
// { }
// break; }
// }
// } if (mainLogicAssembly != null && m_HotfixAssemblys.Count == SettingsUtils.HybridCLRCustomGlobalSettings.HotUpdateAssemblies.Count)
// {
// return mainLogicAssembly; break;
// } }
// }
// /// <summary>
// /// 加载代码资源成功回调。 return mainLogicAssembly;
// /// </summary> }
// /// <param name="assetName">资源名称。</param>
// /// <param name="asset">资源实例。</param> /// <summary>
// /// <param name="duration">加载耗时。</param> /// 加载代码资源成功回调。
// /// <param name="userData">用户数据。</param> /// </summary>
// private void LoadAssetSuccess(string assetName, object asset, float duration, object userData) /// <param name="assetOperationHandle">资源操作句柄。</param>
// { private void LoadAssetSuccess(AssetOperationHandle assetOperationHandle)
// m_LoadAssetCount--; {
// Log.Debug($"LoadAssetSuccess, assetName: [ {assetName} ], duration: [ {duration} ], userData: [ {userData} ]"); m_LoadAssetCount--;
// var textAsset = asset as TextAsset; var assetName = assetOperationHandle.AssetObject.name;
// if (textAsset == null) Log.Debug($"LoadAssetSuccess, assetName: [ {assetName} ]");
// {
// Log.Warning($"Load text asset [ {assetName} ] failed."); var textAsset = assetOperationHandle.AssetObject as TextAsset;
// return; if (textAsset == null)
// } {
// Log.Warning($"Load text asset [ {assetName} ] failed.");
// try return;
// { }
// var assembly = Assembly.Load(textAsset.bytes);
// if (string.Compare(SettingsUtils.HybridCLRCustomGlobalSettings.LogicMainDllName, userData as string, StringComparison.Ordinal) == 0) try
// { {
// m_MainLogicAssembly = assembly; var assembly = Assembly.Load(textAsset.bytes);
// } if (string.Compare(SettingsUtils.HybridCLRCustomGlobalSettings.LogicMainDllName, assetName, StringComparison.Ordinal) == 0)
// m_HotfixAssemblys.Add(assembly); {
// Log.Debug($"Assembly [ {assembly.GetName().Name} ] loaded"); m_MainLogicAssembly = assembly;
// } }
// catch (Exception e) m_HotfixAssemblys.Add(assembly);
// { Log.Debug($"Assembly [ {assembly.GetName().Name} ] loaded");
// m_FailureAssetCount++; }
// Log.Fatal(e); catch (Exception e)
// throw; {
// } m_FailureAssetCount++;
// finally Log.Fatal(e);
// { throw;
// m_LoadAssemblyComplete = m_LoadAssemblyWait && 0 == m_LoadAssetCount; }
// } finally
// } {
// m_LoadAssemblyComplete = m_LoadAssemblyWait && 0 == m_LoadAssetCount;
// /// <summary> }
// /// 加载代码资源失败回调。 }
// /// </summary>
// /// <param name="assetName">资源名称。</param> /// <summary>
// /// <param name="status">加载状态。</param> /// 为Aot Assembly加载原始metadata 这个代码放Aot或者热更新都行。
// /// <param name="errorMessage">错误信息。</param> /// 一旦加载后如果AOT泛型函数对应native实现不存在则自动替换为解释模式执行。
// /// <param name="userData">自定义数据。</param> /// </summary>
// private void LoadAssetFailure(string assetName, LoadResourceStatus status, string errorMessage, object userData) public void LoadMetadataForAOTAssembly()
// { {
// Log.Fatal($"LoadAssetFailure, assetName: [ {assetName} ], status: [ {status} ], errorMessage: [ {errorMessage} ], userData: [ {userData} ]"); // 可以加载任意aot assembly的对应的dll。但要求dll必须与unity build过程中生成的裁剪后的dll一致而不能直接使用原始dll。
// m_LoadAssetCount--; // 我们在BuildProcessor_xxx里添加了处理代码这些裁剪后的dll在打包时自动被复制到 {项目目录}/HybridCLRData/AssembliesPostIl2CppStrip/{Target} 目录。
// m_FailureAssetCount++;
// } // 注意补充元数据是给AOT dll补充元数据而不是给热更新dll补充元数据。
// // 热更新dll不缺元数据不需要补充如果调用LoadMetadataForAOTAssembly会返回错误
// /// <summary> if (SettingsUtils.HybridCLRCustomGlobalSettings.AOTMetaAssemblies.Count == 0)
// /// 为Aot Assembly加载原始metadata 这个代码放Aot或者热更新都行。 {
// /// 一旦加载后如果AOT泛型函数对应native实现不存在则自动替换为解释模式执行。 m_LoadMetadataAssemblyComplete = true;
// /// </summary> return;
// public void LoadMetadataForAOTAssembly() }
// { foreach (string aotDllName in SettingsUtils.HybridCLRCustomGlobalSettings.AOTMetaAssemblies)
// // 可以加载任意aot assembly的对应的dll。但要求dll必须与unity build过程中生成的裁剪后的dll一致而不能直接使用原始dll。 {
// // 我们在BuildProcessor_xxx里添加了处理代码这些裁剪后的dll在打包时自动被复制到 {项目目录}/HybridCLRData/AssembliesPostIl2CppStrip/{Target} 目录。 var assetLocation = aotDllName;
// if (!m_enableAddressable)
// // 注意补充元数据是给AOT dll补充元数据而不是给热更新dll补充元数据。 {
// // 热更新dll不缺元数据不需要补充如果调用LoadMetadataForAOTAssembly会返回错误 assetLocation = Utility.Path.GetRegularPath(
// if (SettingsUtils.HybridCLRCustomGlobalSettings.AOTMetaAssemblies.Count == 0) Path.Combine(
// { "Assets",
// m_LoadMetadataAssemblyComplete = true; SettingsUtils.HybridCLRCustomGlobalSettings.AssemblyTextAssetPath,
// return; $"{aotDllName}{SettingsUtils.HybridCLRCustomGlobalSettings.AssemblyTextAssetExtension}"));
// } }
// m_LoadMetadataAssetCallbacks ??= new LoadAssetCallbacks(LoadMetadataAssetSuccess, LoadMetadataAssetFailure);
// foreach (var aotDllName in SettingsUtils.HybridCLRCustomGlobalSettings.AOTMetaAssemblies)
// { Log.Debug($"LoadMetadataAsset: [ {assetLocation} ]");
// var assetPath = Utility.Path.GetRegularPath( m_LoadMetadataAssetCount++;
// Path.Combine( GameModule.Resource.LoadAssetAsync<TextAsset>(assetLocation,LoadMetadataAssetSuccess);
// "Assets", }
// SettingsUtils.HybridCLRCustomGlobalSettings.AssemblyTextAssetPath, m_LoadMetadataAssemblyWait = true;
// $"{aotDllName}{SettingsUtils.HybridCLRCustomGlobalSettings.AssemblyTextAssetExtension}")); }
// Log.Debug($"LoadMetadataAsset: [ {assetPath} ]");
// m_LoadMetadataAssetCount++; /// <summary>
// GameModule.Resource.LoadAssetAsync(assetPath,typeof(UnityEngine.TextAsset), m_LoadMetadataAssetCallbacks, aotDllName); /// 加载元数据资源成功回调。
// } /// </summary>
// m_LoadMetadataAssemblyWait = true; /// <param name="assetOperationHandle">资源操作句柄。</param>
// } private unsafe void LoadMetadataAssetSuccess(AssetOperationHandle assetOperationHandle)
// {
// /// <summary> m_LoadMetadataAssetCount--;
// /// 加载元数据资源成功回调。 string assetName = assetOperationHandle.AssetObject.name;
// /// </summary> Log.Debug($"LoadMetadataAssetSuccess, assetName: [ {assetName} ]");
// /// <param name="assetName">资源名称。</param> var textAsset = assetOperationHandle.AssetObject as TextAsset;
// /// <param name="asset">资源实例。</param> if (null == textAsset)
// /// <param name="duration">加载耗时。</param> {
// /// <param name="userData">用户数据。</param> Log.Debug($"LoadMetadataAssetSuccess:Load text asset [ {assetName} ] failed.");
// private unsafe void LoadMetadataAssetSuccess(string assetName, object asset, float duration, object userData) return;
// { }
// m_LoadMetadataAssetCount--;
// Log.Debug($"LoadMetadataAssetSuccess, assetName: [ {assetName} ], duration: [ {duration} ], userData: [ {userData} ]"); try
// var textAsset = asset as TextAsset; {
// if (null == textAsset) byte[] dllBytes = textAsset.bytes;
// { fixed (byte* ptr = dllBytes)
// Log.Debug($"LoadMetadataAssetSuccess:Load text asset [ {assetName} ] failed."); {
// return; // 加载assembly对应的dll会自动为它hook。一旦Aot泛型函数的native函数不存在用解释器版本代码
// } HomologousImageMode mode = HomologousImageMode.SuperSet;
// LoadImageErrorCode err = (LoadImageErrorCode)HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly(dllBytes,mode);
// try Log.Warning($"LoadMetadataForAOTAssembly:{assetName}. mode:{mode} ret:{err}");
// { }
// byte[] dllBytes = textAsset.bytes; }
// fixed (byte* ptr = dllBytes) catch (Exception e)
// { {
// #if HybridCLR_Enable m_FailureMetadataAssetCount++;
// // 加载assembly对应的dll会自动为它hook。一旦Aot泛型函数的native函数不存在用解释器版本代码 Log.Fatal(e.Message);
// HomologousImageMode mode = HomologousImageMode.SuperSet; throw;
// LoadImageErrorCode err = (LoadImageErrorCode)HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly(dllBytes,mode); }
// Log.Warning($"LoadMetadataForAOTAssembly:{userData as string}. mode:{mode} ret:{err}"); finally
// #endif {
// } m_LoadMetadataAssemblyComplete = m_LoadMetadataAssemblyWait && 0 == m_LoadMetadataAssetCount;
// } }
// catch (Exception e) }
// {
// m_FailureMetadataAssetCount++;
// Log.Fatal(e.Message);
// throw;
// }
// finally
// {
// m_LoadMetadataAssemblyComplete = m_LoadMetadataAssemblyWait && 0 == m_LoadMetadataAssetCount;
// }
// }
//
// /// <summary>
// /// 加载元数据资源失败回调。
// /// </summary>
// /// <param name="assetName">资源名称。</param>
// /// <param name="status">加载状态。</param>
// /// <param name="errorMessage">错误信息。</param>
// /// <param name="userData">自定义数据。</param>
// private void LoadMetadataAssetFailure(string assetName, LoadResourceStatus status, string errorMessage, object userData)
// {
// Log.Warning($"LoadAssetFailure, assetName: [ {assetName} ], status: [ {status} ], errorMessage: [ {errorMessage} ], userData: [ {userData} ]");
// m_LoadMetadataAssetCount--;
// m_FailureMetadataAssetCount++;
// }
} }
} }