/* * This file is part of the CatLib package. * * (c) CatLib * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * * Document: http://catlib.io/ */ using System; using System.Collections.Generic; using System.Reflection; using UnityEditor; using UnityEngine; namespace CatLib.Editor { /// /// 框架入口可视化图形界面 /// [CustomEditor(typeof(Framework), true)] public class InspectorFramework : UnityEditor.Editor { /// /// 调试等级 /// private SerializedProperty debugLevel; /// /// 已经安装了的服务提供者列表 /// private readonly Dictionary serviceProviders = new Dictionary(); /// /// 绘图界面时 /// public override void OnInspectorGUI() { var framework = (Framework)target; serializedObject.Update(); DrawLogo(); DrawDebugLevels(framework); DrawServiceProvider(framework, serviceProviders); serializedObject.ApplyModifiedProperties(); } /// /// 显示时 /// public void OnEnable() { debugLevel = serializedObject.FindProperty("DebugLevel"); RefreshServiceProviders(); } /// /// 绘制标题 /// private static void DrawLogo() { EditorGUILayout.Separator(); GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("CatLib Framework (" + App.Version + ")", EditorStyles.largeLabel, GUILayout.Height(20)); GUILayout.EndHorizontal(); } /// /// 绘制调试等级 /// private void DrawDebugLevels(Framework framework) { var old = debugLevel.enumValueIndex; GUILayout.BeginHorizontal(); debugLevel.enumValueIndex = (int)(DebugLevels)EditorGUILayout.EnumPopup("Debug Level", (DebugLevels)debugLevel.enumValueIndex, EditorStyles.popup); GUILayout.EndHorizontal(); if (old == debugLevel.enumValueIndex) { return; } if (framework.Application != null) { framework.Application.DebugLevel = (DebugLevels)debugLevel.enumValueIndex; } } /// /// 绘制服务提供者 /// /// 根节点信息 /// 服务提供者列表 private void DrawServiceProvider(Component root, IDictionary serviceProviders) { GUILayout.Space(5); if (EditorApplication.isPlaying) { InspectorTool.LabelBox("GUI Service Providers:", () => { EditorGUILayout.HelpBox("Only be modified if it stops running", MessageType.Info); }); return; } var reload = false; InspectorTool.LabelBox("GUI Service Providers:", () => { if (serviceProviders.Count <= 0) { EditorGUILayout.HelpBox("No optional service provider", MessageType.Info); return; } foreach (var providerAndGameObject in serviceProviders) { var enable = providerAndGameObject.Value != null; InspectorTool.Horizontal(() => { reload = ToggleProvider(root.gameObject, providerAndGameObject.Key, providerAndGameObject.Value) != enable || reload; if (InspectorTool.Button("Go", "Goto The GameObject", enable, 40, 16) && enable) { Selection.activeObject = providerAndGameObject.Value; } }); } }); if (reload) { RefreshServiceProviders(); } } /// /// 服务提供者开关 /// /// 根节点 /// 服务提供者类型 /// 宿主对象 private bool ToggleProvider(GameObject root, Type providerType, Component master) { if (EditorGUILayout.ToggleLeft(providerType.Name, master != null)) { if (master == null) { CreateServiceProvider(providerType, root); } return true; } if (master == null) { return false; } if (root == master.gameObject) { EditorUtility.DisplayDialog("Failure", providerType.Name + " is located in the main game object, please manually delete the script", "Ok"); return true; } if (!EditorUtility.DisplayDialog("Deleting", "The " + providerType.Name + " will be Deleted"+ Environment.NewLine + "Configuration will be lost", "Delete", "Cancel")) { return true; } DestroyImmediate(master.gameObject); return false; } /// /// 创建服务提供者 /// /// 根节点 /// 服务提供者类型 private static void CreateServiceProvider(Type providerType, GameObject root) { var go = new GameObject(providerType.Name); go.transform.parent = root.transform; go.AddComponent(providerType); } /// /// 刷新服务提供者信息 /// private void RefreshServiceProviders() { serviceProviders.Clear(); LoadAllServiceProviders(serviceProviders); LoadInstalledServiceProviders(serviceProviders, (Component)target); } /// /// 获取已经安装了的服务提供者 /// /// 结果集 /// 扫描的根组件 /// 安装关系字典 private static void LoadInstalledServiceProviders(IDictionary result, Component target) { foreach (var serviceProvider in target.gameObject.GetComponentsInChildren()) { result[serviceProvider.GetType()] = (Component)serviceProvider; } } /// /// 获取GUI支持的服务提供者 /// /// 编辑器框架 private static void LoadAllServiceProviders(IDictionary result) { var targetProvider = typeof(IServiceProvider); var targetComponent = typeof(Component); var assembiles = Arr.Filter(AppDomain.CurrentDomain.GetAssemblies(), TestCheckInAssembiles); foreach (var assembly in assembiles) { foreach (var type in assembly.GetTypes()) { if (targetProvider.IsAssignableFrom(type) && targetComponent.IsAssignableFrom(type)) { result.Add(type, null); } } } } /// /// 需要忽略的程序集 /// private static readonly string[] ignoreAssembiles = new string[] { "mscorlib", "UnityEngine", "UnityEditor", "netstandard", "nunit.framework", "System", "ExCSS.Unity", "CatLib.Core", "UnityEditor.*", "UnityEngine.*", "*-Editor", "*.Editor", "System.*", "Mono.*", "Unity.*", "SyntaxTree.*", "Microsoft.*", }; /// /// 测试是否处于需要检查的程序集列表 /// /// 测试程序集 /// 是否处于忽略程序集列表 private static bool TestCheckInAssembiles(Assembly assembly) { foreach (var pattern in ignoreAssembiles) { if (Str.Is(pattern, assembly.GetName().Name)) { return false; } } return true; } } }