public void Release(T element) { m_LastUsingTime = MDebug.GetMillisecondsSinceStartup(); #if GF_DEBUG MDebug.Assert(element != null, "Pool", $"element == null"); bool removedFromUsing = false; for (int iObject = 0; iObject < m_Using.Count; iObject++) { UsingObject usingObject = m_Using[iObject]; if (usingObject.Obj.Equals(element)) { removedFromUsing = true; m_Using.RemoveAt(iObject); break; } } if (!removedFromUsing) { MDebug.LogError("Pool" , $"Object({element.ToString()}) not alloc by ObjectPool<{typeof(T).FullName}>!"); } #endif element.OnRelease(); m_Stack.Push(element); m_UsingCount--; }
public T Alloc() { m_LastUsingTime = MDebug.GetMillisecondsSinceStartup(); T element = default; if (m_Stack.Count == 0) { #if GF_DEBUG CheckMemoryLeak(); #endif element = new T(); element.OnAlloc(); m_AllCount++; } else { element = m_Stack.Pop(); } #if GF_DEBUG m_Using.Add(new UsingObject(element)); #endif m_UsingCount++; return(element); }
private static int GetMillisecondsSinceStartup(IntPtr luaState) { int top = Lua.lua_gettop(luaState); if (top != 0) { return(Lua.luaL_error(luaState, "top != 0")); } Lua.lua_pushint64(luaState, MDebug.GetMillisecondsSinceStartup()); return(1); }
public static void ResetBundleName(Dictionary <string, string> assetToBundle) { long elapsedMS = MDebug.GetMillisecondsSinceStartup(); string[] assetPaths = AssetDatabase.GetAllAssetPaths(); int modifyAssetCount = 0; for (int iAsset = 0; iAsset < assetPaths.Length; iAsset++) { if (iAsset % 100 == 0 && EditorUtility.DisplayCancelableProgressBar("AssetBundle" , $"Reset bundleName {iAsset}/{assetPaths.Length}. Modified {modifyAssetCount}", iAsset / (float)assetPaths.Length)) { throw new CancelException(); } string iterAssetPath = assetPaths[iAsset]; // 没有meta文件的不需要设置bundleName if (!File.Exists(iterAssetPath + ".meta")) { continue; } AssetImporter iterAssetImporter = AssetImporter.GetAtPath(iterAssetPath); if (!assetToBundle.TryGetValue(iterAssetPath, out string bundleName)) { bundleName = string.Empty; } if (iterAssetImporter.assetBundleName != bundleName) { modifyAssetCount++; iterAssetImporter.assetBundleName = bundleName; EditorUtility.SetDirty(iterAssetImporter); } //1000间隔,执行一次IO操作,提高性能,如果中断可能会出现问题,比如BuildPipling获取不到一些已经赋值的BuildName if (iAsset % 1000 == 0) { AssetDatabase.SaveAssets(); Resources.UnloadUnusedAssets(); } } EditorUtility.ClearProgressBar(); AssetDatabase.SaveAssets(); Resources.UnloadUnusedAssets(); AssetDatabase.Refresh(); elapsedMS = MDebug.GetMillisecondsSinceStartup() - elapsedMS; MDebug.Log("AssetBundle" , $"Modify bundleName count ({modifyAssetCount}) elapsed {MDebug.FormatMilliseconds(elapsedMS)}"); }
public void CheckMemoryLeak() { long currentTime = MDebug.GetMillisecondsSinceStartup(); for (int iObject = 0; iObject < m_Using.Count; iObject++) { UsingObject usingObject = m_Using[iObject]; if (currentTime - usingObject.WhenBeUse > m_MemoryLeakMilliseconds) { MDebug.LogWarning("Pool" , $"Object in ObjectPool<{typeof(T).FullName}> be used {(currentTime - usingObject.WhenBeUse) * 0.001:F2} seconds ago, maybe memory leak!\n({usingObject.ToString()})"); } } }
public override string ToString() { System.Text.StringBuilder stringBuilder = StringUtility.AllocStringBuilder(); stringBuilder.Append($"ObjectPool<{typeof(T).FullName}> alloc {m_AllCount} objects. ") .Append($"{m_UsingCount} obejcts being used"); #if GF_DEBUG long currentTime = MDebug.GetMillisecondsSinceStartup(); for (int iObject = 0; iObject < m_Using.Count; iObject++) { UsingObject usingObject = m_Using[iObject]; float beUsedTime = (currentTime - usingObject.WhenBeUse) * 0.001f; stringBuilder.Append($"\nObject be used {beUsedTime:F2} seconds. ({usingObject.ToString()})"); } #endif return(StringUtility.ReleaseStringBuilder(stringBuilder)); }
public override void OnLateUpdate(float deltaTime) { long currentTime = MDebug.GetMillisecondsSinceStartup(); for (int iPool = m_StrongObjectPools.Count - 1; iPool >= 0; iPool--) { IObjectPool iterPool = m_StrongObjectPools[iPool]; if (iterPool.GetUsingCount() == 0 && currentTime - iterPool.GetLastUsingTime() > AUTO_GC_MILLISECONDS) { MDebug.Log("Pool" , $"ObjectPool<{iterPool.GetObjectType().FullName}> will be GC."); m_StrongObjectPools.RemoveAt(iPool); m_WeakObjectPools.Remove(TypeToKey(iterPool.GetObjectType())); } } }
private void EditorUpdate() { if (!CheckAlive()) { return; } if (Application.isPlaying) { return; } // 把自己胡乱拖动, 让编辑器维持更新 transform.position = UnityEngine.Random.insideUnitSphere; // 编辑器下Update的回调 // 在编辑器下 EditorApplication.update 的更新间隔与Time.deltaTime返回的时间不一致 long editModeMilliseconds = MDebug.GetMillisecondsSinceStartup(); if (m_LastEditModeMilliseconds == NOTSET_EDITMODE_MILLISECONDS) { m_LastEditModeMilliseconds = editModeMilliseconds; } else { // 0.001: milliseconds to seconds float deltaTime = (editModeMilliseconds - m_LastEditModeMilliseconds) * 0.001f; // 60: 60FPS if (deltaTime >= 1.0f / _EditModeUpdateRate) { float time = editModeMilliseconds * 0.001f; m_LastEditModeMilliseconds = editModeMilliseconds; for (int iTab = 0; iTab < m_Tabs.Count; iTab++) { m_Tabs[iTab].OnEditorUpdate(time, deltaTime); } } } }
public UsingObject(T element) { Obj = element; WhenBeUse = MDebug.GetMillisecondsSinceStartup(); }