com.guru.unity.sdk/Runtime/Debugger/Runtime/Code/Core/Debugger.cs

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