123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- using Cysharp.Threading.Tasks;
- using HybridCLR;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.Reflection;
- using UnityEngine;
- using YooAsset;
- namespace ET
- {
- public class CodeLoader: Singleton<CodeLoader>
- {
- public void Start()
- {
- AsyncLoadResAndCode().Forget();
- }
- private async UniTaskVoid AsyncLoadResAndCode()
- {
- YooAssets.EPlayMode playMode;
- if (Define.EnableCodes)
- {
- playMode = YooAssets.EPlayMode.EditorSimulateMode;
- }
- else
- {
- GlobalConfig globalConfig = Resources.Load<GlobalConfig>("GlobalConfig");
- playMode = globalConfig.PlayMode;
- }
- Log.Info($"start mode: {playMode}");
- // 启动YooAsset引擎
- await YooAssetProxy.StartYooAssetEngine(playMode);
- // Shader Warm Up
- ShaderVariantCollection shaderVariantCollection =
- (await YooAssetProxy.LoadAssetAsync<ShaderVariantCollection>(
- YooAssetProxy.GetYooAssetFormatResPath("ProjectSShaderVariant",
- YooAssetProxy.YooAssetResType.Shader)))
- .GetAssetObject<ShaderVariantCollection>();
- Stopwatch stopwatch = Stopwatch.StartNew();
- shaderVariantCollection.WarmUp();
- stopwatch.Stop();
- Log.Info($"Shader Warm Up完成, 耗时: {stopwatch.ElapsedMilliseconds}ms,shaderCount: {shaderVariantCollection.shaderCount} variantCount: {shaderVariantCollection.variantCount}");
- //加载代码入口
- if (Define.EnableCodes)
- {
- LoadLocalCode();
- }
- else
- {
- await LoadMetadataForAOT();
- await LoadHotfixCode();
- }
- }
- // 加载assembly对应的dll,会自动为它hook。一旦aot泛型函数的native函数不存在,用解释器版本代码
- private async UniTask LoadMetadataForAOT()
- {
- //AOT dll列表的配置也可以通过热更新下下来,这样增加了新的泛型就不怕了
- HotUpdateAssemblyManifest mainfest =
- (await YooAssetProxy.LoadAssetAsync<HotUpdateAssemblyManifest>("HotUpdateAssemblyManifest"))
- .GetAssetObject<HotUpdateAssemblyManifest>();
- var DLLNameList_ForABLoad = mainfest.AOTMetadataDlls;
- List<UniTask<RawFileOperation>> tasks = new List<UniTask<RawFileOperation>>();
- foreach (var aotDll in DLLNameList_ForABLoad)
- {
- tasks.Add(YooAssetProxy.GetRawFileAsync(aotDll));
- }
- RawFileOperation[] rawFileOperations = await UniTask.WhenAll(tasks);
- foreach (var task in rawFileOperations)
- {
- var ret = RuntimeApi.LoadMetadataForAOTAssembly(task.GetRawBytes(), HomologousImageMode.SuperSet);
- if (ret != LoadImageErrorCode.OK)
- {
- Log.Error($"Error occurs when loadMetadataForAOT: {ret}");
- }
- }
- }
- //热更加载 model.dll & hotfix.dll
- private async UniTask LoadHotfixCode()
- {
- Log.Info("to load model.dll & hotfix.dll.");
- var rawfile_modeldll = await YooAssetProxy.GetRawFileAsync("Model.dll");
- var rawfile_modelpdb = await YooAssetProxy.GetRawFileAsync("Model.pdb");
- var modelAssembly = Assembly.Load(rawfile_modeldll.GetRawBytes(), rawfile_modelpdb.GetRawBytes());
- var rawfile_hotfixdll = await YooAssetProxy.GetRawFileAsync("Hotfix.dll");
- var rawfile_hotfixpdb = await YooAssetProxy.GetRawFileAsync("Hotfix.pdb");
- var hotfixAssembly = Assembly.Load(rawfile_hotfixdll.GetRawBytes(), rawfile_hotfixpdb.GetRawBytes());
- var mdll = await YooAssetProxy.GetRawFileAsync("Unity.Mono.dll");
- var mAssembly = Assembly.Load(mdll.GetRawBytes());
- Dictionary<string, Type> types = AssemblyHelper.GetAssemblyTypes(typeof(Game).Assembly, typeof(Init).Assembly, modelAssembly, hotfixAssembly, mAssembly);
- EventSystem.Instance.Add(types);
- Log.Info("to call Client.Entry.");
- IStaticMethod start = new MonoStaticMethod(modelAssembly, "ET.Entry", "Start");
- start.Run();
- }
- //不使用dll,打开了EnableCode,使用Editor编辑模式
- private void LoadLocalCode()
- {
- //GlobalConfig globalConfig = Resources.Load<GlobalConfig>("GlobalConfig");
- //if (globalConfig.CodeMode != CodeMode.ClientServer)
- //{
- // throw new Exception("ENABLE_CODES mode must use ClientServer code mode!");
- //}
- Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
- Dictionary<string, Type> types = AssemblyHelper.GetAssemblyTypes(assemblies);
- EventSystem.Instance.Add(types);
- bool bStart = false;
- foreach (Assembly ass in assemblies)
- {
- string name = ass.GetName().Name;
- if (name == "Unity.Model.Codes")
- {
- bStart = true;
- IStaticMethod start = new StaticMethod(ass, "ET.Entry", "Start");
- start.Run();
- break;
- }
- }
- if (!bStart)
- {
- throw new Exception("not found Assembly: 'Unity.Model.Codes'");
- }
- }
- //编译时会检查这个方法,需保留
- public void LoadHotfix()
- {
- }
- }
- }
|