diff --git a/README.md b/README.md
index 9fbe2159..5d612eda 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@
-
+ [README_zh_cn.md](README_zh_cn.md)
Documentation »
@@ -31,7 +31,7 @@
-# JENGINE v0.8.0f5
+# JENGINE v0.8.0f6
**JEngine is an out-of-the-box framework designed for Unity developers. It encapsulates powerful functions. Beginners can also get started quickly and easily create games that can be updated in runtime.**
diff --git a/README_zh_cn.md b/README_zh_cn.md
index 635d84f6..2e1c2a6c 100644
--- a/README_zh_cn.md
+++ b/README_zh_cn.md
@@ -30,7 +30,7 @@
-# JENGINE v0.8.0f5
+# JENGINE v0.8.0f6
JEngine是针对Unity开发者设计的**开箱即用**的框架,封装了强大的功能,小白也能**快速上手**,**轻松制作**可以**热更新的游戏**
diff --git a/UnityProject/Assets/Dependencies/JEngine/Core/Manager/AssetMgr.cs b/UnityProject/Assets/Dependencies/JEngine/Core/Manager/AssetMgr.cs
index cbd5d838..e715283d 100644
--- a/UnityProject/Assets/Dependencies/JEngine/Core/Manager/AssetMgr.cs
+++ b/UnityProject/Assets/Dependencies/JEngine/Core/Manager/AssetMgr.cs
@@ -357,8 +357,10 @@ public static void LoadScene(string path, bool additive = false, string package
{
SceneOperationHandle handle = GetPackage(package)
.LoadSceneAsync(path, additive ? LoadSceneMode.Additive : LoadSceneMode.Single);
- handle.Task.Wait();
- RemoveUnusedAssets();
+ handle.Task.ContinueWith((_, __) => RemoveUnusedAssets()
+ , null);
+ _ = handle.Task;
+ Log.PrintWarning("LoadScene will not wait for scene loading complete. Use LoadSceneAsync instead.");
}
public static async Task LoadSceneAsync(string path, bool additive = false, string package = null)
diff --git a/UnityProject/Assets/Dependencies/JEngine/Core/Manager/LifeCycleMgr.cs b/UnityProject/Assets/Dependencies/JEngine/Core/Manager/LifeCycleMgr.cs
index 5f253eb3..5d8fb7e3 100644
--- a/UnityProject/Assets/Dependencies/JEngine/Core/Manager/LifeCycleMgr.cs
+++ b/UnityProject/Assets/Dependencies/JEngine/Core/Manager/LifeCycleMgr.cs
@@ -26,6 +26,8 @@
using System;
using UnityEngine;
+using System.Threading;
+using Unity.Collections;
using System.Reflection;
using System.Collections.Generic;
using Unity.Collections.LowLevel.Unsafe;
@@ -53,7 +55,24 @@ private struct LifeCycleItem
public static LifeCycleItem* Create(in void* instancePtr, in ulong gcAddr, Action action, Func cond)
{
- LifeCycleItem* item = (LifeCycleItem*)Pool.Allocate(sizeof(LifeCycleItem));
+ byte* ptr = UsageList;
+ LifeCycleItem* item = ItemList;
+ byte* max = ptr + MaxSize;
+ while (ptr < max)
+ {
+ if (*ptr == 0)
+ {
+ *ptr = 1;
+ break;
+ }
+
+ ptr++;
+ item++;
+ }
+
+ if (ptr == max)
+ throw new Exception("LifeCycleMgr: LifeCycleItem is full!");
+
item->InstancePtr = (IntPtr)instancePtr;
item->_instanceGCHandleAddress = gcAddr;
item->_actionPtr = UnsafeUtility.PinGCObjectAndGetAddress(action, out item->_actionGCHandleAddress);
@@ -72,7 +91,7 @@ public void Dispose()
UnsafeUtility.ReleaseGCObject(_condGCHandleAddress);
fixed (LifeCycleItem* ptr = &this)
{
- Pool.Free((byte*)ptr);
+ UsageList[ptr - ItemList] = 0;
}
}
}
@@ -100,12 +119,27 @@ public static void Initialize()
/// 单例
///
public static LifeCycleMgr Instance => _instance;
-
+
+ ///
+ /// 非托管内存
+ ///
+ private static readonly LifeCycleItem* ItemList =
+ (LifeCycleItem*)UnsafeUtility.Malloc(sizeof(LifeCycleItem) * MaxSize, 4, Allocator.Persistent);
+
+ ///
+ /// 使用列表
+ ///
+ private static readonly byte* UsageList = (byte*)UnsafeUtility.Malloc(MaxSize, 4, Allocator.Persistent);
+
+ ///
+ /// 最大数量
+ ///
+ private const int MaxSize = 10000;
+
///
- /// 非托管内存池
- /// 最多同时10240个被占用的任务(480KB内存)
+ /// 锁
///
- private static readonly UnmanagedMemoryPool Pool = new UnmanagedMemoryPool(sizeof(LifeCycleItem) * 10240);
+ private static SpinLock _createLock;
///
/// unity周期
@@ -120,6 +154,19 @@ private void Awake()
_ignoreWithoutInInstancesFunc = IgnoreWithoutInInstances;
_ignoreWithInInstancesFunc = IgnoreWithInInstances;
+ GC.AddMemoryPressure(sizeof(LifeCycleItem) * MaxSize);
+ GC.AddMemoryPressure(MaxSize);
+ }
+
+ ///
+ /// 清理非托管
+ ///
+ private void OnDestroy()
+ {
+ UnsafeUtility.Free(ItemList, Allocator.Persistent);
+ UnsafeUtility.Free(UsageList, Allocator.Persistent);
+ GC.RemoveMemoryPressure(sizeof(LifeCycleItem) * MaxSize);
+ GC.RemoveMemoryPressure(MaxSize);
}
///
@@ -175,7 +222,20 @@ private void Awake()
///
///
private static IntPtr GetLifeCycleItem(in void* addr, in ulong gcAddr, Action action,
- Func cond) => (IntPtr)LifeCycleItem.Create(in addr, in gcAddr, action, cond);
+ Func cond)
+ {
+ bool gotLock = false;
+ try
+ {
+ _createLock.Enter(ref gotLock);
+ return
+ (IntPtr)LifeCycleItem.Create(in addr, in gcAddr, action, cond);
+ }
+ finally
+ {
+ if (gotLock) _createLock.Exit();
+ }
+ }
///
/// Add awake task
@@ -576,12 +636,12 @@ private bool IgnoreWithInInstances(in LifeCycleItem* item)
/// remove obj from instances
///
private Predicate RemoveInstanceIfContainsPredicate => RemoveInstanceIfContains;
-
+
///
/// execute once task
///
private bool _onceTaskExecuting;
-
+
///
/// 处理只调用一次的任务
///
diff --git a/UnityProject/Assets/Dependencies/JEngine/Core/Util/UnmanagedMemoryPool.cs b/UnityProject/Assets/Dependencies/JEngine/Core/Util/UnmanagedMemoryPool.cs
deleted file mode 100644
index eecd2916..00000000
--- a/UnityProject/Assets/Dependencies/JEngine/Core/Util/UnmanagedMemoryPool.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-//
-// UnmanagedMemoryPool.cs
-//
-// Author:
-// JasonXuDeveloper(傑)
-//
-// Copyright (c) 2020 JEngine
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// 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 System;
-using Unity.Collections;
-using Unity.Collections.LowLevel.Unsafe;
-
-namespace JEngine.Core
-{
- ///
- /// Memory pool that returns unmanaged memory
- ///
- public unsafe class UnmanagedMemoryPool
- {
- ///
- /// Allocated unmanaged memory
- /// Structure:
- /// Chain:
- /// 1 byte of whether or not hold in use -> 8 bytes of length of n -> n
- /// ---- ---- ---- ---- ---- ----
- /// | 1 | 8 | n1 | 1 | 8 | n2 | ......
- /// ---- ---- ---- ---- ---- ----
- ///
- private readonly byte* _memory;
-
- ///
- /// Allocated size
- ///
- private readonly long _memoryLength;
-
- ///
- /// Create a memory pool
- ///
- ///
- public UnmanagedMemoryPool(long size = 1024)
- {
- _memory = (byte*)UnsafeUtility.Malloc(size, 1, Allocator.Persistent);
- //ensure 0
- UnsafeUtility.MemClear(_memory, size);
- *_memory = 0;
- _memoryLength = size;
- GC.AddMemoryPressure(size);
- }
-
- ///
- /// Destroy the memory pool
- ///
- ~UnmanagedMemoryPool()
- {
- Destroy();
- }
-
- ///
- /// Destroy the current memory pool
- ///
- public void Destroy()
- {
- UnsafeUtility.Free(_memory, Allocator.Persistent);
- GC.RemoveMemoryPressure(_memoryLength);
- }
-
- ///
- /// Allocate memory
- ///
- ///
- ///
- ///
- public byte* Allocate(long size)
- {
- //look for valid blocks
- byte* ptr = _memory;
- while (true)
- {
- //ensure it is not out of boundary
- if (ptr - _memory > _memoryLength || ptr + 9 - _memory > _memoryLength)
- {
- //no enough allocated memory
- throw new OutOfMemoryException("memory pool out of memory");
- }
-
- if (*ptr == 0)
- {
- //if the block is not in use, check if the size is enough
- long len = *(long*)(ptr + 1);
- byte* next = ptr + 9 + len;
- //ensure won't cross the boundary
- if (next > _memory + _memoryLength)
- {
- //no enough allocated memory
- throw new OutOfMemoryException("memory pool out of memory");
- }
- //ensure not intersecting with the next block
- if (*next == 0)
- {
- if (len == 0 || len >= size)//0 -> uninitialized
- {
- //if the size is enough, mark the block as in use
- *ptr = 1;
- //mark size
- *(long*)(ptr + 1) = size;
- return ptr + 9;
- }
- }
- }
-
- //if the block is in use, or the size is not enough, move to the next block
- ptr += *(long*)(ptr + 1) + 9;
- }
- }
-
- ///
- /// Free allocated memory
- ///
- ///
- ///
- public void Free(byte* ptr)
- {
- //ensure p is inside of the memory pool
- if (ptr < _memory || ptr >= _memory + _memoryLength)
- {
- throw new ArgumentException("ptr is not inside of the memory pool");
- }
- //get length of p
- long len = *(long*)(ptr - 8);
- //clear
- UnsafeUtility.MemClear(ptr, len);
- //mark the block as not in use
- *(ptr - 9) = 0;
- }
- }
-}
\ No newline at end of file
diff --git a/UnityProject/Assets/Dependencies/JEngine/Core/Util/UnmanagedMemoryPool.cs.meta b/UnityProject/Assets/Dependencies/JEngine/Core/Util/UnmanagedMemoryPool.cs.meta
deleted file mode 100644
index 2984b230..00000000
--- a/UnityProject/Assets/Dependencies/JEngine/Core/Util/UnmanagedMemoryPool.cs.meta
+++ /dev/null
@@ -1,3 +0,0 @@
-fileFormatVersion: 2
-guid: aeb2d35ff5794f7994756b4bf567c280
-timeCreated: 1673827624
\ No newline at end of file
diff --git a/package.json b/package.json
index c81745f4..f3c7cf2c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "com.jasonxudeveloper.jengine",
- "version": "0.8.0f5",
+ "version": "0.8.0f6",
"displayName": "JEngine",
"description": "The solution that allows unity games update in runtime.",
"license": "MIT",