diff --git a/UnityProject/Assets/Dependencies/JEngine/Core/ILRuntimeHelper/RegisterMethodRedirection.cs b/UnityProject/Assets/Dependencies/JEngine/Core/ILRuntimeHelper/RegisterMethodRedirection.cs index e1b2a88f..724bbaac 100644 --- a/UnityProject/Assets/Dependencies/JEngine/Core/ILRuntimeHelper/RegisterMethodRedirection.cs +++ b/UnityProject/Assets/Dependencies/JEngine/Core/ILRuntimeHelper/RegisterMethodRedirection.cs @@ -659,17 +659,16 @@ private static object DoInstantiate(GameObject ins, GameObject res, AppDomain do { if (res.GetComponentsInChildren(true).Length > 0) { - ClassBindMgr.DoBind(res.GetComponentsInChildren(true).ToList()); + ClassBindMgr.DoBind(res.GetComponentsInChildren(true)); } return res; } //如果同时有adaptor和classbind,肯定是复制的,要给删了 - foreach (var t in res.GetComponentsInChildren(true)) + foreach (var cb in res.GetComponentsInChildren(true)) { - var go = t.gameObject; - var cb = go.GetComponent(); + var go = cb.gameObject; if (cb != null && go.GetComponent() != null) { UnityEngine.Object.DestroyImmediate(cb); //防止重复的ClassBind @@ -754,6 +753,7 @@ private static object DoInstantiate(GameObject ins, GameObject res, AppDomain do if (awakeMethod != null) { awakeMethod.Invoke(clrInstance, null); + LifeCycleMgr.Instance.ExecuteOnceTask(); } else { diff --git a/UnityProject/Assets/Dependencies/JEngine/Core/Manager/ClassBindMgr.cs b/UnityProject/Assets/Dependencies/JEngine/Core/Manager/ClassBindMgr.cs index 57c46ea1..bc7f3b7f 100644 --- a/UnityProject/Assets/Dependencies/JEngine/Core/Manager/ClassBindMgr.cs +++ b/UnityProject/Assets/Dependencies/JEngine/Core/Manager/ClassBindMgr.cs @@ -23,8 +23,8 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. + using UnityEngine; -using System.Threading.Tasks; using System.Collections.Generic; using UnityEngine.SceneManagement; @@ -32,7 +32,7 @@ namespace JEngine.Core { public partial class ClassBindMgr : MonoBehaviour { - public static async Task Instantiate() + public static void Instantiate() { if (_instance != null) return; @@ -42,11 +42,11 @@ public static async Task Instantiate() SceneManager.sceneLoaded += _instance.OnSceneLoaded; SceneManager.sceneUnloaded += _instance.OnSceneUnloaded; LoadedScenes.Add(SceneManager.GetActiveScene()); - await DoBind(); + DoBind(); } private static ClassBindMgr _instance; - public static readonly HashSet LoadedScenes = new HashSet() { }; + public static readonly HashSet LoadedScenes = new HashSet(); private static readonly List Cbs = new List(30); private void Awake() @@ -60,7 +60,7 @@ private void Awake() private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { LoadedScenes.Add(scene); - _ = DoBind(); + DoBind(); } private void OnSceneUnloaded(Scene scene) @@ -80,7 +80,7 @@ private void OnDestroy() } } - public static async Task DoBind(List cbs) + public static void DoBind(ICollection cbs) { foreach (var cb in cbs) { @@ -106,10 +106,13 @@ public static async Task DoBind(List cbs) continue; } - await cb.SetVal(data); + cb.SetVal(data); } } + //确保任务全执行了 + LifeCycleMgr.Instance.ExecuteOnceTask(); + //激活 foreach (var cb in cbs) { @@ -120,22 +123,47 @@ public static async Task DoBind(List cbs) continue; } - await cb.Active(data); + cb.Active(data); } } + + //确保任务全执行了 + LifeCycleMgr.Instance.ExecuteOnceTask(); } - public static async Task DoBind(ClassBind cb) + private static readonly List Temp = new List(1); + + public static void DoBind(ClassBind cb) { if (Cbs.Contains(cb)) return; - await DoBind(new List { cb }); + Cbs.Add(cb); + if (Temp.Count == 1) + { + if (Temp[0] == null) + { + Temp[0] = cb; + DoBind(Temp); + } + else + { + DoBind(new List(1) + { + cb + }); + } + } + else + { + Temp.Add(cb); + DoBind(Temp); + } } - public static async Task DoBind() + public static void DoBind() { var c = Tools.FindObjectsOfTypeAll(); Cbs.AddRange(c); - await DoBind(c); + DoBind(c); } } } \ No newline at end of file diff --git a/UnityProject/Assets/Dependencies/JEngine/Core/Manager/LifeCycleMgr.cs b/UnityProject/Assets/Dependencies/JEngine/Core/Manager/LifeCycleMgr.cs index 30e20e24..5f253eb3 100644 --- a/UnityProject/Assets/Dependencies/JEngine/Core/Manager/LifeCycleMgr.cs +++ b/UnityProject/Assets/Dependencies/JEngine/Core/Manager/LifeCycleMgr.cs @@ -576,6 +576,22 @@ private bool IgnoreWithInInstances(in LifeCycleItem* item) /// remove obj from instances /// private Predicate RemoveInstanceIfContainsPredicate => RemoveInstanceIfContains; + + /// + /// execute once task + /// + private bool _onceTaskExecuting; + + /// + /// 处理只调用一次的任务 + /// + public void ExecuteOnceTask() + { + if (_onceTaskExecuting) return; + _onceTaskExecuting = true; + ExecuteItems(_onceTaskItems); + _onceTaskExecuting = false; + } /// /// unity周期 @@ -596,7 +612,7 @@ private void FixedUpdate() private void Update() { //处理只调用一次的任务 - ExecuteItems(_onceTaskItems); + ExecuteOnceTask(); //处理update //确保本帧没处理过这些对象 //调用update diff --git a/UnityProject/Assets/Dependencies/JEngine/Core/Util/ClassBind.cs b/UnityProject/Assets/Dependencies/JEngine/Core/Util/ClassBind.cs index 5ec3f4bb..1cf38a6d 100644 --- a/UnityProject/Assets/Dependencies/JEngine/Core/Util/ClassBind.cs +++ b/UnityProject/Assets/Dependencies/JEngine/Core/Util/ClassBind.cs @@ -5,7 +5,6 @@ using System.Reflection; using ILRuntime.CLR.Utils; using ILRuntime.Reflection; -using System.Threading.Tasks; using JEngine.Core.DO_NOT_USE; using ILRuntime.CLR.TypeSystem; using UnityEngine.Serialization; @@ -161,7 +160,7 @@ t.BaseType is ILRuntimeWrapperType wrapperType /// Set value /// /// - public async Task SetVal(ClassData classData) + public void SetVal(ClassData classData) { string classType = $"{(string.IsNullOrEmpty(classData.classNamespace) ? String.Empty : $"{classData.classNamespace}.")}{classData.className}"; @@ -169,7 +168,33 @@ public async Task SetVal(ClassData classData) var clrInstance = classData.ClrInstance; //绑定数据 classData.BoundData = false; - var fields = classData.fields.ToArray(); + var fields = classData.fields; + + void BindVal(ClassField field, object obj) + { + try + { + var fi = t.GetField(field.fieldName, AllBindingFlags); + if (fi == null) fi = t.BaseType?.GetField(field.fieldName, AllBindingFlags); + if (fi != null) + { + fi.SetValue(clrInstance.ILInstance, obj); + } + else + { + var pi = t.GetProperty(field.fieldName, AllBindingFlags); + if (pi == null) pi = t.BaseType?.GetProperty(field.fieldName, AllBindingFlags); + if (pi == null) + throw new NullReferenceException(); + pi.SetValue(clrInstance.ILInstance, obj); + } + } + catch (Exception e) + { + Log.PrintError( + $"自动绑定{name}出错:{classType}.{field.fieldName}赋值出错:{e.Message},已跳过"); + } + } foreach (ClassField field in fields) { @@ -375,21 +400,28 @@ void SetField(Type fieldType) } else if (field.fieldType == ClassField.FieldType.HotUpdateResource) { - //Unity 编辑器下AssetDatabase读取图片会变texture2d导致无法给sprite赋值 - var fieldType = t.GetField(field.fieldName, AllBindingFlags)?.FieldType ?? - (t.BaseType?.GetField(field.fieldName, AllBindingFlags)?.FieldType ?? - (t.GetProperty(field.fieldName, AllBindingFlags)?.PropertyType ?? - t.BaseType?.GetProperty(field.fieldName, AllBindingFlags)?.PropertyType)); - fieldType = fieldType is ILRuntimeWrapperType wrapperType ? wrapperType.RealType : fieldType; - var o = await AssetMgr.LoadAsync(field.value, fieldType); - if (fieldType == typeof(Sprite) && o is Texture2D tx) + LifeCycleMgr.Instance.AddTask(async () => { - o = Sprite.Create(tx, new Rect(0, 0, tx.width, tx.height), new Vector2(0.5f, 0.5f), - 100.0f); - } + //Unity 编辑器下AssetDatabase读取图片会变texture2d导致无法给sprite赋值 + var fieldType = t.GetField(field.fieldName, AllBindingFlags)?.FieldType ?? + (t.BaseType?.GetField(field.fieldName, AllBindingFlags)?.FieldType ?? + (t.GetProperty(field.fieldName, AllBindingFlags)?.PropertyType ?? + t.BaseType?.GetProperty(field.fieldName, AllBindingFlags)?.PropertyType)); + fieldType = fieldType is ILRuntimeWrapperType wrapperType + ? wrapperType.RealType + : fieldType; + var o = await AssetMgr.LoadAsync(field.value, fieldType); + if (fieldType == typeof(Sprite) && o is Texture2D tx) + { + o = Sprite.Create(tx, new Rect(0, 0, tx.width, tx.height), new Vector2(0.5f, 0.5f), + 100.0f); + } - obj = o; + obj = o; + BindVal(field,obj); + }); classData.BoundData = true; + continue; } } catch (Exception except) @@ -401,41 +433,7 @@ void SetField(Type fieldType) //如果有数据再绑定 if (classData.BoundData) { - void BindVal(MemberInfo mi) - { - try - { - switch (mi) - { - case null: - throw new NullReferenceException(); - case FieldInfo info: - info.SetValue(clrInstance.ILInstance, obj); - break; - case PropertyInfo inf: - inf.SetValue(clrInstance.ILInstance, obj); - break; - } - } - catch (Exception e) - { - Log.PrintError( - $"自动绑定{name}出错:{classType}.{field.fieldName}赋值出错:{e.Message},已跳过"); - } - } - - var fi = t.GetField(field.fieldName, AllBindingFlags); - if (fi == null) fi = t.BaseType?.GetField(field.fieldName, AllBindingFlags); - if (fi != null) - { - BindVal(fi); - } - else - { - var pi = t.GetProperty(field.fieldName, AllBindingFlags); - if (pi == null) pi = t.BaseType?.GetProperty(field.fieldName, AllBindingFlags); - BindVal(pi); - } + BindVal(field, obj); } } } @@ -444,7 +442,7 @@ void BindVal(MemberInfo mi) /// Active /// /// - public async Task Active(ClassData classData) + public void Active(ClassData classData) { string classType = $"{(string.IsNullOrEmpty(classData.classNamespace) ? String.Empty : $"{classData.classNamespace}.")}{classData.className}"; @@ -494,18 +492,17 @@ public async Task Active(ClassData classData) } } - TaskCompletionSource tcs = new TaskCompletionSource(); LifeCycleMgr.Instance.AddTask(() => { - ((MonoBehaviour)clrInstance).enabled = true; classData.Activated = true; - tcs.SetResult(true); + Remove(); }); - await tcs.Task; } - - Remove(); + else + { + Remove(); + } } /// diff --git a/UnityProject/Assets/Dependencies/JEngine/Core/Util/InitJEngine.cs b/UnityProject/Assets/Dependencies/JEngine/Core/Util/InitJEngine.cs index 839ea05f..f4a499a1 100644 --- a/UnityProject/Assets/Dependencies/JEngine/Core/Util/InitJEngine.cs +++ b/UnityProject/Assets/Dependencies/JEngine/Core/Util/InitJEngine.cs @@ -81,7 +81,7 @@ public async Task LoadHotUpdateCallback() //调用SetupGame周期 Tools.InvokeHotMethod(HotMainType, SetupGameMethod); //初始化ClassBind - await ClassBindMgr.Instantiate(); + ClassBindMgr.Instantiate(); //调用RunGame周期 Tools.InvokeHotMethod(HotMainType, RunGameMethod); //调用在主工程的热更代码加载完毕后的周期 diff --git a/UnityProject/Assets/HotUpdateResources/Main/Common/Prefab/Prefab.txt b/UnityProject/Assets/HotUpdateResources/Main/Common/Prefab/Prefab.txt deleted file mode 100644 index 59a10468..00000000 --- a/UnityProject/Assets/HotUpdateResources/Main/Common/Prefab/Prefab.txt +++ /dev/null @@ -1,2 +0,0 @@ -Drop .prefab here. (Prefabs) - diff --git a/UnityProject/Assets/HotUpdateResources/Main/Common/Prefab/test.prefab b/UnityProject/Assets/HotUpdateResources/Main/Common/Prefab/test.prefab new file mode 100644 index 00000000..395891a4 --- /dev/null +++ b/UnityProject/Assets/HotUpdateResources/Main/Common/Prefab/test.prefab @@ -0,0 +1,51 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &5371248624903576641 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5371248624903576647} + - component: {fileID: 5371248624903576640} + m_Layer: 0 + m_Name: test + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &5371248624903576647 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5371248624903576641} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 368, y: 368, z: 368} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &5371248624903576640 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5371248624903576641} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 136c8f5360d9a4f13a42b9b074fc8038, type: 3} + m_Name: + m_EditorClassIdentifier: + scriptsToBind: + - classNamespace: HotUpdateScripts + className: Test + activeAfter: 1 + fields: + array: [] diff --git a/UnityProject/Assets/HotUpdateResources/Main/Common/Prefab/Prefab.txt.meta b/UnityProject/Assets/HotUpdateResources/Main/Common/Prefab/test.prefab.meta similarity index 62% rename from UnityProject/Assets/HotUpdateResources/Main/Common/Prefab/Prefab.txt.meta rename to UnityProject/Assets/HotUpdateResources/Main/Common/Prefab/test.prefab.meta index aa46ae03..be8a7113 100644 --- a/UnityProject/Assets/HotUpdateResources/Main/Common/Prefab/Prefab.txt.meta +++ b/UnityProject/Assets/HotUpdateResources/Main/Common/Prefab/test.prefab.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 97a6de22af8554e5a9f63093533cb601 -TextScriptImporter: +guid: 0c78a727b437447c2ba30f069ab6e16e +PrefabImporter: externalObjects: {} userData: assetBundleName: diff --git a/UnityProject/Assets/HotUpdateResources/Main/Dll/Hidden~/HotUpdateScripts.dll b/UnityProject/Assets/HotUpdateResources/Main/Dll/Hidden~/HotUpdateScripts.dll index f85e000b..03ab93a4 100644 Binary files a/UnityProject/Assets/HotUpdateResources/Main/Dll/Hidden~/HotUpdateScripts.dll and b/UnityProject/Assets/HotUpdateResources/Main/Dll/Hidden~/HotUpdateScripts.dll differ diff --git a/UnityProject/Assets/HotUpdateResources/Main/Dll/Hidden~/HotUpdateScripts.pdb b/UnityProject/Assets/HotUpdateResources/Main/Dll/Hidden~/HotUpdateScripts.pdb index be262f3a..e7b47d9e 100644 Binary files a/UnityProject/Assets/HotUpdateResources/Main/Dll/Hidden~/HotUpdateScripts.pdb and b/UnityProject/Assets/HotUpdateResources/Main/Dll/Hidden~/HotUpdateScripts.pdb differ diff --git a/UnityProject/Assets/HotUpdateResources/Main/Dll/HotUpdateScripts.bytes b/UnityProject/Assets/HotUpdateResources/Main/Dll/HotUpdateScripts.bytes index f3f2ce51..459055a4 100644 Binary files a/UnityProject/Assets/HotUpdateResources/Main/Dll/HotUpdateScripts.bytes and b/UnityProject/Assets/HotUpdateResources/Main/Dll/HotUpdateScripts.bytes differ diff --git a/UnityProject/Assets/HotUpdateResources/Main/Dll/HotUpdateScripts.pdb.bytes b/UnityProject/Assets/HotUpdateResources/Main/Dll/HotUpdateScripts.pdb.bytes index be262f3a..e7b47d9e 100644 Binary files a/UnityProject/Assets/HotUpdateResources/Main/Dll/HotUpdateScripts.pdb.bytes and b/UnityProject/Assets/HotUpdateResources/Main/Dll/HotUpdateScripts.pdb.bytes differ diff --git a/UnityProject/HotUpdateScripts/JEngine/Core/JBehaviour.cs b/UnityProject/HotUpdateScripts/JEngine/Core/JBehaviour.cs index 31dba6be..da3ace15 100644 --- a/UnityProject/HotUpdateScripts/JEngine/Core/JBehaviour.cs +++ b/UnityProject/HotUpdateScripts/JEngine/Core/JBehaviour.cs @@ -221,7 +221,7 @@ private static string AddClassBind(GameObject gameObject, bool activeAfter, Type activeAfter = activeAfter, }; var id = ((JBehaviour)cb.AddClass(cd))._instanceID; - _ = cb.Active(cd); + cb.BindSelf(); return id; } diff --git a/package.json b/package.json index 51c4f51d..c20f7789 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.jasonxudeveloper.jengine", - "version": "0.8.0f1", + "version": "0.8.0f2", "displayName": "JEngine", "description": "The solution that allows unity games update in runtime.", "license": "MIT",