mirror of
https://github.com/DCFApixels/DragonECS-Unity.git
synced 2025-09-17 17:34:34 +08:00
stash
This commit is contained in:
parent
2642510c89
commit
f068c22661
8
src/DebugUtils/UnityDebugService.meta
Normal file
8
src/DebugUtils/UnityDebugService.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69f2abf8b8744c840b2da7f8988b3f8d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using DCFApixels.DragonECS.Unity.Internal;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Unity.Profiling;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
#region [InitializeOnLoad]
|
||||
@ -12,14 +15,12 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
// Методы юнитевского Debug и ProfilerMarker потоко безопасны
|
||||
public partial class UnityDebugService : DebugService
|
||||
{
|
||||
private ProfilerMarker[] _profilerMarkers = new ProfilerMarker[64];
|
||||
|
||||
static UnityDebugService()
|
||||
{
|
||||
Activate();
|
||||
@ -29,6 +30,27 @@ namespace DCFApixels.DragonECS
|
||||
if (Instance.GetType() == typeof(UnityDebugService)) { return; }
|
||||
Set<UnityDebugService>();
|
||||
}
|
||||
protected override void OnEnableBaseService(DebugService oldService)
|
||||
{
|
||||
EditorGUI.hyperLinkClicked -= EditorGUI_hyperLinkClicked;
|
||||
EditorGUI.hyperLinkClicked += EditorGUI_hyperLinkClicked;
|
||||
Application.logMessageReceived -= Application_logMessageReceived;
|
||||
Application.logMessageReceived += Application_logMessageReceived;
|
||||
}
|
||||
protected override void OnDisableBaseService(DebugService nextService)
|
||||
{
|
||||
Application.logMessageReceived -= Application_logMessageReceived;
|
||||
EditorGUI.hyperLinkClicked -= EditorGUI_hyperLinkClicked;
|
||||
}
|
||||
private void EditorGUI_hyperLinkClicked(EditorWindow editor, HyperLinkClickedEventArgs args)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
private void Application_logMessageReceived(string logString, string stackTrace, LogType type)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected override DebugService CreateThreadInstance()
|
||||
{
|
119
src/DebugUtils/UnityDebugService/UnityDebugServiceStorage.cs
Normal file
119
src/DebugUtils/UnityDebugService/UnityDebugServiceStorage.cs
Normal file
@ -0,0 +1,119 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS.Unity.Internal
|
||||
{
|
||||
internal class UnityDebugServiceStorage : ScriptableSingleton<UnityDebugServiceStorage>
|
||||
{
|
||||
private static readonly MethodInfo _getLogsCountMethod;
|
||||
public static readonly bool IsSupportAutoLingks;
|
||||
static UnityDebugServiceStorage()
|
||||
{
|
||||
var logEntriesType = typeof(EditorWindow).Assembly.GetType("UnityEditor.LogEntries");
|
||||
if (logEntriesType != null)
|
||||
{
|
||||
_getLogsCountMethod = logEntriesType.GetMethod("GetCount", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
}
|
||||
IsSupportAutoLingks = _getLogsCountMethod != null;
|
||||
|
||||
EditorGUI.hyperLinkClicked -= EditorGUI_hyperLinkClicked;
|
||||
Application.logMessageReceived -= Application_logMessageReceived;
|
||||
_consoleLogCounter = -1;
|
||||
if (IsSupportAutoLingks)
|
||||
{
|
||||
EditorGUI.hyperLinkClicked += EditorGUI_hyperLinkClicked;
|
||||
Application.logMessageReceived += Application_logMessageReceived;
|
||||
_consoleLogCounter = GetConsoleLogCount();
|
||||
}
|
||||
}
|
||||
public UnityDebugServiceStorage() { }
|
||||
|
||||
private const int IntervalChecksTicksThreshold = 100;
|
||||
private static int _consoleLogCounter;
|
||||
private static int _intervalChecksTicks = 0;
|
||||
private static StructList<string> _recycledIndexes;
|
||||
private static StructList<LogEntry> _logEntries;
|
||||
private static object _lock = new object();
|
||||
|
||||
private static void EditorGUI_hyperLinkClicked(EditorWindow window, HyperLinkClickedEventArgs args)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static void Application_logMessageReceived(string logString, string stackTrace, LogType type)
|
||||
{
|
||||
if (_intervalChecksTicks >= IntervalChecksTicksThreshold ||
|
||||
_logEntries.Count >= _logEntries.Capacity - 1)
|
||||
{
|
||||
CheckConsoleClean();
|
||||
_intervalChecksTicks = 0;
|
||||
}
|
||||
_logEntries.Add(new LogEntry(logString, stackTrace));
|
||||
|
||||
Interlocked.Increment(ref _consoleLogCounter);
|
||||
Interlocked.Increment(ref _intervalChecksTicks);
|
||||
}
|
||||
|
||||
|
||||
private static bool CheckConsoleClean()
|
||||
{
|
||||
int currentCount = GetConsoleLogCount();
|
||||
if (_consoleLogCounter > currentCount)
|
||||
{
|
||||
|
||||
error
|
||||
|
||||
_consoleLogCounter = currentCount;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private static int GetConsoleLogCount()
|
||||
{
|
||||
return (int)_getLogsCountMethod.Invoke(null, null);
|
||||
}
|
||||
private static string CreateIndexedLink(int index)
|
||||
{
|
||||
return $"<a href=\"{index}\">∆</a> ";
|
||||
}
|
||||
|
||||
|
||||
|
||||
//multi thread access.
|
||||
public static string GetHyperLink()
|
||||
{
|
||||
return instance.GetHyperLink_Internal();
|
||||
}
|
||||
public string GetHyperLink_Internal()
|
||||
{
|
||||
string hyperLink;
|
||||
if (_recycledIndexes.Count > 0)
|
||||
{
|
||||
hyperLink = _recycledIndexes.Dequeue();
|
||||
}
|
||||
else
|
||||
{
|
||||
hyperLink = CreateIndexedLink(_logEntries.Count);
|
||||
}
|
||||
return hyperLink;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private readonly struct LogEntry
|
||||
{
|
||||
public readonly string LogString;
|
||||
public readonly string StackTrace;
|
||||
public LogEntry(string logString, string stackTrace)
|
||||
{
|
||||
LogString = logString;
|
||||
StackTrace = stackTrace;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8666cb6c75b076c41910acbe59d258af
|
@ -72,58 +72,31 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
}
|
||||
}
|
||||
|
||||
internal static class ArrayUtility
|
||||
internal static class DragonArrayUtility
|
||||
{
|
||||
private static int GetHighBitNumber(uint bits)
|
||||
{
|
||||
if (bits == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int bit = 0;
|
||||
if ((bits & 0xFFFF0000) != 0)
|
||||
{
|
||||
bits >>= 16;
|
||||
bit |= 16;
|
||||
}
|
||||
if ((bits & 0xFF00) != 0)
|
||||
{
|
||||
bits >>= 8;
|
||||
bit |= 8;
|
||||
}
|
||||
if ((bits & 0xF0) != 0)
|
||||
{
|
||||
bits >>= 4;
|
||||
bit |= 4;
|
||||
}
|
||||
if ((bits & 0xC) != 0)
|
||||
{
|
||||
bits >>= 2;
|
||||
bit |= 2;
|
||||
}
|
||||
if ((bits & 0x2) != 0)
|
||||
{
|
||||
bit |= 1;
|
||||
}
|
||||
return bit;
|
||||
}
|
||||
public static int NormalizeSizeToPowerOfTwo(int minSize)
|
||||
public static int NextPow2(int v)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return 1 << (GetHighBitNumber((uint)minSize - 1u) + 1);
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
return ++v;
|
||||
}
|
||||
}
|
||||
public static int NormalizeSizeToPowerOfTwo_ClampOverflow(int minSize)
|
||||
public static int NextPow2_ClampOverflow(int v)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int hibit = (GetHighBitNumber((uint)minSize - 1u) + 1);
|
||||
if (hibit >= 32)
|
||||
const int NO_SIGN_HIBIT = 0x40000000;
|
||||
if ((v & NO_SIGN_HIBIT) != 0)
|
||||
{
|
||||
return int.MaxValue;
|
||||
}
|
||||
return 1 << hibit;
|
||||
return NextPow2(v);
|
||||
}
|
||||
}
|
||||
public static void Fill<T>(T[] array, T value, int startIndex = 0, int length = -1)
|
@ -432,6 +432,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
}
|
||||
else if (current.type == EventType.MouseDown && current.clickCount >= 2)
|
||||
{
|
||||
//UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(); //TODO
|
||||
AssetDatabase.OpenAsset(script);
|
||||
}
|
||||
}
|
||||
|
@ -3,13 +3,18 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS.Unity.Internal
|
||||
{
|
||||
[Serializable]
|
||||
[DebuggerDisplay("Count: {Count}")]
|
||||
internal struct StructList<T>
|
||||
{
|
||||
[SerializeField]
|
||||
internal T[] _items;
|
||||
[SerializeField]
|
||||
internal int _count;
|
||||
|
||||
public IEnumerable<T> Enumerable
|
||||
@ -39,7 +44,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
set
|
||||
{
|
||||
if (value <= _items.Length) { return; }
|
||||
value = ArrayUtility.NormalizeSizeToPowerOfTwo(value);
|
||||
value = DragonArrayUtility.NextPow2(value);
|
||||
Array.Resize(ref _items, value);
|
||||
}
|
||||
}
|
||||
@ -66,7 +71,7 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public StructList(int capacity)
|
||||
{
|
||||
_items = new T[ArrayUtility.NormalizeSizeToPowerOfTwo(capacity)];
|
||||
_items = new T[DragonArrayUtility.NextPow2(capacity)];
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
@ -92,6 +97,24 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
_items[idnex2] = tmp;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ref T FastDequeue()
|
||||
{
|
||||
#if DEBUG
|
||||
if (_count <= 0) { Throw.ArgumentOutOfRange(); }
|
||||
#endif
|
||||
return ref _items[--_count];
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public T Dequeue()
|
||||
{
|
||||
#if DEBUG
|
||||
if (_count <= 0) { Throw.ArgumentOutOfRange(); }
|
||||
#endif
|
||||
T result = _items[--_count];
|
||||
_items[_count] = default;
|
||||
return result;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void FastRemoveAt(int index)
|
||||
{
|
||||
#if DEBUG
|
||||
@ -178,4 +201,38 @@ namespace DCFApixels.DragonECS.Unity.Internal
|
||||
return _items;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class StructListExt
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Add_MultiAccess<T>(this ref StructList<T> self, T item)
|
||||
{
|
||||
var index = Interlocked.Increment(ref self._count);
|
||||
index -= 1;
|
||||
if (index >= self._items.Length)
|
||||
{
|
||||
lock (self._items)
|
||||
{
|
||||
if (index >= self._items.Length)
|
||||
{
|
||||
Array.Resize(ref self._items, self._items.Length << 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
self._items[index] = item;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryDequeue_MultiAccess<T>(this ref StructList<T> self, T item)
|
||||
{
|
||||
var index = Interlocked.Increment(ref self._count);
|
||||
|
||||
#if DEBUG
|
||||
if (_count <= 0) { Throw.ArgumentOutOfRange(); }
|
||||
#endif
|
||||
T result = _items[--_count];
|
||||
_items[_count] = default;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user