291 lines
7.9 KiB
C#
291 lines
7.9 KiB
C#
|
|
|
|
namespace Guru
|
|
{
|
|
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using G = GlobalVars;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
|
|
public class Debugger
|
|
{
|
|
public const string Version = "1.0.0";
|
|
private static bool _initOnce = false;
|
|
private static Debugger _instance;
|
|
public static Debugger Instance
|
|
{
|
|
get
|
|
{
|
|
if (_instance == null)
|
|
{
|
|
Init();
|
|
}
|
|
return _instance;
|
|
}
|
|
}
|
|
|
|
public static event Action OnClosed
|
|
{
|
|
add
|
|
{
|
|
if (_onViewClosed == null)
|
|
{
|
|
_onViewClosed = value;
|
|
}
|
|
else
|
|
{
|
|
_onViewClosed += value;
|
|
}
|
|
}
|
|
|
|
remove
|
|
{
|
|
if (_onViewClosed != null)
|
|
{
|
|
_onViewClosed -= value;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static Action _onViewClosed;
|
|
|
|
private DebuggerViewRoot _viewRoot;
|
|
private Dictionary<string, List<OptionLayout>> optionDicts;
|
|
private string _curTabName;
|
|
|
|
public static void Init()
|
|
{
|
|
if (_instance == null) _initOnce = false;
|
|
|
|
if (_initOnce) return;
|
|
_initOnce = true;
|
|
_instance = new Debugger();
|
|
_instance.StartService();
|
|
}
|
|
|
|
private void StartService()
|
|
{
|
|
_viewRoot = DebuggerViewRoot.Instance;
|
|
optionDicts = new Dictionary<string, List<OptionLayout>>(5);
|
|
G.Events.OnUIEvent += OnUIEvent;
|
|
}
|
|
|
|
private void OnUIEvent(string evt, object data)
|
|
{
|
|
switch (evt)
|
|
{
|
|
case G.Events.EventTabClicked:
|
|
OnSelectTab(data.ToString());
|
|
break;
|
|
case G.Events.EventViewClosed:
|
|
optionDicts?.Clear();
|
|
_onViewClosed?.Invoke();
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
#region UI Layout
|
|
|
|
public OptionLayout AddOption(string uri, string content = "", Action clickHandler = null)
|
|
{
|
|
string tabName = G.Consts.DefaultTabName;
|
|
string optName = G.Consts.DefaultOptionName;
|
|
if (uri.Contains("/"))
|
|
{
|
|
var names = uri.Split('/');
|
|
if (names.Length > 0)
|
|
{
|
|
tabName = names[0];
|
|
}
|
|
if(names.Length > 1) optName = names[1];
|
|
}
|
|
|
|
if (!optionDicts.ContainsKey(tabName))
|
|
{
|
|
optionDicts[tabName] = new List<OptionLayout>(10);
|
|
}
|
|
|
|
OptionLayout opt = new OptionLayout();
|
|
opt.tabName = tabName;
|
|
opt.optName = optName;
|
|
opt.content = content;
|
|
opt.selfClickHandler = clickHandler;
|
|
|
|
AddOptionLayout(tabName, opt);
|
|
|
|
return opt;
|
|
}
|
|
|
|
private void AddOptionLayout(string tabName, OptionLayout layout)
|
|
{
|
|
if (!optionDicts.ContainsKey(tabName))
|
|
{
|
|
optionDicts[tabName] = new List<OptionLayout>(20);
|
|
}
|
|
|
|
optionDicts[tabName].Add(layout);
|
|
}
|
|
|
|
|
|
public void ShowPage(string tabName = "")
|
|
{
|
|
if (string.IsNullOrEmpty(tabName)
|
|
&& optionDicts != null && optionDicts.Count > 0)
|
|
{
|
|
tabName = optionDicts.Keys.First();
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(tabName))
|
|
{
|
|
RenderPage(tabName);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 渲染页面
|
|
/// </summary>
|
|
/// <param name="tabName"></param>
|
|
private void RenderPage(string tabName)
|
|
{
|
|
if (string.IsNullOrEmpty(tabName)) return;
|
|
|
|
_viewRoot.Show();
|
|
_viewRoot.RefreshTabs(tabName, optionDicts.Keys.ToList());
|
|
_viewRoot.CleanOptions();
|
|
if (optionDicts.TryGetValue(tabName, out var opts))
|
|
{
|
|
OptionLayout ol;
|
|
UIOptionItem ui;
|
|
for (int i = 0; i < opts.Count; i++)
|
|
{
|
|
ol = opts[i];
|
|
ui = _viewRoot.RegisterOption(ol.optName, ol.content);
|
|
|
|
if (ol.selfClickHandler != null)
|
|
{
|
|
var btnName = ol.content;
|
|
if (string.IsNullOrEmpty(btnName)) btnName = ol.optName;
|
|
var btn = _viewRoot.AddOptionButton(ui, btnName, ol.selfClickHandler);
|
|
ui.Clickable = true;
|
|
continue;
|
|
}
|
|
|
|
foreach (var item in ol.items)
|
|
{
|
|
switch (item.type)
|
|
{
|
|
case "button":
|
|
var btn = _viewRoot.AddOptionButton(ui, item.name, item.clickHandler);
|
|
if (!item.size.Equals(Vector2.zero)) btn.Size = item.size;
|
|
break;
|
|
|
|
case "label":
|
|
var lb = _viewRoot.AddOptionLabel(ui, item.name, item.align);
|
|
if (!item.size.Equals(Vector2.zero)) lb.Size = item.size;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"{tabName} not found!");
|
|
}
|
|
|
|
}
|
|
|
|
|
|
private void OnSelectTab(string tabName)
|
|
{
|
|
if (_curTabName == tabName) return;
|
|
Instance.ShowPage(tabName);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Display
|
|
|
|
public static void Show(string tabName = "")
|
|
{
|
|
Instance.ShowPage(tabName);
|
|
}
|
|
|
|
public static void Hide() => Instance._viewRoot.Hide();
|
|
|
|
#endregion
|
|
|
|
#region DebuggerOption
|
|
|
|
public class OptionLayout
|
|
{
|
|
public string optName;
|
|
public string content;
|
|
public string tabName;
|
|
public Action selfClickHandler;
|
|
|
|
internal List<OptionItemLayout> items;
|
|
|
|
|
|
public OptionLayout()
|
|
{
|
|
items = new List<OptionItemLayout>(10);
|
|
}
|
|
|
|
|
|
public OptionLayout AddLabel(string labelName)
|
|
{
|
|
items.Add(new OptionItemLayout()
|
|
{
|
|
name = labelName,
|
|
type = "label",
|
|
});
|
|
return this;
|
|
}
|
|
|
|
public OptionLayout AddButton(string btnName, Action onClick)
|
|
{
|
|
items.Add(new OptionItemLayout()
|
|
{
|
|
name = btnName,
|
|
type = "button",
|
|
clickHandler = onClick
|
|
});
|
|
return this;
|
|
}
|
|
}
|
|
|
|
internal class OptionItemLayout
|
|
{
|
|
public string type;
|
|
public Action clickHandler;
|
|
public string name;
|
|
public string content;
|
|
public TextAnchor align = TextAnchor.MiddleCenter;
|
|
public Vector2 size = Vector2.zero;
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
|
|
public static class OptionLayoutExtension
|
|
{
|
|
public static Debugger.OptionLayout AddCopyButton(this Debugger.OptionLayout layout, Action onClick = null)
|
|
{
|
|
layout.AddButton("Copy", ()=>
|
|
{
|
|
GUIUtility.systemCopyBuffer = layout.content;
|
|
onClick?.Invoke();
|
|
});
|
|
return layout;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
} |