This commit is contained in:
DCFApixels 2025-03-21 14:32:50 +08:00
parent 2642510c89
commit f068c22661
9 changed files with 227 additions and 45 deletions

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 69f2abf8b8744c840b2da7f8988b3f8d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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()
{

View 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

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8666cb6c75b076c41910acbe59d258af

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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;
}
}
}