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