You've already forked ParticleEffectForUGUI
mirror of
https://github.com/mob-sakai/ParticleEffectForUGUI.git
synced 2026-05-16 05:00:07 +00:00
resharp
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Profiling;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.UI;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
|
||||
using UnityEditorInternal;
|
||||
#endif
|
||||
|
||||
namespace Coffee.NanoMonitor
|
||||
@@ -13,24 +14,29 @@ namespace Coffee.NanoMonitor
|
||||
[CustomEditor(typeof(NanoMonitor))]
|
||||
internal class NanoMonitorEditor : Editor
|
||||
{
|
||||
private UnityEditorInternal.ReorderableList m_MonitorItemList;
|
||||
private ReorderableList _monitorItemList;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
var items = serializedObject.FindProperty("m_CustomMonitorItems");
|
||||
m_MonitorItemList = new UnityEditorInternal.ReorderableList(serializedObject, items)
|
||||
_monitorItemList = new ReorderableList(serializedObject, items)
|
||||
{
|
||||
draggable = false,
|
||||
drawHeaderCallback = r => { EditorGUI.LabelField(r, new GUIContent("Custom Monitor Items")); },
|
||||
drawHeaderCallback = r =>
|
||||
{
|
||||
EditorGUI.LabelField(r, new GUIContent("Custom Monitor Items"));
|
||||
},
|
||||
drawElementCallback = (r, i, _, __) =>
|
||||
{
|
||||
EditorGUI.LabelField(new Rect(r.x, r.y, r.width, r.height - 2), GUIContent.none, EditorStyles.textArea);
|
||||
EditorGUI.LabelField(new Rect(r.x, r.y, r.width, r.height - 2), GUIContent.none,
|
||||
EditorStyles.textArea);
|
||||
var labelWidth = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = 80;
|
||||
EditorGUI.PropertyField(new Rect(r.x + 2, r.y + 3, r.width - 4, r.height - 4), items.GetArrayElementAtIndex(i), true);
|
||||
EditorGUI.PropertyField(new Rect(r.x + 2, r.y + 3, r.width - 4, r.height - 4),
|
||||
items.GetArrayElementAtIndex(i), true);
|
||||
EditorGUIUtility.labelWidth = labelWidth;
|
||||
},
|
||||
elementHeightCallback = i => EditorGUI.GetPropertyHeight(items.GetArrayElementAtIndex(i)) + 6,
|
||||
elementHeightCallback = i => EditorGUI.GetPropertyHeight(items.GetArrayElementAtIndex(i)) + 6
|
||||
};
|
||||
}
|
||||
|
||||
@@ -38,7 +44,7 @@ namespace Coffee.NanoMonitor
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
m_MonitorItemList.DoLayoutList();
|
||||
_monitorItemList.DoLayoutList();
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
@@ -52,38 +58,50 @@ namespace Coffee.NanoMonitor
|
||||
// Serialize Members.
|
||||
//################################
|
||||
// Settings
|
||||
[Header("Settings")] [SerializeField] [Range(0.01f, 2f)]
|
||||
[Header("Settings")]
|
||||
[SerializeField]
|
||||
[Range(0.01f, 2f)]
|
||||
private float m_Interval = 1f;
|
||||
|
||||
[SerializeField] [Range(0, 3)] private int m_Precision = 2;
|
||||
[SerializeField] private Font m_Font;
|
||||
[SerializeField]
|
||||
[Range(0, 3)]
|
||||
private int m_Precision = 2;
|
||||
|
||||
[SerializeField]
|
||||
private Font m_Font;
|
||||
|
||||
// Foldout
|
||||
[Header("Foldout")] [SerializeField] private bool m_Opened = false;
|
||||
[Header("Foldout")]
|
||||
[SerializeField]
|
||||
private bool m_Opened;
|
||||
|
||||
[FormerlySerializedAs("m_Collapse")] [SerializeField]
|
||||
private GameObject m_FoldoutObject = null;
|
||||
[FormerlySerializedAs("m_Collapse")]
|
||||
[SerializeField]
|
||||
private GameObject m_FoldoutObject;
|
||||
|
||||
[SerializeField] private Button m_OpenButton = null;
|
||||
[SerializeField] private Button m_CloseButton = null;
|
||||
[SerializeField]
|
||||
private Button m_OpenButton;
|
||||
|
||||
[SerializeField]
|
||||
private Button m_CloseButton;
|
||||
|
||||
// View
|
||||
[Header("View")] [SerializeField] private MonitorUI m_Fps = null;
|
||||
[SerializeField] private MonitorUI m_Gc = null;
|
||||
[SerializeField] private MonitorUI m_MonoUsage = null;
|
||||
[SerializeField] private MonitorUI m_UnityUsage = null;
|
||||
[Header("View")]
|
||||
[SerializeField]
|
||||
private MonitorUI m_Fps;
|
||||
|
||||
[HideInInspector] [SerializeField] private CustomMonitorItem[] m_CustomMonitorItems = new CustomMonitorItem[0];
|
||||
[SerializeField]
|
||||
private MonitorUI m_Gc;
|
||||
|
||||
[SerializeField]
|
||||
private MonitorUI m_MonoUsage;
|
||||
|
||||
//################################
|
||||
// Public Members.
|
||||
//################################
|
||||
public void Clean()
|
||||
{
|
||||
Resources.UnloadUnusedAssets();
|
||||
GC.Collect();
|
||||
}
|
||||
[SerializeField]
|
||||
private MonitorUI m_UnityUsage;
|
||||
|
||||
[HideInInspector]
|
||||
[SerializeField]
|
||||
private CustomMonitorItem[] m_CustomMonitorItems = new CustomMonitorItem[0];
|
||||
|
||||
|
||||
//################################
|
||||
@@ -93,44 +111,75 @@ namespace Coffee.NanoMonitor
|
||||
private double _fpsElapsed;
|
||||
private int _frames;
|
||||
|
||||
private void Open()
|
||||
private void Update()
|
||||
{
|
||||
_frames++;
|
||||
_elapsed += Time.unscaledDeltaTime;
|
||||
_fpsElapsed += Time.unscaledDeltaTime;
|
||||
if (_elapsed < m_Interval) return;
|
||||
|
||||
if (m_Fps)
|
||||
{
|
||||
m_Fps.SetText("FPS: {0}", (int)(_frames / _fpsElapsed));
|
||||
}
|
||||
|
||||
if (m_Gc)
|
||||
{
|
||||
m_Gc.SetText("GC: {0}", GC.CollectionCount(0));
|
||||
}
|
||||
|
||||
if (m_MonoUsage)
|
||||
{
|
||||
var monoUsed = (Profiler.GetMonoUsedSizeLong() >> 10) / 1024f;
|
||||
var monoTotal = (Profiler.GetMonoHeapSizeLong() >> 10) / 1024f;
|
||||
if (m_Precision == 3)
|
||||
{
|
||||
m_MonoUsage.SetText("Mono: {0:N3}/{1:N3}MB", monoUsed, monoTotal);
|
||||
}
|
||||
else if (m_Precision == 2)
|
||||
{
|
||||
m_MonoUsage.SetText("Mono: {0:N2}/{1:N2}MB", monoUsed, monoTotal);
|
||||
}
|
||||
else if (m_Precision == 1)
|
||||
{
|
||||
m_MonoUsage.SetText("Mono: {0:N1}/{1:N1}MB", monoUsed, monoTotal);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_MonoUsage.SetText("Mono: {0:N0}/{1:N0}MB", monoUsed, monoTotal);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_UnityUsage)
|
||||
{
|
||||
var unityUsed = (Profiler.GetTotalAllocatedMemoryLong() >> 10) / 1024f;
|
||||
var unityTotal = (Profiler.GetTotalReservedMemoryLong() >> 10) / 1024f;
|
||||
if (m_Precision == 3)
|
||||
{
|
||||
m_UnityUsage.SetText("Unity: {0:N3}/{1:N3}MB", unityUsed, unityTotal);
|
||||
}
|
||||
else if (m_Precision == 2)
|
||||
{
|
||||
m_UnityUsage.SetText("Unity: {0:N2}/{1:N2}MB", unityUsed, unityTotal);
|
||||
}
|
||||
else if (m_Precision == 1)
|
||||
{
|
||||
m_UnityUsage.SetText("Unity: {0:N1}/{1:N1}MB", unityUsed, unityTotal);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_UnityUsage.SetText("Unity: {0:N0}/{1:N0}MB", unityUsed, unityTotal);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in m_CustomMonitorItems)
|
||||
{
|
||||
item.UpdateText();
|
||||
}
|
||||
|
||||
_frames = 0;
|
||||
_elapsed = m_Interval;
|
||||
_elapsed %= m_Interval;
|
||||
_fpsElapsed = 0;
|
||||
|
||||
if (m_FoldoutObject)
|
||||
{
|
||||
m_FoldoutObject.SetActive(true);
|
||||
}
|
||||
|
||||
if (m_CloseButton)
|
||||
{
|
||||
m_CloseButton.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
if (m_OpenButton)
|
||||
{
|
||||
m_OpenButton.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void Close()
|
||||
{
|
||||
if (m_FoldoutObject)
|
||||
{
|
||||
m_FoldoutObject.SetActive(false);
|
||||
}
|
||||
|
||||
if (m_CloseButton)
|
||||
{
|
||||
m_CloseButton.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
if (m_OpenButton)
|
||||
{
|
||||
m_OpenButton.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -172,77 +221,6 @@ namespace Coffee.NanoMonitor
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
_frames++;
|
||||
_elapsed += Time.unscaledDeltaTime;
|
||||
_fpsElapsed += Time.unscaledDeltaTime;
|
||||
if (_elapsed < m_Interval) return;
|
||||
|
||||
if (m_Fps)
|
||||
{
|
||||
m_Fps.SetText("FPS: {0}", (int) (_frames / _fpsElapsed));
|
||||
}
|
||||
|
||||
if (m_Gc)
|
||||
{
|
||||
m_Gc.SetText("GC: {0}", GC.CollectionCount(0));
|
||||
}
|
||||
|
||||
if (m_MonoUsage)
|
||||
{
|
||||
var monoUsed = (UnityEngine.Profiling.Profiler.GetMonoUsedSizeLong() >> 10) / 1024f;
|
||||
var monoTotal = (UnityEngine.Profiling.Profiler.GetMonoHeapSizeLong() >> 10) / 1024f;
|
||||
if (m_Precision == 3)
|
||||
{
|
||||
m_MonoUsage.SetText("Mono: {0:N3}/{1:N3}MB", monoUsed, monoTotal);
|
||||
}
|
||||
else if (m_Precision == 2)
|
||||
{
|
||||
m_MonoUsage.SetText("Mono: {0:N2}/{1:N2}MB", monoUsed, monoTotal);
|
||||
}
|
||||
else if (m_Precision == 1)
|
||||
{
|
||||
m_MonoUsage.SetText("Mono: {0:N1}/{1:N1}MB", monoUsed, monoTotal);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_MonoUsage.SetText("Mono: {0:N0}/{1:N0}MB", monoUsed, monoTotal);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_UnityUsage)
|
||||
{
|
||||
var unityUsed = (UnityEngine.Profiling.Profiler.GetTotalAllocatedMemoryLong() >> 10) / 1024f;
|
||||
var unityTotal = (UnityEngine.Profiling.Profiler.GetTotalReservedMemoryLong() >> 10) / 1024f;
|
||||
if (m_Precision == 3)
|
||||
{
|
||||
m_UnityUsage.SetText("Unity: {0:N3}/{1:N3}MB", unityUsed, unityTotal);
|
||||
}
|
||||
else if (m_Precision == 2)
|
||||
{
|
||||
m_UnityUsage.SetText("Unity: {0:N2}/{1:N2}MB", unityUsed, unityTotal);
|
||||
}
|
||||
else if (m_Precision == 1)
|
||||
{
|
||||
m_UnityUsage.SetText("Unity: {0:N1}/{1:N1}MB", unityUsed, unityTotal);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_UnityUsage.SetText("Unity: {0:N0}/{1:N0}MB", unityUsed, unityTotal);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in m_CustomMonitorItems)
|
||||
{
|
||||
item.UpdateText();
|
||||
}
|
||||
|
||||
_frames = 0;
|
||||
_elapsed %= m_Interval;
|
||||
_fpsElapsed = 0;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnValidate()
|
||||
{
|
||||
@@ -264,5 +242,55 @@ namespace Coffee.NanoMonitor
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//################################
|
||||
// Public Members.
|
||||
//################################
|
||||
public void Clean()
|
||||
{
|
||||
Resources.UnloadUnusedAssets();
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
private void Open()
|
||||
{
|
||||
_frames = 0;
|
||||
_elapsed = m_Interval;
|
||||
_fpsElapsed = 0;
|
||||
|
||||
if (m_FoldoutObject)
|
||||
{
|
||||
m_FoldoutObject.SetActive(true);
|
||||
}
|
||||
|
||||
if (m_CloseButton)
|
||||
{
|
||||
m_CloseButton.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
if (m_OpenButton)
|
||||
{
|
||||
m_OpenButton.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void Close()
|
||||
{
|
||||
if (m_FoldoutObject)
|
||||
{
|
||||
m_FoldoutObject.SetActive(false);
|
||||
}
|
||||
|
||||
if (m_CloseButton)
|
||||
{
|
||||
m_CloseButton.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
if (m_OpenButton)
|
||||
{
|
||||
m_OpenButton.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,17 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Coffee.NanoMonitor{
|
||||
namespace Coffee.NanoMonitor
|
||||
{
|
||||
public class FixedFont
|
||||
{
|
||||
private readonly UIVertex[] _tmpVerts = new UIVertex[4];
|
||||
private static readonly Dictionary<Font, FixedFont> _fonts = new Dictionary<Font, FixedFont>();
|
||||
private static readonly TextGenerator _textGenerator = new TextGenerator(100);
|
||||
private const string k_Characters =
|
||||
"_!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
|
||||
private static TextGenerationSettings _settings = new TextGenerationSettings
|
||||
private static readonly Dictionary<Font, FixedFont> s_Fonts = new Dictionary<Font, FixedFont>();
|
||||
private static readonly TextGenerator s_TextGenerator = new TextGenerator(100);
|
||||
|
||||
private static TextGenerationSettings s_Settings = new TextGenerationSettings
|
||||
{
|
||||
scaleFactor = 1,
|
||||
horizontalOverflow = HorizontalWrapMode.Overflow,
|
||||
@@ -19,25 +22,33 @@ namespace Coffee.NanoMonitor{
|
||||
color = Color.white
|
||||
};
|
||||
|
||||
private int _resolution = 0;
|
||||
private readonly Font _font;
|
||||
private UIVertex[] _verts;
|
||||
private readonly UIVertex[] _tmpVerts = new UIVertex[4];
|
||||
private UICharInfo[] _charInfos;
|
||||
|
||||
private int _resolution;
|
||||
private UIVertex[] _verts;
|
||||
|
||||
private FixedFont(Font font)
|
||||
{
|
||||
_font = font;
|
||||
}
|
||||
|
||||
public int fontSize => _font.dynamic ? 32 : _font.fontSize;
|
||||
public int fontSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return _font.dynamic ? 32 : _font.fontSize;
|
||||
}
|
||||
}
|
||||
|
||||
public static FixedFont GetOrCreate(Font font)
|
||||
{
|
||||
if (font == null) return null;
|
||||
if (_fonts.TryGetValue(font, out var data)) return data;
|
||||
if (s_Fonts.TryGetValue(font, out var data)) return data;
|
||||
|
||||
data = new FixedFont(font);
|
||||
_fonts.Add(font, data);
|
||||
s_Fonts.Add(font, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -61,18 +72,20 @@ namespace Coffee.NanoMonitor{
|
||||
if (_resolution == currentResolution) return;
|
||||
_resolution = currentResolution;
|
||||
|
||||
_settings.font = _font;
|
||||
_textGenerator.Invalidate();
|
||||
_textGenerator.Populate("_!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", _settings);
|
||||
s_Settings.font = _font;
|
||||
s_TextGenerator.Invalidate();
|
||||
s_TextGenerator.Populate(k_Characters, s_Settings);
|
||||
|
||||
_verts = _textGenerator.GetVerticesArray();
|
||||
_charInfos = _textGenerator.GetCharactersArray();
|
||||
_verts = s_TextGenerator.GetVerticesArray();
|
||||
_charInfos = s_TextGenerator.GetCharactersArray();
|
||||
|
||||
float offsetX = 0;
|
||||
for (var i = 0; i < _verts.Length; i++)
|
||||
{
|
||||
if ((i & 3) == 0)
|
||||
{
|
||||
offsetX = _verts[i].position.x;
|
||||
}
|
||||
|
||||
var v = _verts[i];
|
||||
v.position -= new Vector3(offsetX, 0);
|
||||
@@ -118,18 +131,27 @@ namespace Coffee.NanoMonitor{
|
||||
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
_tmpVerts[i] = new UIVertex();
|
||||
_tmpVerts[i].uv0 = uv;
|
||||
_tmpVerts[i].color = color;
|
||||
_tmpVerts[i] = new UIVertex
|
||||
{
|
||||
uv0 = uv,
|
||||
color = color
|
||||
};
|
||||
|
||||
if (i == 0)
|
||||
_tmpVerts[i].position = new Vector2(-size.x, -size.y) + offset;
|
||||
else if (i == 1)
|
||||
_tmpVerts[i].position = new Vector2(-size.x, size.y) + offset;
|
||||
else if (i == 2)
|
||||
_tmpVerts[i].position = new Vector2(size.x, size.y) + offset;
|
||||
else
|
||||
_tmpVerts[i].position = new Vector2(size.x, -size.y) + offset;
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
_tmpVerts[i].position = new Vector2(-size.x, -size.y) + offset;
|
||||
break;
|
||||
case 1:
|
||||
_tmpVerts[i].position = new Vector2(-size.x, size.y) + offset;
|
||||
break;
|
||||
case 2:
|
||||
_tmpVerts[i].position = new Vector2(size.x, size.y) + offset;
|
||||
break;
|
||||
case 3:
|
||||
_tmpVerts[i].position = new Vector2(size.x, -size.y) + offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
toFill.AddUIVertexQuad(_tmpVerts);
|
||||
|
||||
@@ -1,50 +1,46 @@
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Coffee.NanoMonitor{
|
||||
namespace Coffee.NanoMonitor
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
|
||||
[CustomEditor(typeof(MonitorUI))]
|
||||
public class MonitorTextEditor : Editor
|
||||
{
|
||||
private SerializedProperty m_Mode;
|
||||
private SerializedProperty m_TextAnchor;
|
||||
private SerializedProperty m_FontSize;
|
||||
private SerializedProperty m_Font;
|
||||
private SerializedProperty m_Text;
|
||||
private SerializedProperty m_Color;
|
||||
private SerializedProperty _color;
|
||||
private SerializedProperty _font;
|
||||
private SerializedProperty _fontSize;
|
||||
private SerializedProperty _mode;
|
||||
private SerializedProperty _text;
|
||||
private SerializedProperty _textAnchor;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_Mode = serializedObject.FindProperty("m_Mode");
|
||||
|
||||
m_Text = serializedObject.FindProperty("m_Text");
|
||||
m_Color = serializedObject.FindProperty("m_Color");
|
||||
_mode = serializedObject.FindProperty("m_Mode");
|
||||
_text = serializedObject.FindProperty("m_Text");
|
||||
_color = serializedObject.FindProperty("m_Color");
|
||||
var fontData = serializedObject.FindProperty("m_FontData");
|
||||
m_FontSize = fontData.FindPropertyRelative("m_FontSize");
|
||||
m_Font = fontData.FindPropertyRelative("m_Font");
|
||||
m_TextAnchor = serializedObject.FindProperty("m_TextAnchor");
|
||||
_fontSize = fontData.FindPropertyRelative("m_FontSize");
|
||||
_font = fontData.FindPropertyRelative("m_Font");
|
||||
_textAnchor = serializedObject.FindProperty("m_TextAnchor");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.PropertyField(m_Mode);
|
||||
if ((MonitorUI.Mode) m_Mode.intValue == MonitorUI.Mode.Text)
|
||||
EditorGUILayout.PropertyField(_mode);
|
||||
if ((MonitorUI.Mode)_mode.intValue == MonitorUI.Mode.Text)
|
||||
{
|
||||
EditorGUILayout.PropertyField(m_Text);
|
||||
EditorGUILayout.PropertyField(m_FontSize);
|
||||
EditorGUILayout.PropertyField(m_TextAnchor);
|
||||
|
||||
//EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUILayout.PropertyField(m_Font);
|
||||
//EditorGUI.EndDisabledGroup();
|
||||
EditorGUILayout.PropertyField(_text);
|
||||
EditorGUILayout.PropertyField(_fontSize);
|
||||
EditorGUILayout.PropertyField(_textAnchor);
|
||||
EditorGUILayout.PropertyField(_font);
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(m_Color);
|
||||
EditorGUILayout.PropertyField(_color);
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
@@ -56,7 +52,7 @@ namespace Coffee.NanoMonitor{
|
||||
public enum Mode
|
||||
{
|
||||
Text,
|
||||
Fill,
|
||||
Fill
|
||||
}
|
||||
|
||||
public enum TextAnchor
|
||||
@@ -74,26 +70,38 @@ namespace Coffee.NanoMonitor{
|
||||
[SerializeField] private TextAnchor m_TextAnchor;
|
||||
|
||||
|
||||
//################################
|
||||
// Private Members.
|
||||
//################################
|
||||
private readonly StringBuilder _sb = new StringBuilder(64);
|
||||
|
||||
|
||||
//################################
|
||||
// Public Members.
|
||||
//################################
|
||||
public override string text
|
||||
{
|
||||
get => m_StringBuilder.ToString();
|
||||
get
|
||||
{
|
||||
return _sb.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Text = value;
|
||||
if (m_StringBuilder.IsEqual(m_Text)) return;
|
||||
if (_sb.IsEqual(m_Text)) return;
|
||||
|
||||
m_StringBuilder.Length = 0;
|
||||
m_StringBuilder.Append(m_Text);
|
||||
_sb.Length = 0;
|
||||
_sb.Append(m_Text);
|
||||
SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public TextAnchor textAnchor
|
||||
{
|
||||
get => m_TextAnchor;
|
||||
get
|
||||
{
|
||||
return m_TextAnchor;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (m_TextAnchor == value) return;
|
||||
@@ -105,44 +113,11 @@ namespace Coffee.NanoMonitor{
|
||||
|
||||
public override bool raycastTarget
|
||||
{
|
||||
get => m_Mode == Mode.Fill;
|
||||
set { }
|
||||
}
|
||||
|
||||
public void SetText(string format, double arg0 = 0, double arg1 = 0, double arg2 = 0, double arg3 = 0)
|
||||
{
|
||||
m_StringBuilder.Length = 0;
|
||||
m_StringBuilder.AppendFormatNoAlloc(format, arg0, arg1, arg2, arg3);
|
||||
SetVerticesDirty();
|
||||
}
|
||||
|
||||
public void SetText(StringBuilder builder)
|
||||
{
|
||||
m_StringBuilder.Length = 0;
|
||||
m_StringBuilder.Append(builder);
|
||||
SetVerticesDirty();
|
||||
}
|
||||
|
||||
|
||||
//################################
|
||||
// Private Members.
|
||||
//################################
|
||||
private readonly StringBuilder m_StringBuilder = new StringBuilder(64);
|
||||
|
||||
private void UpdateFont()
|
||||
{
|
||||
//var globalFont = NNanoMonitorttings.Instance.font;
|
||||
//if (globalFont)
|
||||
//{
|
||||
// font = globalFont;
|
||||
//}
|
||||
|
||||
var fontData = FixedFont.GetOrCreate(font);
|
||||
if (fontData != null)
|
||||
get
|
||||
{
|
||||
fontData.Invalidate();
|
||||
fontData.UpdateFont();
|
||||
return m_Mode == Mode.Fill;
|
||||
}
|
||||
set { }
|
||||
}
|
||||
|
||||
|
||||
@@ -151,19 +126,17 @@ namespace Coffee.NanoMonitor{
|
||||
//################################
|
||||
protected override void OnEnable()
|
||||
{
|
||||
//NaNanoMonitortings.Instance.onFontChanged += UpdateFont;
|
||||
RegisterDirtyMaterialCallback(UpdateFont);
|
||||
|
||||
base.OnEnable();
|
||||
raycastTarget = false;
|
||||
maskable = false;
|
||||
m_StringBuilder.Length = 0;
|
||||
m_StringBuilder.Append(m_Text);
|
||||
_sb.Length = 0;
|
||||
_sb.Append(m_Text);
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
//NanNanoMonitorings.Instance.onFontChanged -= UpdateFont;
|
||||
UnregisterDirtyMaterialCallback(UpdateFont);
|
||||
|
||||
base.OnDisable();
|
||||
@@ -174,14 +147,38 @@ namespace Coffee.NanoMonitor{
|
||||
{
|
||||
base.OnValidate();
|
||||
|
||||
if (!m_StringBuilder.IsEqual(m_Text))
|
||||
if (!_sb.IsEqual(m_Text))
|
||||
{
|
||||
m_StringBuilder.Length = 0;
|
||||
m_StringBuilder.Append(m_Text);
|
||||
_sb.Length = 0;
|
||||
_sb.Append(m_Text);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public void SetText(string format, double arg0 = 0, double arg1 = 0, double arg2 = 0, double arg3 = 0)
|
||||
{
|
||||
_sb.Length = 0;
|
||||
_sb.AppendFormatNoAlloc(format, arg0, arg1, arg2, arg3);
|
||||
SetVerticesDirty();
|
||||
}
|
||||
|
||||
public void SetText(StringBuilder builder)
|
||||
{
|
||||
_sb.Length = 0;
|
||||
_sb.Append(builder);
|
||||
SetVerticesDirty();
|
||||
}
|
||||
|
||||
private void UpdateFont()
|
||||
{
|
||||
var fontData = FixedFont.GetOrCreate(font);
|
||||
if (fontData != null)
|
||||
{
|
||||
fontData.Invalidate();
|
||||
fontData.UpdateFont();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPopulateMesh(VertexHelper toFill)
|
||||
{
|
||||
toFill.Clear();
|
||||
@@ -197,7 +194,7 @@ namespace Coffee.NanoMonitor{
|
||||
return;
|
||||
}
|
||||
|
||||
var scale = (float) fontSize / fontData.fontSize;
|
||||
var scale = (float)fontSize / fontData.fontSize;
|
||||
float offset = 0;
|
||||
switch (textAnchor)
|
||||
{
|
||||
@@ -205,20 +202,26 @@ namespace Coffee.NanoMonitor{
|
||||
offset = rectTransform.rect.xMin;
|
||||
break;
|
||||
case TextAnchor.Center:
|
||||
for (var i = 0; i < m_StringBuilder.Length; i++)
|
||||
offset = fontData.Layout(m_StringBuilder[i], offset, scale);
|
||||
for (var i = 0; i < _sb.Length; i++)
|
||||
{
|
||||
offset = fontData.Layout(_sb[i], offset, scale);
|
||||
}
|
||||
|
||||
offset = -offset / 2;
|
||||
break;
|
||||
case TextAnchor.Right:
|
||||
for (var i = 0; i < m_StringBuilder.Length; i++)
|
||||
offset = fontData.Layout(m_StringBuilder[i], offset, scale);
|
||||
for (var i = 0; i < _sb.Length; i++)
|
||||
{
|
||||
offset = fontData.Layout(_sb[i], offset, scale);
|
||||
}
|
||||
|
||||
offset = rectTransform.rect.xMax - offset;
|
||||
break;
|
||||
}
|
||||
|
||||
for (var i = 0; i < m_StringBuilder.Length; i++)
|
||||
for (var i = 0; i < _sb.Length; i++)
|
||||
{
|
||||
offset = fontData.Append(toFill, m_StringBuilder[i], offset, scale, color);
|
||||
offset = fontData.Append(toFill, _sb[i], offset, scale, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace Coffee.MiniProfiler
|
||||
{
|
||||
internal class MiniProfilerSettings : ScriptableSettings<MiniProfilerSettings>
|
||||
{
|
||||
[Header("UI")]
|
||||
[SerializeField] private Font m_Font = null;
|
||||
|
||||
[Header("Instantiate On Boot")]
|
||||
[SerializeField] private GameObject miniProfilerPrefab = null;
|
||||
[SerializeField] private string[] m_SceneNames = new string[0];
|
||||
|
||||
public Font font => m_Font;
|
||||
public event Action onFontChanged;
|
||||
|
||||
protected override void OnBoot()
|
||||
{
|
||||
SceneManager.sceneLoaded -= OnSceneLoaded;
|
||||
SceneManager.sceneLoaded += OnSceneLoaded;
|
||||
}
|
||||
|
||||
public void OnSceneLoaded(Scene scene, LoadSceneMode __)
|
||||
{
|
||||
SceneManager.sceneLoaded -= OnSceneLoaded;
|
||||
if (!miniProfilerPrefab || !m_SceneNames.Contains(scene.name)) return;
|
||||
|
||||
var go = Instantiate(miniProfilerPrefab);
|
||||
if (Application.isPlaying)
|
||||
DontDestroyOnLoad(go);
|
||||
}
|
||||
|
||||
protected override bool bootOnPlayMode => true;
|
||||
protected override bool bootOnEditorMode => false;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate()
|
||||
{
|
||||
onFontChanged?.Invoke();
|
||||
base.OnValidate();
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
m_Font = UnityEngine.Resources.GetBuiltinResource<Font>("Arial.ttf");
|
||||
}
|
||||
|
||||
[UnityEditor.SettingsProvider]
|
||||
private static UnityEditor.SettingsProvider CreateSettingsProvider() => new ScriptableSettingsProvider<MiniProfilerSettings>();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 647dad4f8226a49b9874b68b79413d64
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- miniProfilerPrefab: {fileID: 7211429669315726685, guid: 784696794bc6345bc80bf49623581c2e,
|
||||
type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,280 +0,0 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Linq;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
|
||||
#endif
|
||||
|
||||
namespace Coffee.MiniProfiler
|
||||
{
|
||||
internal abstract class ScriptableSettings : ScriptableObject
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
public virtual string GetSettingPath()
|
||||
{
|
||||
return GetSettingPath(GetType());
|
||||
}
|
||||
|
||||
internal static string GetSettingPath(Type type)
|
||||
{
|
||||
return $"Project/{ObjectNames.NicifyVariableName(type.Name.Replace("ProjectSettings", ""))}";
|
||||
}
|
||||
#endif
|
||||
|
||||
public virtual string GetDefaultAssetPath()
|
||||
{
|
||||
return $"Assets/ProjectSettings/{GetType().Name}.asset";
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class ScriptableSettings<T> : ScriptableSettings
|
||||
where T : ScriptableSettings<T>
|
||||
{
|
||||
//################################
|
||||
// Public Members.
|
||||
//################################
|
||||
public static T Instance => _instance ? _instance : _instance = GetOrCreate();
|
||||
|
||||
private static T _instance;
|
||||
|
||||
protected virtual bool bootOnEditorMode => true;
|
||||
protected virtual bool bootOnPlayMode => true;
|
||||
|
||||
protected abstract void OnBoot();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
//################################
|
||||
// Private Members.
|
||||
//################################
|
||||
private bool enabled;
|
||||
|
||||
private static T GetOrCreate()
|
||||
{
|
||||
return PlayerSettings.GetPreloadedAssets()
|
||||
.OfType<T>()
|
||||
.FirstOrDefault() ?? CreateInstance<T>();
|
||||
}
|
||||
|
||||
private void OnPlayModeStateChanged(PlayModeStateChange state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case PlayModeStateChange.EnteredEditMode:
|
||||
enabled = true;
|
||||
Boot();
|
||||
break;
|
||||
case PlayModeStateChange.ExitingEditMode:
|
||||
case PlayModeStateChange.ExitingPlayMode:
|
||||
enabled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void Boot()
|
||||
{
|
||||
var preloadedAssets = PlayerSettings.GetPreloadedAssets();
|
||||
var assets = preloadedAssets.OfType<T>().ToArray();
|
||||
var first = assets.FirstOrDefault() ?? this as T;
|
||||
|
||||
// If there are no preloaded assets, registry the first asset.
|
||||
// If there are multiple preloaded assets, unregisters all but the first one.
|
||||
if (assets.Length != 1)
|
||||
{
|
||||
// The first asset is not saved.
|
||||
if (string.IsNullOrEmpty(AssetDatabase.GetAssetPath(first)))
|
||||
{
|
||||
if (!AssetDatabase.IsValidFolder("Assets/ProjectSettings"))
|
||||
AssetDatabase.CreateFolder("Assets", "ProjectSettings");
|
||||
|
||||
var assetName = ObjectNames.NicifyVariableName(first.GetType().Name.Replace("ProjectSettings", ""));
|
||||
var assetPath = AssetDatabase.GenerateUniqueAssetPath($"Assets/ProjectSettings/{assetName}.asset");
|
||||
AssetDatabase.CreateAsset(first, assetPath);
|
||||
}
|
||||
|
||||
PlayerSettings.SetPreloadedAssets(preloadedAssets
|
||||
.Where(x => x)
|
||||
.Except(assets)
|
||||
.Concat(new[] {first})
|
||||
.ToArray());
|
||||
}
|
||||
|
||||
// Another asset is registered as a preload asset.
|
||||
if (first != this)
|
||||
{
|
||||
UnityEngine.Debug.LogError($"Another asset '{first}' is registered as a preload '{typeof(T).Name}' asset." +
|
||||
$"\nThis instance ('{this}') will be ignored. Check 'Project Settings > Player > Preload Assets'", this);
|
||||
return;
|
||||
}
|
||||
|
||||
_instance = first;
|
||||
|
||||
// Do nothing on editor mode.
|
||||
if (!bootOnEditorMode && !EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Do nothing on play mode.
|
||||
if (!bootOnPlayMode && EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OnBoot();
|
||||
}
|
||||
|
||||
|
||||
//################################
|
||||
// Unity Callbacks.
|
||||
//################################
|
||||
private void OnEnable()
|
||||
{
|
||||
enabled = true;
|
||||
Boot();
|
||||
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
|
||||
}
|
||||
|
||||
protected virtual void OnValidate()
|
||||
{
|
||||
if (enabled)
|
||||
Boot();
|
||||
}
|
||||
#else
|
||||
private static T GetOrCreate()
|
||||
{
|
||||
return CreateInstance<T>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (!bootOnPlayMode) return;
|
||||
|
||||
_instance = this as T;
|
||||
OnBoot();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[CustomEditor(typeof(ScriptablePreferenceSettings<>), true)]
|
||||
internal class ScriptablePreferenceSettingsEditor : Editor
|
||||
{
|
||||
private static readonly GUIContent _button = new GUIContent("Open Project Settings");
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (GUILayout.Button(_button))
|
||||
{
|
||||
SettingsService.OpenProjectSettings(((ScriptableSettings) target).GetSettingPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class ScriptablePreferenceSettings<T> : ScriptableSingleton<T>
|
||||
where T : ScriptablePreferenceSettings<T>
|
||||
{
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[CustomEditor(typeof(ScriptableSettings), true)]
|
||||
internal class ScriptableSettingsEditor : Editor
|
||||
{
|
||||
private static readonly GUIContent _button = new GUIContent("Open Project Settings");
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (GUILayout.Button(_button))
|
||||
{
|
||||
SettingsService.OpenProjectSettings(((ScriptableSettings) target).GetSettingPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ScriptableSettingsProvider<T> : SettingsProvider where T : ScriptableSettings<T>
|
||||
{
|
||||
public ScriptableSettingsProvider(string path) : base(path)
|
||||
{
|
||||
}
|
||||
|
||||
public ScriptableSettingsProvider() : base(ScriptableSettings.GetSettingPath(typeof(T)))
|
||||
{
|
||||
}
|
||||
|
||||
protected SerializedObject serializedObject { get; private set; }
|
||||
protected ScriptableSettings<T> target { get; private set; }
|
||||
|
||||
public sealed override void OnGUI(string searchContext)
|
||||
{
|
||||
if (!target)
|
||||
{
|
||||
target = ScriptableSettings<T>.Instance;
|
||||
serializedObject = new SerializedObject(target);
|
||||
}
|
||||
|
||||
OnGUI();
|
||||
}
|
||||
|
||||
protected virtual void OnGUI()
|
||||
{
|
||||
serializedObject.UpdateIfRequiredOrScript();
|
||||
var iterator = serializedObject.GetIterator();
|
||||
var enterChildren = true;
|
||||
while (iterator.NextVisible(enterChildren))
|
||||
{
|
||||
if (iterator.propertyPath != "m_Script")
|
||||
EditorGUILayout.PropertyField(iterator, true);
|
||||
|
||||
enterChildren = false;
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
internal class ScriptablePreferenceSettingsProvider<T> : SettingsProvider where T : ScriptableSettings<T>
|
||||
{
|
||||
public ScriptablePreferenceSettingsProvider(string path) : base(path, SettingsScope.User)
|
||||
{
|
||||
}
|
||||
|
||||
public ScriptablePreferenceSettingsProvider() : base(ScriptableSettings.GetSettingPath(typeof(T)), SettingsScope.User)
|
||||
{
|
||||
}
|
||||
|
||||
protected SerializedObject serializedObject { get; private set; }
|
||||
protected ScriptableSettings<T> target { get; private set; }
|
||||
|
||||
public sealed override void OnGUI(string searchContext)
|
||||
{
|
||||
if (!target)
|
||||
{
|
||||
target = ScriptableSettings<T>.Instance;
|
||||
serializedObject = new SerializedObject(target);
|
||||
}
|
||||
|
||||
OnGUI();
|
||||
}
|
||||
|
||||
protected virtual void OnGUI()
|
||||
{
|
||||
serializedObject.UpdateIfRequiredOrScript();
|
||||
var iterator = serializedObject.GetIterator();
|
||||
var enterChildren = true;
|
||||
while (iterator.NextVisible(enterChildren))
|
||||
{
|
||||
if (iterator.propertyPath != "m_Script")
|
||||
EditorGUILayout.PropertyField(iterator, true);
|
||||
|
||||
enterChildren = false;
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ea9606f69cee413e9f96f52de99fa5e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
@@ -11,12 +12,17 @@ namespace Coffee.NanoMonitor
|
||||
{
|
||||
public override void OnGUI(Rect p, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
EditorGUI.PropertyField(new Rect(p.x, p.y + 18 * 0, p.width, 16), property.FindPropertyRelative("m_Text"));
|
||||
EditorGUI.PropertyField(new Rect(p.x, p.y + 18 * 1, p.width, 16), property.FindPropertyRelative("m_Format"));
|
||||
var pos = new Rect(p.x, p.y + 18 * 0, p.width, 16);
|
||||
EditorGUI.PropertyField(pos, property.FindPropertyRelative("m_Text"));
|
||||
pos.y += 18;
|
||||
EditorGUI.PropertyField(pos, property.FindPropertyRelative("m_Format"));
|
||||
pos.y += 18;
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUI.PropertyField(new Rect(p.x, p.y + 18 * 2, p.width, 16), property.FindPropertyRelative("m_Arg0"));
|
||||
EditorGUI.PropertyField(new Rect(p.x, p.y + 18 * 3, p.width, 16), property.FindPropertyRelative("m_Arg1"));
|
||||
EditorGUI.PropertyField(new Rect(p.x, p.y + 18 * 4, p.width, 16), property.FindPropertyRelative("m_Arg2"));
|
||||
EditorGUI.PropertyField(pos, property.FindPropertyRelative("m_Arg0"));
|
||||
pos.y += 18;
|
||||
EditorGUI.PropertyField(pos, property.FindPropertyRelative("m_Arg1"));
|
||||
pos.y += 18;
|
||||
EditorGUI.PropertyField(pos, property.FindPropertyRelative("m_Arg2"));
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
@@ -29,19 +35,21 @@ namespace Coffee.NanoMonitor
|
||||
}
|
||||
#endif
|
||||
|
||||
[System.Serializable]
|
||||
[Serializable]
|
||||
public class CustomMonitorItem
|
||||
{
|
||||
[SerializeField] private MonitorUI m_Text = null;
|
||||
[SerializeField] private MonitorUI m_Text;
|
||||
[SerializeField] private string m_Format = "";
|
||||
[SerializeField] private NumericProperty m_Arg0 = null;
|
||||
[SerializeField] private NumericProperty m_Arg1 = null;
|
||||
[SerializeField] private NumericProperty m_Arg2 = null;
|
||||
[SerializeField] private NumericProperty m_Arg0;
|
||||
[SerializeField] private NumericProperty m_Arg1;
|
||||
[SerializeField] private NumericProperty m_Arg2;
|
||||
|
||||
public void UpdateText()
|
||||
{
|
||||
if (m_Text)
|
||||
{
|
||||
m_Text.SetText(m_Format, m_Arg0.Get(), m_Arg1.Get(), m_Arg2.Get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
|
||||
#endif
|
||||
using UnityEngine;
|
||||
|
||||
namespace Coffee.NanoMonitor
|
||||
{
|
||||
@@ -20,39 +16,45 @@ namespace Coffee.NanoMonitor
|
||||
|
||||
private static readonly Dictionary<Type, string> s_SupportedTypes = new Dictionary<Type, string>
|
||||
{
|
||||
{typeof(bool), "bool"},
|
||||
{typeof(sbyte), "sbyte"},
|
||||
{typeof(short), "short"},
|
||||
{typeof(int), "int"},
|
||||
{typeof(long), "long"},
|
||||
{typeof(byte), "byte"},
|
||||
{typeof(ushort), "ushort"},
|
||||
{typeof(uint), "uint"},
|
||||
{typeof(ulong), "ulong"},
|
||||
{typeof(float), "float"},
|
||||
{typeof(double), "double"},
|
||||
{typeof(decimal), "decimal"},
|
||||
{ typeof(bool), "bool" },
|
||||
{ typeof(sbyte), "sbyte" },
|
||||
{ typeof(short), "short" },
|
||||
{ typeof(int), "int" },
|
||||
{ typeof(long), "long" },
|
||||
{ typeof(byte), "byte" },
|
||||
{ typeof(ushort), "ushort" },
|
||||
{ typeof(uint), "uint" },
|
||||
{ typeof(ulong), "ulong" },
|
||||
{ typeof(float), "float" },
|
||||
{ typeof(double), "double" },
|
||||
{ typeof(decimal), "decimal" }
|
||||
};
|
||||
|
||||
private static void Init()
|
||||
{
|
||||
if (s_PropertyMenu != null) return;
|
||||
|
||||
const BindingFlags bindingFlags = BindingFlags.Public
|
||||
| BindingFlags.NonPublic
|
||||
| BindingFlags.Static
|
||||
| BindingFlags.GetProperty;
|
||||
var properties = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.SelectMany(assembly => assembly.GetTypes())
|
||||
.SelectMany(type => type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetProperty))
|
||||
.SelectMany(type => type.GetProperties(bindingFlags))
|
||||
.Where(pi => pi.GetMethod != null && s_SupportedTypes.ContainsKey(pi.PropertyType))
|
||||
.OrderBy(pi => ConvertToMenuItem(pi, false))
|
||||
.ToArray();
|
||||
|
||||
s_PropertyMenu = new GenericMenu();
|
||||
s_PropertyMenu.AddItem(new GUIContent("No Property"), false, arg => s_OnMenuSelected?.Invoke(arg as PropertyInfo), null);
|
||||
s_PropertyMenu.AddItem(new GUIContent("(Non Public Properties)/"), false, ()=>{});
|
||||
s_PropertyMenu.AddItem(new GUIContent("No Property"), false,
|
||||
arg => s_OnMenuSelected?.Invoke(arg as PropertyInfo), null);
|
||||
s_PropertyMenu.AddItem(new GUIContent("(Non Public Properties)/"), false, () => { });
|
||||
s_PropertyMenu.AddSeparator("");
|
||||
|
||||
foreach (var pi in properties)
|
||||
{
|
||||
s_PropertyMenu.AddItem(new GUIContent(ConvertToMenuItem(pi, true)), false, arg => s_OnMenuSelected?.Invoke(arg as PropertyInfo), pi);
|
||||
s_PropertyMenu.AddItem(new GUIContent(ConvertToMenuItem(pi, true)), false,
|
||||
arg => s_OnMenuSelected?.Invoke(arg as PropertyInfo), pi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,11 +62,17 @@ namespace Coffee.NanoMonitor
|
||||
{
|
||||
var type = p.DeclaringType;
|
||||
if (type == null) return "";
|
||||
var category = p.GetMethod.IsPublic && type.IsPublic ? "" : "(Non Public Properties)/";
|
||||
|
||||
var category = p.GetMethod.IsPublic && type.IsPublic
|
||||
? ""
|
||||
: "(Non Public Properties)/";
|
||||
var typeName = type.FullName;
|
||||
var asmName = type.Assembly.GetName().Name;
|
||||
if (asmName == "UnityEngine.CoreModule")
|
||||
{
|
||||
asmName = "UnityEngine";
|
||||
}
|
||||
|
||||
return propertyType
|
||||
? $"{category}{asmName}/{typeName}/{s_SupportedTypes[p.PropertyType]} {p.Name}"
|
||||
: $"{category}{asmName}/{typeName}/{p.Name}";
|
||||
@@ -84,7 +92,9 @@ namespace Coffee.NanoMonitor
|
||||
{
|
||||
s_OnMenuSelected = p =>
|
||||
{
|
||||
path.stringValue = p == null ? "" : $"{p.DeclaringType?.FullName}, {p.DeclaringType?.Assembly.GetName().Name};{p.Name}";
|
||||
path.stringValue = p == null
|
||||
? ""
|
||||
: $"{p.DeclaringType?.FullName}, {p.DeclaringType?.Assembly.GetName().Name};{p.Name}";
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
};
|
||||
s_PropertyMenu.DropDown(position);
|
||||
@@ -104,6 +114,22 @@ namespace Coffee.NanoMonitor
|
||||
[SerializeField] private string m_Path = "";
|
||||
|
||||
|
||||
//################################
|
||||
// Private Members.
|
||||
//################################
|
||||
private Func<double> _get;
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
var pInfo = GetPropertyInfo(m_Path);
|
||||
_get = CreateFunc(pInfo?.GetMethod);
|
||||
}
|
||||
|
||||
|
||||
//################################
|
||||
// Public Members.
|
||||
//################################
|
||||
@@ -112,12 +138,6 @@ namespace Coffee.NanoMonitor
|
||||
return _get?.Invoke() ?? -1;
|
||||
}
|
||||
|
||||
|
||||
//################################
|
||||
// Private Members.
|
||||
//################################
|
||||
private Func<double> _get = null;
|
||||
|
||||
private static PropertyInfo GetPropertyInfo(string path)
|
||||
{
|
||||
var p = path.Split(';');
|
||||
@@ -126,14 +146,14 @@ namespace Coffee.NanoMonitor
|
||||
var type = Type.GetType(p[0]);
|
||||
if (type == null)
|
||||
{
|
||||
UnityEngine.Debug.LogException(new Exception($"Type '{p[0]}' is not found"));
|
||||
Debug.LogException(new Exception($"Type '{p[0]}' is not found"));
|
||||
return null;
|
||||
}
|
||||
|
||||
var pInfo = type.GetProperty(p[1], BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Static);
|
||||
if (pInfo == null)
|
||||
{
|
||||
UnityEngine.Debug.LogException(new Exception($"Member '{p[1]}' is not found in type '{type}'"));
|
||||
Debug.LogException(new Exception($"Member '{p[1]}' is not found in type '{type}'"));
|
||||
}
|
||||
|
||||
return pInfo;
|
||||
@@ -145,55 +165,72 @@ namespace Coffee.NanoMonitor
|
||||
switch (Type.GetTypeCode(mInfo.ReturnType))
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
var f_bool = (Func<bool>) mInfo.CreateDelegate(typeof(Func<bool>));
|
||||
return () => f_bool() ? 1 : 0;
|
||||
{
|
||||
var func = (Func<bool>)mInfo.CreateDelegate(typeof(Func<bool>));
|
||||
return () => func() ? 1 : 0;
|
||||
}
|
||||
case TypeCode.Byte:
|
||||
var f_byte = (Func<byte>) mInfo.CreateDelegate(typeof(Func<byte>));
|
||||
return () => f_byte();
|
||||
{
|
||||
var func = (Func<byte>)mInfo.CreateDelegate(typeof(Func<byte>));
|
||||
return () => func();
|
||||
}
|
||||
case TypeCode.SByte:
|
||||
var f_sbyte = (Func<sbyte>) mInfo.CreateDelegate(typeof(Func<sbyte>));
|
||||
return () => f_sbyte();
|
||||
{
|
||||
var func = (Func<sbyte>)mInfo.CreateDelegate(typeof(Func<sbyte>));
|
||||
return () => func();
|
||||
}
|
||||
case TypeCode.UInt16:
|
||||
var f_ushort = (Func<ushort>) mInfo.CreateDelegate(typeof(Func<ushort>));
|
||||
return () => f_ushort();
|
||||
{
|
||||
var func = (Func<ushort>)mInfo.CreateDelegate(typeof(Func<ushort>));
|
||||
return () => func();
|
||||
}
|
||||
case TypeCode.UInt32:
|
||||
var f_uint = (Func<uint>) mInfo.CreateDelegate(typeof(Func<uint>));
|
||||
return () => f_uint();
|
||||
{
|
||||
var func = (Func<uint>)mInfo.CreateDelegate(typeof(Func<uint>));
|
||||
return () => func();
|
||||
}
|
||||
case TypeCode.UInt64:
|
||||
var f_ulong = (Func<ulong>) mInfo.CreateDelegate(typeof(Func<ulong>));
|
||||
return () => f_ulong();
|
||||
{
|
||||
var func = (Func<ulong>)mInfo.CreateDelegate(typeof(Func<ulong>));
|
||||
return () => func();
|
||||
}
|
||||
case TypeCode.Int16:
|
||||
var f_short = (Func<short>) mInfo.CreateDelegate(typeof(Func<short>));
|
||||
return () => f_short();
|
||||
{
|
||||
var func = (Func<short>)mInfo.CreateDelegate(typeof(Func<short>));
|
||||
return () => func();
|
||||
}
|
||||
case TypeCode.Int32:
|
||||
var f_int = (Func<int>) mInfo.CreateDelegate(typeof(Func<int>));
|
||||
return () => f_int();
|
||||
{
|
||||
var f = (Func<int>)mInfo.CreateDelegate(typeof(Func<int>));
|
||||
return () => f();
|
||||
}
|
||||
case TypeCode.Int64:
|
||||
var f_long = (Func<long>) mInfo.CreateDelegate(typeof(Func<long>));
|
||||
return () => f_long();
|
||||
{
|
||||
var f = (Func<long>)mInfo.CreateDelegate(typeof(Func<long>));
|
||||
return () => f();
|
||||
}
|
||||
case TypeCode.Decimal:
|
||||
var f_decimal = (Func<decimal>) mInfo.CreateDelegate(typeof(Func<decimal>));
|
||||
return () => (double) f_decimal();
|
||||
{
|
||||
var f = (Func<decimal>)mInfo.CreateDelegate(typeof(Func<decimal>));
|
||||
return () => (double)f();
|
||||
}
|
||||
case TypeCode.Double:
|
||||
var f_double = (Func<double>) mInfo.CreateDelegate(typeof(Func<double>));
|
||||
return f_double;
|
||||
{
|
||||
var f = (Func<double>)mInfo.CreateDelegate(typeof(Func<double>));
|
||||
return f;
|
||||
}
|
||||
case TypeCode.Single:
|
||||
var f_float = (Func<float>) mInfo.CreateDelegate(typeof(Func<float>));
|
||||
return () => f_float();
|
||||
{
|
||||
var f = (Func<float>)mInfo.CreateDelegate(typeof(Func<float>));
|
||||
return () => f();
|
||||
}
|
||||
default:
|
||||
UnityEngine.Debug.LogException(new Exception(string.Format("Method '{1}.{0}' is not supported.", mInfo.Name, mInfo.DeclaringType)));
|
||||
{
|
||||
var message = $"Method '{mInfo.DeclaringType}.{mInfo.Name} ({mInfo.ReturnType})' is not supported.";
|
||||
Debug.LogException(new Exception(message));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
var pInfo = GetPropertyInfo(m_Path);
|
||||
_get = CreateFunc(pInfo?.GetMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@ namespace Coffee.NanoMonitor
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void AppendFormatNoAlloc(this StringBuilder sb, string format, double arg0 = 0, double arg1 = 0, double arg2 = 0, double arg3 = 0)
|
||||
public static void AppendFormatNoAlloc(this StringBuilder sb, string format, double arg0 = 0, double arg1 = 0,
|
||||
double arg2 = 0, double arg3 = 0)
|
||||
{
|
||||
for (var i = 0; i < format.Length; i++)
|
||||
{
|
||||
@@ -56,7 +57,7 @@ namespace Coffee.NanoMonitor
|
||||
}
|
||||
}
|
||||
|
||||
internal static void AppendInteger(this StringBuilder sb, double number, int padding, int precision, int alignment)
|
||||
private static void AppendInteger(this StringBuilder sb, double number, int padding, int alignment)
|
||||
{
|
||||
number = Math.Truncate(number);
|
||||
var sign = number < 0;
|
||||
@@ -68,8 +69,8 @@ namespace Coffee.NanoMonitor
|
||||
var n = Math.Truncate(number % 10);
|
||||
number /= 10;
|
||||
|
||||
sb.Append((char) (n + 48));
|
||||
} while (1 <= number || (sb.Length - startIndex) < padding);
|
||||
sb.Append((char)(n + 48));
|
||||
} while (1 <= number || sb.Length - startIndex < padding);
|
||||
|
||||
if (sign)
|
||||
{
|
||||
@@ -82,11 +83,12 @@ namespace Coffee.NanoMonitor
|
||||
sb.Alignment(alignment, startIndex, endIndex);
|
||||
}
|
||||
|
||||
internal static void AppendDouble(this StringBuilder sb, double number, int padding, int precision, int alignment)
|
||||
private static void AppendDouble(this StringBuilder sb, double number, int padding, int precision,
|
||||
int alignment)
|
||||
{
|
||||
var integer = Math.Truncate(number);
|
||||
var startIndex = sb.Length;
|
||||
sb.AppendInteger(integer, padding, precision, 0);
|
||||
sb.AppendInteger(integer, padding, 0);
|
||||
|
||||
if (0 < precision)
|
||||
{
|
||||
@@ -96,8 +98,8 @@ namespace Coffee.NanoMonitor
|
||||
for (var p = 0; p < precision; p++)
|
||||
{
|
||||
number *= 10;
|
||||
integer = (long) number;
|
||||
sb.Append((char) (integer + 48));
|
||||
integer = (long)number;
|
||||
sb.Append((char)(integer + 48));
|
||||
number -= integer;
|
||||
number = Math.Round(number, precision);
|
||||
}
|
||||
@@ -106,20 +108,18 @@ namespace Coffee.NanoMonitor
|
||||
sb.Alignment(alignment, startIndex, sb.Length - 1);
|
||||
}
|
||||
|
||||
internal static void Reverse(this StringBuilder sb, int start, int end)
|
||||
private static void Reverse(this StringBuilder sb, int start, int end)
|
||||
{
|
||||
while (start < end)
|
||||
{
|
||||
var c = sb[start];
|
||||
sb[start] = sb[end];
|
||||
sb[end] = c;
|
||||
|
||||
// swap
|
||||
(sb[start], sb[end]) = (sb[end], sb[start]);
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Alignment(this StringBuilder sb, int alignment, int start, int end)
|
||||
private static void Alignment(this StringBuilder sb, int alignment, int start, int end)
|
||||
{
|
||||
if (alignment == 0) return;
|
||||
|
||||
@@ -129,9 +129,8 @@ namespace Coffee.NanoMonitor
|
||||
sb.Append(' ', alignment - len);
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
var c = sb[end - i];
|
||||
sb[end - i] = sb[start + alignment - i - 1];
|
||||
sb[start + alignment - i - 1] = c;
|
||||
// swap
|
||||
(sb[end - i], sb[start + alignment - i - 1]) = (sb[start + alignment - i - 1], sb[end - i]);
|
||||
}
|
||||
}
|
||||
else if (alignment < 0 && len < -alignment)
|
||||
@@ -140,7 +139,8 @@ namespace Coffee.NanoMonitor
|
||||
}
|
||||
}
|
||||
|
||||
internal static int GetFormat(string format, int i, out int argIndex, out int padding, out int precision, out int alignment)
|
||||
private static int GetFormat(string format, int i, out int argIndex, out int padding, out int precision,
|
||||
out int alignment)
|
||||
{
|
||||
argIndex = -1;
|
||||
padding = 0;
|
||||
|
||||
Reference in New Issue
Block a user