Update
This commit is contained in:
ALEXTANG
2023-04-03 14:05:14 +08:00
parent db425ff58a
commit 212f4192ac
378 changed files with 11605 additions and 21 deletions

View File

@@ -213,6 +213,49 @@ Transform:
m_Father: {fileID: 2061060682}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1176880017
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1176880018}
- component: {fileID: 1176880019}
m_Layer: 0
m_Name: ObjectPool
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1176880018
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1176880017}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 2061060682}
m_RootOrder: 5
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1176880019
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1176880017}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: da10a6ed68a3439b8a2df5384febd504, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &1513514422
GameObject:
m_ObjectHideFlags: 0
@@ -222,6 +265,7 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 1513514423}
- component: {fileID: 1513514424}
m_Layer: 0
m_Name: Setting
m_TagString: Untagged
@@ -243,6 +287,20 @@ Transform:
m_Father: {fileID: 2061060682}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1513514424
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1513514422}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 352db63f3a7b449bac6e5de8bb32141a, type: 3}
m_Name:
m_EditorClassIdentifier:
m_SettingHelperTypeName: TEngine.PlayerPrefsSettingHelper
m_CustomSettingHelper: {fileID: 0}
--- !u!1 &1947304784
GameObject:
m_ObjectHideFlags: 0
@@ -272,7 +330,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 2061060682}
m_RootOrder: 4
m_RootOrder: 6
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1947304786
MonoBehaviour:
@@ -370,6 +428,49 @@ Transform:
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &2049602905
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2049602906}
- component: {fileID: 2049602907}
m_Layer: 0
m_Name: Resource
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2049602906
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2049602905}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 2061060682}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2049602907
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2049602905}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 77d67944806247f99024bf5307adc918, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &2061060681
GameObject:
m_ObjectHideFlags: 0
@@ -402,6 +503,8 @@ Transform:
- {fileID: 43232120}
- {fileID: 23410075}
- {fileID: 1513514423}
- {fileID: 2049602906}
- {fileID: 1176880018}
- {fileID: 1947304785}
- {fileID: 2108959336}
m_Father: {fileID: 0}
@@ -438,6 +541,7 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 2108959336}
- component: {fileID: 2108959337}
m_Layer: 0
m_Name: Debugger
m_TagString: Untagged
@@ -457,5 +561,39 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 2061060682}
m_RootOrder: 5
m_RootOrder: 7
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2108959337
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2108959335}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d58978a9ed0f473ca3cc5a302c3bf87b, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Skin: {fileID: 11400000, guid: a06a4c0455d3ccb45baf4d805cab535a, type: 2}
m_ActiveWindow: 0
m_ShowFullWindow: 0
m_ConsoleWindow:
m_LockScroll: 1
m_MaxLine: 100
m_InfoFilter: 1
m_WarningFilter: 1
m_ErrorFilter: 1
m_FatalFilter: 1
m_InfoColor:
serializedVersion: 2
rgba: 4294967295
m_WarningColor:
serializedVersion: 2
rgba: 4278512639
m_ErrorColor:
serializedVersion: 2
rgba: 4278190335
m_FatalColor:
serializedVersion: 2
rgba: 4281545650

View File

@@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
namespace TEngine.Editor.Inspector
{
[CustomEditor(typeof(ObjectPoolComponent))]
internal sealed class ObjectPoolComponentInspector : GameFrameworkInspector
{
private readonly HashSet<string> m_OpenedItems = new HashSet<string>();
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (!EditorApplication.isPlaying)
{
EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
return;
}
ObjectPoolComponent t = (ObjectPoolComponent)target;
if (IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Object Pool Count", t.Count.ToString());
ObjectPoolBase[] objectPools = t.GetAllObjectPools(true);
foreach (ObjectPoolBase objectPool in objectPools)
{
DrawObjectPool(objectPool);
}
}
Repaint();
}
private void OnEnable()
{
}
private void DrawObjectPool(ObjectPoolBase objectPool)
{
bool lastState = m_OpenedItems.Contains(objectPool.FullName);
bool currentState = EditorGUILayout.Foldout(lastState, objectPool.FullName);
if (currentState != lastState)
{
if (currentState)
{
m_OpenedItems.Add(objectPool.FullName);
}
else
{
m_OpenedItems.Remove(objectPool.FullName);
}
}
if (currentState)
{
EditorGUILayout.BeginVertical("box");
{
EditorGUILayout.LabelField("Name", objectPool.Name);
EditorGUILayout.LabelField("Type", objectPool.ObjectType.FullName);
EditorGUILayout.LabelField("Auto Release Interval", objectPool.AutoReleaseInterval.ToString());
EditorGUILayout.LabelField("Capacity", objectPool.Capacity.ToString());
EditorGUILayout.LabelField("Used Count", objectPool.Count.ToString());
EditorGUILayout.LabelField("Can Release Count", objectPool.CanReleaseCount.ToString());
EditorGUILayout.LabelField("Expire Time", objectPool.ExpireTime.ToString());
EditorGUILayout.LabelField("Priority", objectPool.Priority.ToString());
ObjectInfo[] objectInfos = objectPool.GetAllObjectInfos();
if (objectInfos.Length > 0)
{
EditorGUILayout.LabelField("Name",
objectPool.AllowMultiSpawn ? "Locked\tCount\tFlag\tPriority\tLast Use Time" : "Locked\tIn Use\tFlag\tPriority\tLast Use Time");
foreach (ObjectInfo objectInfo in objectInfos)
{
EditorGUILayout.LabelField(string.IsNullOrEmpty(objectInfo.Name) ? "<None>" : objectInfo.Name,
objectPool.AllowMultiSpawn
? Utility.Text.Format("{0}\t{1}\t{2}\t{3}\t{4:yyyy-MM-dd HH:mm:ss}", objectInfo.Locked, objectInfo.SpawnCount, objectInfo.CustomCanReleaseFlag,
objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime())
: Utility.Text.Format("{0}\t{1}\t{2}\t{3}\t{4:yyyy-MM-dd HH:mm:ss}", objectInfo.Locked, objectInfo.IsInUse, objectInfo.CustomCanReleaseFlag,
objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime()));
}
if (GUILayout.Button("Release"))
{
objectPool.Release();
}
if (GUILayout.Button("Release All Unused"))
{
objectPool.ReleaseAllUnused();
}
if (GUILayout.Button("Export CSV Data"))
{
string exportFileName = EditorUtility.SaveFilePanel("Export CSV Data", string.Empty, Utility.Text.Format("Object Pool Data - {0}.csv", objectPool.Name),
string.Empty);
if (!string.IsNullOrEmpty(exportFileName))
{
try
{
int index = 0;
string[] data = new string[objectInfos.Length + 1];
data[index++] = Utility.Text.Format("Name,Locked,{0},Custom Can Release Flag,Priority,Last Use Time",
objectPool.AllowMultiSpawn ? "Count" : "In Use");
foreach (ObjectInfo objectInfo in objectInfos)
{
data[index++] = objectPool.AllowMultiSpawn
? Utility.Text.Format("{0},{1},{2},{3},{4},{5:yyyy-MM-dd HH:mm:ss}", objectInfo.Name, objectInfo.Locked, objectInfo.SpawnCount,
objectInfo.CustomCanReleaseFlag, objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime())
: Utility.Text.Format("{0},{1},{2},{3},{4},{5:yyyy-MM-dd HH:mm:ss}", objectInfo.Name, objectInfo.Locked, objectInfo.IsInUse,
objectInfo.CustomCanReleaseFlag, objectInfo.Priority, objectInfo.LastUseTime.ToLocalTime());
}
File.WriteAllLines(exportFileName, data, Encoding.UTF8);
Debug.Log(Utility.Text.Format("Export object pool CSV data to '{0}' success.", exportFileName));
}
catch (Exception exception)
{
Debug.LogError(Utility.Text.Format("Export object pool CSV data to '{0}' failure, exception is '{1}'.", exportFileName, exception));
}
}
}
}
else
{
GUILayout.Label("Object Pool is Empty ...");
}
}
EditorGUILayout.EndVertical();
EditorGUILayout.Separator();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 19febee9477a4fbabaa6edb9ea6b6a00
timeCreated: 1680501264

View File

@@ -0,0 +1,73 @@
using UnityEditor;
using UnityEngine;
namespace TEngine.Editor.Inspector
{
[CustomEditor(typeof(SettingComponent))]
internal sealed class SettingComponentInspector : GameFrameworkInspector
{
private HelperInfo<SettingHelperBase> m_SettingHelperInfo = new HelperInfo<SettingHelperBase>("Setting");
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
SettingComponent t = (SettingComponent)target;
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
{
m_SettingHelperInfo.Draw();
}
EditorGUI.EndDisabledGroup();
if (EditorApplication.isPlaying && IsPrefabInHierarchy(t.gameObject))
{
EditorGUILayout.LabelField("Setting Count", t.Count >= 0 ? t.Count.ToString() : "<Unknown>");
if (t.Count > 0)
{
string[] settingNames = t.GetAllSettingNames();
foreach (string settingName in settingNames)
{
EditorGUILayout.LabelField(settingName, t.GetString(settingName));
}
}
}
if (EditorApplication.isPlaying)
{
if (GUILayout.Button("Save Settings"))
{
t.Save();
}
if (GUILayout.Button("Remove All Settings"))
{
t.RemoveAllSettings();
}
}
serializedObject.ApplyModifiedProperties();
Repaint();
}
protected override void OnCompileComplete()
{
base.OnCompileComplete();
RefreshTypeNames();
}
private void OnEnable()
{
m_SettingHelperInfo.Init(serializedObject);
RefreshTypeNames();
}
private void RefreshTypeNames()
{
m_SettingHelperInfo.Refresh();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 74b840f402134b97b07f730eb60228f6
timeCreated: 1680494479

View File

@@ -0,0 +1,89 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
namespace TEngine.Editor
{
internal sealed class HelperInfo<T> where T : MonoBehaviour
{
private const string CustomOptionName = "<Custom>";
private readonly string m_Name;
private SerializedProperty m_HelperTypeName;
private SerializedProperty m_CustomHelper;
private string[] m_HelperTypeNames;
private int m_HelperTypeNameIndex;
public HelperInfo(string name)
{
m_Name = name;
m_HelperTypeName = null;
m_CustomHelper = null;
m_HelperTypeNames = null;
m_HelperTypeNameIndex = 0;
}
public void Init(SerializedObject serializedObject)
{
m_HelperTypeName = serializedObject.FindProperty(Utility.Text.Format("m_{0}HelperTypeName", m_Name));
m_CustomHelper = serializedObject.FindProperty(Utility.Text.Format("m_Custom{0}Helper", m_Name));
}
public void Draw()
{
string displayName = FieldNameForDisplay(m_Name);
int selectedIndex = EditorGUILayout.Popup(Utility.Text.Format("{0} Helper", displayName), m_HelperTypeNameIndex, m_HelperTypeNames);
if (selectedIndex != m_HelperTypeNameIndex)
{
m_HelperTypeNameIndex = selectedIndex;
m_HelperTypeName.stringValue = selectedIndex <= 0 ? null : m_HelperTypeNames[selectedIndex];
}
if (m_HelperTypeNameIndex <= 0)
{
EditorGUILayout.PropertyField(m_CustomHelper);
if (m_CustomHelper.objectReferenceValue == null)
{
EditorGUILayout.HelpBox(Utility.Text.Format("You must set Custom {0} Helper.", displayName), MessageType.Error);
}
}
}
public void Refresh()
{
List<string> helperTypeNameList = new List<string>
{
CustomOptionName
};
helperTypeNameList.AddRange(Type.GetRuntimeTypeNames(typeof(T)));
m_HelperTypeNames = helperTypeNameList.ToArray();
m_HelperTypeNameIndex = 0;
if (!string.IsNullOrEmpty(m_HelperTypeName.stringValue))
{
m_HelperTypeNameIndex = helperTypeNameList.IndexOf(m_HelperTypeName.stringValue);
if (m_HelperTypeNameIndex <= 0)
{
m_HelperTypeNameIndex = 0;
m_HelperTypeName.stringValue = null;
}
}
}
private string FieldNameForDisplay(string fieldName)
{
if (string.IsNullOrEmpty(fieldName))
{
return string.Empty;
}
string str = Regex.Replace(fieldName, @"^m_", string.Empty);
str = Regex.Replace(str, @"((?<=[a-z])[A-Z]|[A-Z](?=[a-z]))", @" $1").TrimStart();
return str;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d2341dcdab9f45559064663e38061622
timeCreated: 1680494517

View File

@@ -40,7 +40,7 @@ namespace TEngine.Editor
/// <summary>
/// 禁用所有日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Log Scripting Define Symbols/Disable All Logs", false, 30)]
[MenuItem("TEngine/Log Scripting Define Symbols/Disable All Logs", false, 30)]
public static void DisableAllLogs()
{
ScriptingDefineSymbols.RemoveScriptingDefineSymbol(EnableLogScriptingDefineSymbol);
@@ -59,7 +59,7 @@ namespace TEngine.Editor
/// <summary>
/// 开启所有日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Log Scripting Define Symbols/Enable All Logs", false, 31)]
[MenuItem("TEngine/Log Scripting Define Symbols/Enable All Logs", false, 31)]
public static void EnableAllLogs()
{
DisableAllLogs();
@@ -69,7 +69,7 @@ namespace TEngine.Editor
/// <summary>
/// 开启调试及以上级别的日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Log Scripting Define Symbols/Enable Debug And Above Logs", false, 32)]
[MenuItem("TEngine/Log Scripting Define Symbols/Enable Debug And Above Logs", false, 32)]
public static void EnableDebugAndAboveLogs()
{
SetAboveLogScriptingDefineSymbol(EnableDebugAndAboveLogScriptingDefineSymbol);
@@ -78,7 +78,7 @@ namespace TEngine.Editor
/// <summary>
/// 开启信息及以上级别的日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Log Scripting Define Symbols/Enable Info And Above Logs", false, 33)]
[MenuItem("TEngine/Log Scripting Define Symbols/Enable Info And Above Logs", false, 33)]
public static void EnableInfoAndAboveLogs()
{
SetAboveLogScriptingDefineSymbol(EnableInfoAndAboveLogScriptingDefineSymbol);
@@ -87,7 +87,7 @@ namespace TEngine.Editor
/// <summary>
/// 开启警告及以上级别的日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Log Scripting Define Symbols/Enable Warning And Above Logs", false, 34)]
[MenuItem("TEngine/Log Scripting Define Symbols/Enable Warning And Above Logs", false, 34)]
public static void EnableWarningAndAboveLogs()
{
SetAboveLogScriptingDefineSymbol(EnableWarningAndAboveLogScriptingDefineSymbol);
@@ -96,7 +96,7 @@ namespace TEngine.Editor
/// <summary>
/// 开启错误及以上级别的日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Log Scripting Define Symbols/Enable Error And Above Logs", false, 35)]
[MenuItem("TEngine/Log Scripting Define Symbols/Enable Error And Above Logs", false, 35)]
public static void EnableErrorAndAboveLogs()
{
SetAboveLogScriptingDefineSymbol(EnableErrorAndAboveLogScriptingDefineSymbol);
@@ -105,7 +105,7 @@ namespace TEngine.Editor
/// <summary>
/// 开启严重错误及以上级别的日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Log Scripting Define Symbols/Enable Fatal And Above Logs", false, 36)]
[MenuItem("TEngine/Log Scripting Define Symbols/Enable Fatal And Above Logs", false, 36)]
public static void EnableFatalAndAboveLogs()
{
SetAboveLogScriptingDefineSymbol(EnableFatalAndAboveLogScriptingDefineSymbol);

View File

@@ -13,7 +13,7 @@ namespace TEngine.Editor
/// <summary>
/// 打开 Data Path 文件夹。
/// </summary>
[MenuItem("Game Framework/Open Folder/Data Path", false, 10)]
[MenuItem("TEngine/Open Folder/Data Path", false, 10)]
public static void OpenFolderDataPath()
{
Execute(Application.dataPath);
@@ -22,7 +22,7 @@ namespace TEngine.Editor
/// <summary>
/// 打开 Persistent Data Path 文件夹。
/// </summary>
[MenuItem("Game Framework/Open Folder/Persistent Data Path", false, 11)]
[MenuItem("TEngine/Open Folder/Persistent Data Path", false, 11)]
public static void OpenFolderPersistentDataPath()
{
Execute(Application.persistentDataPath);
@@ -31,7 +31,7 @@ namespace TEngine.Editor
/// <summary>
/// 打开 Streaming Assets Path 文件夹。
/// </summary>
[MenuItem("Game Framework/Open Folder/Streaming Assets Path", false, 12)]
[MenuItem("TEngine/Open Folder/Streaming Assets Path", false, 12)]
public static void OpenFolderStreamingAssetsPath()
{
Execute(Application.streamingAssetsPath);
@@ -40,7 +40,7 @@ namespace TEngine.Editor
/// <summary>
/// 打开 Temporary Cache Path 文件夹。
/// </summary>
[MenuItem("Game Framework/Open Folder/Temporary Cache Path", false, 13)]
[MenuItem("TEngine/Open Folder/Temporary Cache Path", false, 13)]
public static void OpenFolderTemporaryCachePath()
{
Execute(Application.temporaryCachePath);
@@ -51,7 +51,7 @@ namespace TEngine.Editor
/// <summary>
/// 打开 Console Log Path 文件夹。
/// </summary>
[MenuItem("Game Framework/Open Folder/Console Log Path", false, 14)]
[MenuItem("TEngine/Open Folder/Console Log Path", false, 14)]
public static void OpenFolderConsoleLogPath()
{
Execute(System.IO.Path.GetDirectoryName(Application.consoleLogPath));

View File

@@ -16,7 +16,7 @@ namespace TEngine.Editor
/// <summary>
/// 禁用所有日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Profiler Define Symbols/Disable All Logs", false, 30)]
[MenuItem("TEngine/Profiler Define Symbols/Disable All Logs", false, 30)]
public static void DisableAllLogs()
{
foreach (string aboveLogScriptingDefineSymbol in AllProfilerDefineSymbols)
@@ -28,7 +28,7 @@ namespace TEngine.Editor
/// <summary>
/// 开启所有日志脚本宏定义。
/// </summary>
[MenuItem("Game Framework/Profiler Define Symbols/Enable All Logs", false, 31)]
[MenuItem("TEngine/Profiler Define Symbols/Enable All Logs", false, 31)]
public static void EnableAllLogs()
{
DisableAllLogs();

View File

@@ -0,0 +1,201 @@
using System.Collections.Generic;
using System.IO;
namespace TEngine
{
/// <summary>
/// 游戏框架序列化器基类。
/// </summary>
/// <typeparam name="T">要序列化的数据类型。</typeparam>
public abstract class GameFrameworkSerializer<T>
{
private readonly Dictionary<byte, SerializeCallback> m_SerializeCallbacks;
private readonly Dictionary<byte, DeserializeCallback> m_DeserializeCallbacks;
private readonly Dictionary<byte, TryGetValueCallback> m_TryGetValueCallbacks;
private byte m_LatestSerializeCallbackVersion;
/// <summary>
/// 初始化游戏框架序列化器基类的新实例。
/// </summary>
public GameFrameworkSerializer()
{
m_SerializeCallbacks = new Dictionary<byte, SerializeCallback>();
m_DeserializeCallbacks = new Dictionary<byte, DeserializeCallback>();
m_TryGetValueCallbacks = new Dictionary<byte, TryGetValueCallback>();
m_LatestSerializeCallbackVersion = 0;
}
/// <summary>
/// 序列化回调函数。
/// </summary>
/// <param name="stream">目标流。</param>
/// <param name="data">要序列化的数据。</param>
/// <returns>是否序列化数据成功。</returns>
public delegate bool SerializeCallback(Stream stream, T data);
/// <summary>
/// 反序列化回调函数。
/// </summary>
/// <param name="stream">指定流。</param>
/// <returns>反序列化的数据。</returns>
public delegate T DeserializeCallback(Stream stream);
/// <summary>
/// 尝试从指定流获取指定键的值回调函数。
/// </summary>
/// <param name="stream">指定流。</param>
/// <param name="key">指定键。</param>
/// <param name="value">指定键的值。</param>
/// <returns>是否从指定流获取指定键的值成功。</returns>
public delegate bool TryGetValueCallback(Stream stream, string key, out object value);
/// <summary>
/// 注册序列化回调函数。
/// </summary>
/// <param name="version">序列化回调函数的版本。</param>
/// <param name="callback">序列化回调函数。</param>
public void RegisterSerializeCallback(byte version, SerializeCallback callback)
{
if (callback == null)
{
throw new GameFrameworkException("Serialize callback is invalid.");
}
m_SerializeCallbacks[version] = callback;
if (version > m_LatestSerializeCallbackVersion)
{
m_LatestSerializeCallbackVersion = version;
}
}
/// <summary>
/// 注册反序列化回调函数。
/// </summary>
/// <param name="version">反序列化回调函数的版本。</param>
/// <param name="callback">反序列化回调函数。</param>
public void RegisterDeserializeCallback(byte version, DeserializeCallback callback)
{
if (callback == null)
{
throw new GameFrameworkException("Deserialize callback is invalid.");
}
m_DeserializeCallbacks[version] = callback;
}
/// <summary>
/// 注册尝试从指定流获取指定键的值回调函数。
/// </summary>
/// <param name="version">尝试从指定流获取指定键的值回调函数的版本。</param>
/// <param name="callback">尝试从指定流获取指定键的值回调函数。</param>
public void RegisterTryGetValueCallback(byte version, TryGetValueCallback callback)
{
if (callback == null)
{
throw new GameFrameworkException("Try get value callback is invalid.");
}
m_TryGetValueCallbacks[version] = callback;
}
/// <summary>
/// 序列化数据到目标流中。
/// </summary>
/// <param name="stream">目标流。</param>
/// <param name="data">要序列化的数据。</param>
/// <returns>是否序列化数据成功。</returns>
public bool Serialize(Stream stream, T data)
{
if (m_SerializeCallbacks.Count <= 0)
{
throw new GameFrameworkException("No serialize callback registered.");
}
return Serialize(stream, data, m_LatestSerializeCallbackVersion);
}
/// <summary>
/// 序列化数据到目标流中。
/// </summary>
/// <param name="stream">目标流。</param>
/// <param name="data">要序列化的数据。</param>
/// <param name="version">序列化回调函数的版本。</param>
/// <returns>是否序列化数据成功。</returns>
public bool Serialize(Stream stream, T data, byte version)
{
byte[] header = GetHeader();
stream.WriteByte(header[0]);
stream.WriteByte(header[1]);
stream.WriteByte(header[2]);
stream.WriteByte(version);
SerializeCallback callback = null;
if (!m_SerializeCallbacks.TryGetValue(version, out callback))
{
throw new GameFrameworkException(Utility.Text.Format("Serialize callback '{0}' is not exist.", version));
}
return callback(stream, data);
}
/// <summary>
/// 从指定流反序列化数据。
/// </summary>
/// <param name="stream">指定流。</param>
/// <returns>反序列化的数据。</returns>
public T Deserialize(Stream stream)
{
byte[] header = GetHeader();
byte header0 = (byte)stream.ReadByte();
byte header1 = (byte)stream.ReadByte();
byte header2 = (byte)stream.ReadByte();
if (header0 != header[0] || header1 != header[1] || header2 != header[2])
{
throw new GameFrameworkException(Utility.Text.Format("Header is invalid, need '{0}{1}{2}', current '{3}{4}{5}'.", (char)header[0], (char)header[1], (char)header[2], (char)header0, (char)header1, (char)header2));
}
byte version = (byte)stream.ReadByte();
DeserializeCallback callback = null;
if (!m_DeserializeCallbacks.TryGetValue(version, out callback))
{
throw new GameFrameworkException(Utility.Text.Format("Deserialize callback '{0}' is not exist.", version));
}
return callback(stream);
}
/// <summary>
/// 尝试从指定流获取指定键的值。
/// </summary>
/// <param name="stream">指定流。</param>
/// <param name="key">指定键。</param>
/// <param name="value">指定键的值。</param>
/// <returns>是否从指定流获取指定键的值成功。</returns>
public bool TryGetValue(Stream stream, string key, out object value)
{
value = null;
byte[] header = GetHeader();
byte header0 = (byte)stream.ReadByte();
byte header1 = (byte)stream.ReadByte();
byte header2 = (byte)stream.ReadByte();
if (header0 != header[0] || header1 != header[1] || header2 != header[2])
{
return false;
}
byte version = (byte)stream.ReadByte();
TryGetValueCallback callback = null;
if (!m_TryGetValueCallbacks.TryGetValue(version, out callback))
{
return false;
}
return callback(stream, key, out value);
}
/// <summary>
/// 获取数据头标识。
/// </summary>
/// <returns>数据头标识。</returns>
protected abstract byte[] GetHeader();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1d21d1882be542d0b73cb85f7cfa226c
timeCreated: 1680494414

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 88f259bd9cbe449da273e6ea3aeab2e4
timeCreated: 1680489578

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9871da9e5bc640969d89e4bd1efd8b4d
timeCreated: 1680489758

View File

@@ -0,0 +1,89 @@
using UnityEngine;
#if UNITY_5_5_OR_NEWER
using UnityEngine.Rendering;
#endif
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class EnvironmentInformationWindow : ScrollableDebuggerWindowBase
{
private RootComponent m_RootComponent = null;
private ResourceComponent m_ResourceComponent = null;
public override void Initialize(params object[] args)
{
m_RootComponent = GameEntry.GetComponent<RootComponent>();
if (m_RootComponent == null)
{
Log.Fatal("Base component is invalid.");
return;
}
m_ResourceComponent = GameEntry.GetComponent<ResourceComponent>();
if (m_ResourceComponent == null)
{
Log.Fatal("Resource component is invalid.");
return;
}
}
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Environment Information</b>");
GUILayout.BeginVertical("box");
{
DrawItem("Product Name", Application.productName);
DrawItem("Company Name", Application.companyName);
#if UNITY_5_6_OR_NEWER
DrawItem("Game Identifier", Application.identifier);
#else
DrawItem("Game Identifier", Application.bundleIdentifier);
#endif
DrawItem("Game Framework Version", Version.GameFrameworkVersion);
DrawItem("Game Version", Utility.Text.Format("{0} ({1})", Version.GameVersion, Version.InternalGameVersion));
DrawItem("Resource Version", (string.IsNullOrEmpty(m_ResourceComponent.ApplicableGameVersion) ? "Unknown" : Utility.Text.Format("{0} ({1})", m_ResourceComponent.ApplicableGameVersion, m_ResourceComponent.InternalResourceVersion)));
DrawItem("Application Version", Application.version);
DrawItem("Unity Version", Application.unityVersion);
DrawItem("Platform", Application.platform.ToString());
DrawItem("System Language", Application.systemLanguage.ToString());
DrawItem("Cloud Project Id", Application.cloudProjectId);
#if UNITY_5_6_OR_NEWER
DrawItem("Build Guid", Application.buildGUID);
#endif
DrawItem("Target Frame Rate", Application.targetFrameRate.ToString());
DrawItem("Internet Reachability", Application.internetReachability.ToString());
DrawItem("Background Loading Priority", Application.backgroundLoadingPriority.ToString());
DrawItem("Is Playing", Application.isPlaying.ToString());
#if UNITY_5_5_OR_NEWER
DrawItem("Splash Screen Is Finished", SplashScreen.isFinished.ToString());
#else
DrawItem("Is Showing Splash Screen", Application.isShowingSplashScreen.ToString());
#endif
DrawItem("Run In Background", Application.runInBackground.ToString());
#if UNITY_5_5_OR_NEWER
DrawItem("Install Name", Application.installerName);
#endif
DrawItem("Install Mode", Application.installMode.ToString());
DrawItem("Sandbox Type", Application.sandboxType.ToString());
DrawItem("Is Mobile Platform", Application.isMobilePlatform.ToString());
DrawItem("Is Console Platform", Application.isConsolePlatform.ToString());
DrawItem("Is Editor", Application.isEditor.ToString());
DrawItem("Is Debug Build", Debug.isDebugBuild.ToString());
#if UNITY_5_6_OR_NEWER
DrawItem("Is Focused", Application.isFocused.ToString());
#endif
#if UNITY_2018_2_OR_NEWER
DrawItem("Is Batch Mode", Application.isBatchMode.ToString());
#endif
#if UNITY_5_3
DrawItem("Stack Trace Log Type", Application.stackTraceLogType.ToString());
#endif
}
GUILayout.EndVertical();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 117d1215a84c42189328f73f5e9eac2d
timeCreated: 1680489774

View File

@@ -0,0 +1,162 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class GraphicsInformationWindow : ScrollableDebuggerWindowBase
{
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Graphics Information</b>");
GUILayout.BeginVertical("box");
{
DrawItem("Device ID", SystemInfo.graphicsDeviceID.ToString());
DrawItem("Device Name", SystemInfo.graphicsDeviceName);
DrawItem("Device Vendor ID", SystemInfo.graphicsDeviceVendorID.ToString());
DrawItem("Device Vendor", SystemInfo.graphicsDeviceVendor);
DrawItem("Device Type", SystemInfo.graphicsDeviceType.ToString());
DrawItem("Device Version", SystemInfo.graphicsDeviceVersion);
DrawItem("Memory Size", Utility.Text.Format("{0} MB", SystemInfo.graphicsMemorySize));
DrawItem("Multi Threaded", SystemInfo.graphicsMultiThreaded.ToString());
#if UNITY_2019_3_OR_NEWER
DrawItem("Rendering Threading Mode", SystemInfo.renderingThreadingMode.ToString());
#endif
#if UNITY_2020_1_OR_NEWER
DrawItem("HRD Display Support Flags", SystemInfo.hdrDisplaySupportFlags.ToString());
#endif
DrawItem("Shader Level", GetShaderLevelString(SystemInfo.graphicsShaderLevel));
DrawItem("Global Maximum LOD", Shader.globalMaximumLOD.ToString());
#if UNITY_5_6_OR_NEWER
DrawItem("Global Render Pipeline", Shader.globalRenderPipeline);
#endif
#if UNITY_2020_2_OR_NEWER
DrawItem("Min OpenGLES Version", Graphics.minOpenGLESVersion.ToString());
#endif
#if UNITY_5_5_OR_NEWER
DrawItem("Active Tier", Graphics.activeTier.ToString());
#endif
#if UNITY_2017_2_OR_NEWER
DrawItem("Active Color Gamut", Graphics.activeColorGamut.ToString());
#endif
#if UNITY_2019_2_OR_NEWER
DrawItem("Preserve Frame Buffer Alpha", Graphics.preserveFramebufferAlpha.ToString());
#endif
DrawItem("NPOT Support", SystemInfo.npotSupport.ToString());
DrawItem("Max Texture Size", SystemInfo.maxTextureSize.ToString());
DrawItem("Supported Render Target Count", SystemInfo.supportedRenderTargetCount.ToString());
#if UNITY_2019_3_OR_NEWER
DrawItem("Supported Random Write Target Count", SystemInfo.supportedRandomWriteTargetCount.ToString());
#endif
#if UNITY_5_4_OR_NEWER
DrawItem("Copy Texture Support", SystemInfo.copyTextureSupport.ToString());
#endif
#if UNITY_5_5_OR_NEWER
DrawItem("Uses Reversed ZBuffer", SystemInfo.usesReversedZBuffer.ToString());
#endif
#if UNITY_5_6_OR_NEWER
DrawItem("Max Cubemap Size", SystemInfo.maxCubemapSize.ToString());
DrawItem("Graphics UV Starts At Top", SystemInfo.graphicsUVStartsAtTop.ToString());
#endif
#if UNITY_2020_2_OR_NEWER
DrawItem("Constant Buffer Offset Alignment", SystemInfo.constantBufferOffsetAlignment.ToString());
#elif UNITY_2019_1_OR_NEWER
DrawItem("Min Constant Buffer Offset Alignment", SystemInfo.minConstantBufferOffsetAlignment.ToString());
#endif
#if UNITY_2018_3_OR_NEWER
DrawItem("Has Hidden Surface Removal On GPU", SystemInfo.hasHiddenSurfaceRemovalOnGPU.ToString());
DrawItem("Has Dynamic Uniform Array Indexing In Fragment Shaders", SystemInfo.hasDynamicUniformArrayIndexingInFragmentShaders.ToString());
#endif
#if UNITY_2019_2_OR_NEWER
DrawItem("Has Mip Max Level", SystemInfo.hasMipMaxLevel.ToString());
#endif
#if UNITY_2019_3_OR_NEWER
DrawItem("Uses Load Store Actions", SystemInfo.usesLoadStoreActions.ToString());
DrawItem("Max Compute Buffer Inputs Compute", SystemInfo.maxComputeBufferInputsCompute.ToString());
DrawItem("Max Compute Buffer Inputs Domain", SystemInfo.maxComputeBufferInputsDomain.ToString());
DrawItem("Max Compute Buffer Inputs Fragment", SystemInfo.maxComputeBufferInputsFragment.ToString());
DrawItem("Max Compute Buffer Inputs Geometry", SystemInfo.maxComputeBufferInputsGeometry.ToString());
DrawItem("Max Compute Buffer Inputs Hull", SystemInfo.maxComputeBufferInputsHull.ToString());
DrawItem("Max Compute Buffer Inputs Vertex", SystemInfo.maxComputeBufferInputsVertex.ToString());
DrawItem("Max Compute Work Group Size", SystemInfo.maxComputeWorkGroupSize.ToString());
DrawItem("Max Compute Work Group Size X", SystemInfo.maxComputeWorkGroupSizeX.ToString());
DrawItem("Max Compute Work Group Size Y", SystemInfo.maxComputeWorkGroupSizeY.ToString());
DrawItem("Max Compute Work Group Size Z", SystemInfo.maxComputeWorkGroupSizeZ.ToString());
#endif
#if UNITY_5_3 || UNITY_5_4
DrawItem("Supports Stencil", SystemInfo.supportsStencil.ToString());
DrawItem("Supports Render Textures", SystemInfo.supportsRenderTextures.ToString());
#endif
DrawItem("Supports Sparse Textures", SystemInfo.supportsSparseTextures.ToString());
DrawItem("Supports 3D Textures", SystemInfo.supports3DTextures.ToString());
DrawItem("Supports Shadows", SystemInfo.supportsShadows.ToString());
DrawItem("Supports Raw Shadow Depth Sampling", SystemInfo.supportsRawShadowDepthSampling.ToString());
#if !UNITY_2019_1_OR_NEWER
DrawItem("Supports Render To Cubemap", SystemInfo.supportsRenderToCubemap.ToString());
DrawItem("Supports Image Effects", SystemInfo.supportsImageEffects.ToString());
#endif
DrawItem("Supports Compute Shader", SystemInfo.supportsComputeShaders.ToString());
DrawItem("Supports Instancing", SystemInfo.supportsInstancing.ToString());
#if UNITY_5_4_OR_NEWER
DrawItem("Supports 2D Array Textures", SystemInfo.supports2DArrayTextures.ToString());
DrawItem("Supports Motion Vectors", SystemInfo.supportsMotionVectors.ToString());
#endif
#if UNITY_5_5_OR_NEWER
DrawItem("Supports Cubemap Array Textures", SystemInfo.supportsCubemapArrayTextures.ToString());
#endif
#if UNITY_5_6_OR_NEWER
DrawItem("Supports 3D Render Textures", SystemInfo.supports3DRenderTextures.ToString());
#endif
#if UNITY_2017_2_OR_NEWER && !UNITY_2017_2_0 || UNITY_2017_1_4
DrawItem("Supports Texture Wrap Mirror Once", SystemInfo.supportsTextureWrapMirrorOnce.ToString());
#endif
#if UNITY_2019_1_OR_NEWER
DrawItem("Supports Graphics Fence", SystemInfo.supportsGraphicsFence.ToString());
#elif UNITY_2017_3_OR_NEWER
DrawItem("Supports GPU Fence", SystemInfo.supportsGPUFence.ToString());
#endif
#if UNITY_2017_3_OR_NEWER
DrawItem("Supports Async Compute", SystemInfo.supportsAsyncCompute.ToString());
DrawItem("Supports Multi-sampled Textures", SystemInfo.supportsMultisampledTextures.ToString());
#endif
#if UNITY_2018_1_OR_NEWER
DrawItem("Supports Async GPU Readback", SystemInfo.supportsAsyncGPUReadback.ToString());
DrawItem("Supports 32bits Index Buffer", SystemInfo.supports32bitsIndexBuffer.ToString());
DrawItem("Supports Hardware Quad Topology", SystemInfo.supportsHardwareQuadTopology.ToString());
#endif
#if UNITY_2018_2_OR_NEWER
DrawItem("Supports Mip Streaming", SystemInfo.supportsMipStreaming.ToString());
DrawItem("Supports Multi-sample Auto Resolve", SystemInfo.supportsMultisampleAutoResolve.ToString());
#endif
#if UNITY_2018_3_OR_NEWER
DrawItem("Supports Separated Render Targets Blend", SystemInfo.supportsSeparatedRenderTargetsBlend.ToString());
#endif
#if UNITY_2019_1_OR_NEWER
DrawItem("Supports Set Constant Buffer", SystemInfo.supportsSetConstantBuffer.ToString());
#endif
#if UNITY_2019_3_OR_NEWER
DrawItem("Supports Geometry Shaders", SystemInfo.supportsGeometryShaders.ToString());
DrawItem("Supports Ray Tracing", SystemInfo.supportsRayTracing.ToString());
DrawItem("Supports Tessellation Shaders", SystemInfo.supportsTessellationShaders.ToString());
#endif
#if UNITY_2020_1_OR_NEWER
DrawItem("Supports Compressed 3D Textures", SystemInfo.supportsCompressed3DTextures.ToString());
DrawItem("Supports Conservative Raster", SystemInfo.supportsConservativeRaster.ToString());
DrawItem("Supports GPU Recorder", SystemInfo.supportsGpuRecorder.ToString());
#endif
#if UNITY_2020_2_OR_NEWER
DrawItem("Supports Multi-sampled 2D Array Textures", SystemInfo.supportsMultisampled2DArrayTextures.ToString());
DrawItem("Supports Multiview", SystemInfo.supportsMultiview.ToString());
DrawItem("Supports Render Target Array Index From Vertex Shader", SystemInfo.supportsRenderTargetArrayIndexFromVertexShader.ToString());
#endif
}
GUILayout.EndVertical();
}
private string GetShaderLevelString(int shaderLevel)
{
return Utility.Text.Format("Shader Model {0}.{1}", shaderLevel / 10, shaderLevel % 10);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b257b0e038194eb480632d81e640058e
timeCreated: 1680489774

View File

@@ -0,0 +1,38 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class InputAccelerationInformationWindow : ScrollableDebuggerWindowBase
{
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Input Acceleration Information</b>");
GUILayout.BeginVertical("box");
{
DrawItem("Acceleration", Input.acceleration.ToString());
DrawItem("Acceleration Event Count", Input.accelerationEventCount.ToString());
DrawItem("Acceleration Events", GetAccelerationEventsString(Input.accelerationEvents));
}
GUILayout.EndVertical();
}
private string GetAccelerationEventString(AccelerationEvent accelerationEvent)
{
return Utility.Text.Format("{0}, {1}", accelerationEvent.acceleration, accelerationEvent.deltaTime);
}
private string GetAccelerationEventsString(AccelerationEvent[] accelerationEvents)
{
string[] accelerationEventStrings = new string[accelerationEvents.Length];
for (int i = 0; i < accelerationEvents.Length; i++)
{
accelerationEventStrings[i] = GetAccelerationEventString(accelerationEvents[i]);
}
return string.Join("; ", accelerationEventStrings);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 88685f3bc75649dc8c198de19ae84c3e
timeCreated: 1680489774

View File

@@ -0,0 +1,41 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class InputCompassInformationWindow : ScrollableDebuggerWindowBase
{
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Input Compass Information</b>");
GUILayout.BeginVertical("box");
{
GUILayout.BeginHorizontal();
{
if (GUILayout.Button("Enable", GUILayout.Height(30f)))
{
Input.compass.enabled = true;
}
if (GUILayout.Button("Disable", GUILayout.Height(30f)))
{
Input.compass.enabled = false;
}
}
GUILayout.EndHorizontal();
DrawItem("Enabled", Input.compass.enabled.ToString());
if (Input.compass.enabled)
{
DrawItem("Heading Accuracy", Input.compass.headingAccuracy.ToString());
DrawItem("Magnetic Heading", Input.compass.magneticHeading.ToString());
DrawItem("Raw Vector", Input.compass.rawVector.ToString());
DrawItem("Timestamp", Input.compass.timestamp.ToString());
DrawItem("True Heading", Input.compass.trueHeading.ToString());
}
}
GUILayout.EndVertical();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: dfbb3d3f61b041d9a0fa135a7cac876a
timeCreated: 1680489774

View File

@@ -0,0 +1,42 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class InputGyroscopeInformationWindow : ScrollableDebuggerWindowBase
{
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Input Gyroscope Information</b>");
GUILayout.BeginVertical("box");
{
GUILayout.BeginHorizontal();
{
if (GUILayout.Button("Enable", GUILayout.Height(30f)))
{
Input.gyro.enabled = true;
}
if (GUILayout.Button("Disable", GUILayout.Height(30f)))
{
Input.gyro.enabled = false;
}
}
GUILayout.EndHorizontal();
DrawItem("Enabled", Input.gyro.enabled.ToString());
if (Input.gyro.enabled)
{
DrawItem("Update Interval", Input.gyro.updateInterval.ToString());
DrawItem("Attitude", Input.gyro.attitude.eulerAngles.ToString());
DrawItem("Gravity", Input.gyro.gravity.ToString());
DrawItem("Rotation Rate", Input.gyro.rotationRate.ToString());
DrawItem("Rotation Rate Unbiased", Input.gyro.rotationRateUnbiased.ToString());
DrawItem("User Acceleration", Input.gyro.userAcceleration.ToString());
}
}
GUILayout.EndVertical();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 153ce8ea1c9b400c82c4ec742d8aa6b7
timeCreated: 1680489774

View File

@@ -0,0 +1,43 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class InputLocationInformationWindow : ScrollableDebuggerWindowBase
{
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Input Location Information</b>");
GUILayout.BeginVertical("box");
{
GUILayout.BeginHorizontal();
{
if (GUILayout.Button("Enable", GUILayout.Height(30f)))
{
Input.location.Start();
}
if (GUILayout.Button("Disable", GUILayout.Height(30f)))
{
Input.location.Stop();
}
}
GUILayout.EndHorizontal();
DrawItem("Is Enabled By User", Input.location.isEnabledByUser.ToString());
DrawItem("Status", Input.location.status.ToString());
if (Input.location.status == LocationServiceStatus.Running)
{
DrawItem("Horizontal Accuracy", Input.location.lastData.horizontalAccuracy.ToString());
DrawItem("Vertical Accuracy", Input.location.lastData.verticalAccuracy.ToString());
DrawItem("Longitude", Input.location.lastData.longitude.ToString());
DrawItem("Latitude", Input.location.lastData.latitude.ToString());
DrawItem("Altitude", Input.location.lastData.altitude.ToString());
DrawItem("Timestamp", Input.location.lastData.timestamp.ToString());
}
}
GUILayout.EndVertical();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 04628888fa364b2b97b4cb77dcbbdd44
timeCreated: 1680489774

View File

@@ -0,0 +1,32 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class InputSummaryInformationWindow : ScrollableDebuggerWindowBase
{
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Input Summary Information</b>");
GUILayout.BeginVertical("box");
{
DrawItem("Back Button Leaves App", Input.backButtonLeavesApp.ToString());
DrawItem("Device Orientation", Input.deviceOrientation.ToString());
DrawItem("Mouse Present", Input.mousePresent.ToString());
DrawItem("Mouse Position", Input.mousePosition.ToString());
DrawItem("Mouse Scroll Delta", Input.mouseScrollDelta.ToString());
DrawItem("Any Key", Input.anyKey.ToString());
DrawItem("Any Key Down", Input.anyKeyDown.ToString());
DrawItem("Input String", Input.inputString);
DrawItem("IME Is Selected", Input.imeIsSelected.ToString());
DrawItem("IME Composition Mode", Input.imeCompositionMode.ToString());
DrawItem("Compensate Sensors", Input.compensateSensors.ToString());
DrawItem("Composition Cursor Position", Input.compositionCursorPos.ToString());
DrawItem("Composition String", Input.compositionString);
}
GUILayout.EndVertical();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ada3bed2bef9413a85c890e907e0e449
timeCreated: 1680489774

View File

@@ -0,0 +1,42 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class InputTouchInformationWindow : ScrollableDebuggerWindowBase
{
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Input Touch Information</b>");
GUILayout.BeginVertical("box");
{
DrawItem("Touch Supported", Input.touchSupported.ToString());
DrawItem("Touch Pressure Supported", Input.touchPressureSupported.ToString());
DrawItem("Stylus Touch Supported", Input.stylusTouchSupported.ToString());
DrawItem("Simulate Mouse With Touches", Input.simulateMouseWithTouches.ToString());
DrawItem("Multi Touch Enabled", Input.multiTouchEnabled.ToString());
DrawItem("Touch Count", Input.touchCount.ToString());
DrawItem("Touches", GetTouchesString(Input.touches));
}
GUILayout.EndVertical();
}
private string GetTouchString(Touch touch)
{
return Utility.Text.Format("{0}, {1}, {2}, {3}, {4}", touch.position, touch.deltaPosition, touch.rawPosition, touch.pressure, touch.phase);
}
private string GetTouchesString(Touch[] touches)
{
string[] touchStrings = new string[touches.Length];
for (int i = 0; i < touches.Length; i++)
{
touchStrings[i] = GetTouchString(touches[i]);
}
return string.Join("; ", touchStrings);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1a54fc6c38204d28b511fe8747b4151d
timeCreated: 1680489774

View File

@@ -0,0 +1,117 @@
using System;
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
/// <summary>
/// 日志记录结点。
/// </summary>
public sealed class LogNode : IMemory
{
private DateTime m_LogTime;
private int m_LogFrameCount;
private LogType m_LogType;
private string m_LogMessage;
private string m_StackTrack;
/// <summary>
/// 初始化日志记录结点的新实例。
/// </summary>
public LogNode()
{
m_LogTime = default(DateTime);
m_LogFrameCount = 0;
m_LogType = LogType.Error;
m_LogMessage = null;
m_StackTrack = null;
}
/// <summary>
/// 获取日志时间。
/// </summary>
public DateTime LogTime
{
get
{
return m_LogTime;
}
}
/// <summary>
/// 获取日志帧计数。
/// </summary>
public int LogFrameCount
{
get
{
return m_LogFrameCount;
}
}
/// <summary>
/// 获取日志类型。
/// </summary>
public LogType LogType
{
get
{
return m_LogType;
}
}
/// <summary>
/// 获取日志内容。
/// </summary>
public string LogMessage
{
get
{
return m_LogMessage;
}
}
/// <summary>
/// 获取日志堆栈信息。
/// </summary>
public string StackTrack
{
get
{
return m_StackTrack;
}
}
/// <summary>
/// 创建日志记录结点。
/// </summary>
/// <param name="logType">日志类型。</param>
/// <param name="logMessage">日志内容。</param>
/// <param name="stackTrack">日志堆栈信息。</param>
/// <returns>创建的日志记录结点。</returns>
public static LogNode Create(LogType logType, string logMessage, string stackTrack)
{
LogNode logNode = MemoryPool.Acquire<LogNode>();
logNode.m_LogTime = DateTime.UtcNow;
logNode.m_LogFrameCount = Time.frameCount;
logNode.m_LogType = logType;
logNode.m_LogMessage = logMessage;
logNode.m_StackTrack = stackTrack;
return logNode;
}
/// <summary>
/// 清理日志记录结点。
/// </summary>
public void Clear()
{
m_LogTime = default(DateTime);
m_LogFrameCount = 0;
m_LogType = LogType.Error;
m_LogMessage = null;
m_StackTrack = null;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e7135a7b2bbe46f8a69c3b6b9b4cf2be
timeCreated: 1680489774

View File

@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class MemoryPoolPoolInformationWindow : ScrollableDebuggerWindowBase
{
private readonly Dictionary<string, List<MemoryPoolInfo>> m_MemoryPoolInfos = new Dictionary<string, List<MemoryPoolInfo>>(StringComparer.Ordinal);
private readonly Comparison<MemoryPoolInfo> m_NormalClassNameComparer = NormalClassNameComparer;
private readonly Comparison<MemoryPoolInfo> m_FullClassNameComparer = FullClassNameComparer;
private bool m_ShowFullClassName = false;
public override void Initialize(params object[] args)
{
}
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Memory Pool Information</b>");
GUILayout.BeginVertical("box");
{
DrawItem("Enable Strict Check", MemoryPool.EnableStrictCheck.ToString());
DrawItem("Memory Pool Count", MemoryPool.Count.ToString());
}
GUILayout.EndVertical();
m_ShowFullClassName = GUILayout.Toggle(m_ShowFullClassName, "Show Full Class Name");
m_MemoryPoolInfos.Clear();
MemoryPoolInfo[] memoryPoolInfos = MemoryPool.GetAllMemoryPoolInfos();
foreach (MemoryPoolInfo memoryPoolInfo in memoryPoolInfos)
{
string assemblyName = memoryPoolInfo.Type.Assembly.GetName().Name;
List<MemoryPoolInfo> results = null;
if (!m_MemoryPoolInfos.TryGetValue(assemblyName, out results))
{
results = new List<MemoryPoolInfo>();
m_MemoryPoolInfos.Add(assemblyName, results);
}
results.Add(memoryPoolInfo);
}
foreach (KeyValuePair<string, List<MemoryPoolInfo>> assemblyMemoryPoolInfo in m_MemoryPoolInfos)
{
GUILayout.Label(Utility.Text.Format("<b>Assembly: {0}</b>", assemblyMemoryPoolInfo.Key));
GUILayout.BeginVertical("box");
{
GUILayout.BeginHorizontal();
{
GUILayout.Label(m_ShowFullClassName ? "<b>Full Class Name</b>" : "<b>Class Name</b>");
GUILayout.Label("<b>Unused</b>", GUILayout.Width(60f));
GUILayout.Label("<b>Using</b>", GUILayout.Width(60f));
GUILayout.Label("<b>Acquire</b>", GUILayout.Width(60f));
GUILayout.Label("<b>Release</b>", GUILayout.Width(60f));
GUILayout.Label("<b>Add</b>", GUILayout.Width(60f));
GUILayout.Label("<b>Remove</b>", GUILayout.Width(60f));
}
GUILayout.EndHorizontal();
if (assemblyMemoryPoolInfo.Value.Count > 0)
{
assemblyMemoryPoolInfo.Value.Sort(m_ShowFullClassName ? m_FullClassNameComparer : m_NormalClassNameComparer);
foreach (MemoryPoolInfo memoryPoolInfo in assemblyMemoryPoolInfo.Value)
{
DrawMemoryPoolInfo(memoryPoolInfo);
}
}
else
{
GUILayout.Label("<i>Memory Pool is Empty ...</i>");
}
}
GUILayout.EndVertical();
}
}
private void DrawMemoryPoolInfo(MemoryPoolInfo memoryPoolInfo)
{
GUILayout.BeginHorizontal();
{
GUILayout.Label(m_ShowFullClassName ? memoryPoolInfo.Type.FullName : memoryPoolInfo.Type.Name);
GUILayout.Label(memoryPoolInfo.UnusedMemoryCount.ToString(), GUILayout.Width(60f));
GUILayout.Label(memoryPoolInfo.UsingMemoryCount.ToString(), GUILayout.Width(60f));
GUILayout.Label(memoryPoolInfo.AcquireMemoryCount.ToString(), GUILayout.Width(60f));
GUILayout.Label(memoryPoolInfo.ReleaseMemoryCount.ToString(), GUILayout.Width(60f));
GUILayout.Label(memoryPoolInfo.AddMemoryCount.ToString(), GUILayout.Width(60f));
GUILayout.Label(memoryPoolInfo.RemoveMemoryCount.ToString(), GUILayout.Width(60f));
}
GUILayout.EndHorizontal();
}
private static int NormalClassNameComparer(MemoryPoolInfo a, MemoryPoolInfo b)
{
return a.Type.Name.CompareTo(b.Type.Name);
}
private static int FullClassNameComparer(MemoryPoolInfo a, MemoryPoolInfo b)
{
return a.Type.FullName.CompareTo(b.Type.FullName);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 71ce9435de5c41b3a582614d4ea71512
timeCreated: 1680489774

View File

@@ -0,0 +1,61 @@
// using UnityEngine;
//
// namespace TEngine
// {
// public sealed partial class DebuggerComponent : GameFrameworkComponent
// {
// private sealed class NetworkInformationWindow : ScrollableDebuggerWindowBase
// {
// private NetworkComponent m_NetworkComponent = null;
//
// public override void Initialize(params object[] args)
// {
// m_NetworkComponent = GameEntry.GetComponent<NetworkComponent>();
// if (m_NetworkComponent == null)
// {
// Log.Fatal("Network component is invalid.");
// return;
// }
// }
//
// protected override void OnDrawScrollableWindow()
// {
// GUILayout.Label("<b>Network Information</b>");
// GUILayout.BeginVertical("box");
// {
// DrawItem("Network Channel Count", m_NetworkComponent.NetworkChannelCount.ToString());
// }
// GUILayout.EndVertical();
// INetworkChannel[] networkChannels = m_NetworkComponent.GetAllNetworkChannels();
// for (int i = 0; i < networkChannels.Length; i++)
// {
// DrawNetworkChannel(networkChannels[i]);
// }
// }
//
// private void DrawNetworkChannel(INetworkChannel networkChannel)
// {
// GUILayout.Label(Utility.Text.Format("<b>Network Channel: {0} ({1})</b>", networkChannel.Name, networkChannel.Connected ? "Connected" : "Disconnected"));
// GUILayout.BeginVertical("box");
// {
// DrawItem("Service Type", networkChannel.ServiceType.ToString());
// DrawItem("Address Family", networkChannel.AddressFamily.ToString());
// DrawItem("Local Address", networkChannel.Connected ? networkChannel.Socket.LocalEndPoint.ToString() : "Unavailable");
// DrawItem("Remote Address", networkChannel.Connected ? networkChannel.Socket.RemoteEndPoint.ToString() : "Unavailable");
// DrawItem("Send Packet", Utility.Text.Format("{0} / {1}", networkChannel.SendPacketCount, networkChannel.SentPacketCount));
// DrawItem("Receive Packet", Utility.Text.Format("{0} / {1}", networkChannel.ReceivePacketCount, networkChannel.ReceivedPacketCount));
// DrawItem("Miss Heart Beat Count", networkChannel.MissHeartBeatCount.ToString());
// DrawItem("Heart Beat", Utility.Text.Format("{0:F2} / {1:F2}", networkChannel.HeartBeatElapseSeconds, networkChannel.HeartBeatInterval));
// if (networkChannel.Connected)
// {
// if (GUILayout.Button("Disconnect", GUILayout.Height(30f)))
// {
// networkChannel.Close();
// }
// }
// }
// GUILayout.EndVertical();
// }
// }
// }
// }

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 91eb2683b03a4eb0afdd2edd034df2cc
timeCreated: 1680489774

View File

@@ -0,0 +1,86 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class ObjectPoolInformationWindow : ScrollableDebuggerWindowBase
{
private ObjectPoolComponent m_ObjectPoolComponent = null;
public override void Initialize(params object[] args)
{
m_ObjectPoolComponent = GameEntry.GetComponent<ObjectPoolComponent>();
if (m_ObjectPoolComponent == null)
{
Log.Fatal("Object pool component is invalid.");
return;
}
}
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Object Pool Information</b>");
GUILayout.BeginVertical("box");
{
DrawItem("Object Pool Count", m_ObjectPoolComponent.Count.ToString());
}
GUILayout.EndVertical();
ObjectPoolBase[] objectPools = m_ObjectPoolComponent.GetAllObjectPools(true);
for (int i = 0; i < objectPools.Length; i++)
{
DrawObjectPool(objectPools[i]);
}
}
private void DrawObjectPool(ObjectPoolBase objectPool)
{
GUILayout.Label(Utility.Text.Format("<b>Object Pool: {0}</b>", objectPool.FullName));
GUILayout.BeginVertical("box");
{
DrawItem("Name", objectPool.Name);
DrawItem("Type", objectPool.ObjectType.FullName);
DrawItem("Auto Release Interval", objectPool.AutoReleaseInterval.ToString());
DrawItem("Capacity", objectPool.Capacity.ToString());
DrawItem("Used Count", objectPool.Count.ToString());
DrawItem("Can Release Count", objectPool.CanReleaseCount.ToString());
DrawItem("Expire Time", objectPool.ExpireTime.ToString());
DrawItem("Priority", objectPool.Priority.ToString());
ObjectInfo[] objectInfos = objectPool.GetAllObjectInfos();
GUILayout.BeginHorizontal();
{
GUILayout.Label("<b>Name</b>");
GUILayout.Label("<b>Locked</b>", GUILayout.Width(60f));
GUILayout.Label(objectPool.AllowMultiSpawn ? "<b>Count</b>" : "<b>In Use</b>", GUILayout.Width(60f));
GUILayout.Label("<b>Flag</b>", GUILayout.Width(60f));
GUILayout.Label("<b>Priority</b>", GUILayout.Width(60f));
GUILayout.Label("<b>Last Use Time</b>", GUILayout.Width(120f));
}
GUILayout.EndHorizontal();
if (objectInfos.Length > 0)
{
for (int i = 0; i < objectInfos.Length; i++)
{
GUILayout.BeginHorizontal();
{
GUILayout.Label(string.IsNullOrEmpty(objectInfos[i].Name) ? "<None>" : objectInfos[i].Name);
GUILayout.Label(objectInfos[i].Locked.ToString(), GUILayout.Width(60f));
GUILayout.Label(objectPool.AllowMultiSpawn ? objectInfos[i].SpawnCount.ToString() : objectInfos[i].IsInUse.ToString(), GUILayout.Width(60f));
GUILayout.Label(objectInfos[i].CustomCanReleaseFlag.ToString(), GUILayout.Width(60f));
GUILayout.Label(objectInfos[i].Priority.ToString(), GUILayout.Width(60f));
GUILayout.Label(objectInfos[i].LastUseTime.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss"), GUILayout.Width(120f));
}
GUILayout.EndHorizontal();
}
}
else
{
GUILayout.Label("<i>Object Pool is Empty ...</i>");
}
}
GUILayout.EndVertical();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2f669ce069054868b72a95ebf28d8042
timeCreated: 1680489774

View File

@@ -0,0 +1,59 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class OperationsWindow : ScrollableDebuggerWindowBase
{
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Operations</b>");
GUILayout.BeginVertical("box");
{
ObjectPoolComponent objectPoolComponent = GameEntry.GetComponent<ObjectPoolComponent>();
if (objectPoolComponent != null)
{
if (GUILayout.Button("Object Pool Release", GUILayout.Height(30f)))
{
objectPoolComponent.Release();
}
if (GUILayout.Button("Object Pool Release All Unused", GUILayout.Height(30f)))
{
objectPoolComponent.ReleaseAllUnused();
}
}
ResourceComponent resourceCompoent = GameEntry.GetComponent<ResourceComponent>();
if (resourceCompoent != null)
{
if (GUILayout.Button("Unload Unused Assets", GUILayout.Height(30f)))
{
resourceCompoent.ForceUnloadUnusedAssets(false);
}
if (GUILayout.Button("Unload Unused Assets and Garbage Collect", GUILayout.Height(30f)))
{
resourceCompoent.ForceUnloadUnusedAssets(true);
}
}
if (GUILayout.Button("Shutdown Game Framework (None)", GUILayout.Height(30f)))
{
GameEntry.Shutdown(ShutdownType.None);
}
if (GUILayout.Button("Shutdown Game Framework (Restart)", GUILayout.Height(30f)))
{
GameEntry.Shutdown(ShutdownType.Restart);
}
if (GUILayout.Button("Shutdown Game Framework (Quit)", GUILayout.Height(30f)))
{
GameEntry.Shutdown(ShutdownType.Quit);
}
}
GUILayout.EndVertical();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 88ba6493eca64e6f8e8135b305f4eaf0
timeCreated: 1680489774

View File

@@ -0,0 +1,28 @@
using System;
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class PathInformationWindow : ScrollableDebuggerWindowBase
{
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Path Information</b>");
GUILayout.BeginVertical("box");
{
DrawItem("Current Directory", Utility.Path.GetRegularPath(Environment.CurrentDirectory));
DrawItem("Data Path", Utility.Path.GetRegularPath(Application.dataPath));
DrawItem("Persistent Data Path", Utility.Path.GetRegularPath(Application.persistentDataPath));
DrawItem("Streaming Assets Path", Utility.Path.GetRegularPath(Application.streamingAssetsPath));
DrawItem("Temporary Cache Path", Utility.Path.GetRegularPath(Application.temporaryCachePath));
#if UNITY_2018_3_OR_NEWER
DrawItem("Console Log Path", Utility.Path.GetRegularPath(Application.consoleLogPath));
#endif
}
GUILayout.EndVertical();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6d2a77c65d5e472792cf84e5c52894b8
timeCreated: 1680489774

View File

@@ -0,0 +1,59 @@
using UnityEngine;
#if UNITY_5_5_OR_NEWER
using UnityEngine.Profiling;
#endif
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class ProfilerInformationWindow : ScrollableDebuggerWindowBase
{
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Profiler Information</b>");
GUILayout.BeginVertical("box");
{
DrawItem("Supported", Profiler.supported.ToString());
DrawItem("Enabled", Profiler.enabled.ToString());
DrawItem("Enable Binary Log", Profiler.enableBinaryLog ? Utility.Text.Format("True, {0}", Profiler.logFile) : "False");
#if UNITY_2019_3_OR_NEWER
DrawItem("Enable Allocation Callstacks", Profiler.enableAllocationCallstacks.ToString());
#endif
#if UNITY_2018_3_OR_NEWER
DrawItem("Area Count", Profiler.areaCount.ToString());
#endif
#if UNITY_5_3 || UNITY_5_4
DrawItem("Max Samples Number Per Frame", Profiler.maxNumberOfSamplesPerFrame.ToString());
#endif
#if UNITY_2018_3_OR_NEWER
DrawItem("Max Used Memory", GetByteLengthString(Profiler.maxUsedMemory));
#endif
#if UNITY_5_6_OR_NEWER
DrawItem("Mono Used Size", GetByteLengthString(Profiler.GetMonoUsedSizeLong()));
DrawItem("Mono Heap Size", GetByteLengthString(Profiler.GetMonoHeapSizeLong()));
DrawItem("Used Heap Size", GetByteLengthString(Profiler.usedHeapSizeLong));
DrawItem("Total Allocated Memory", GetByteLengthString(Profiler.GetTotalAllocatedMemoryLong()));
DrawItem("Total Reserved Memory", GetByteLengthString(Profiler.GetTotalReservedMemoryLong()));
DrawItem("Total Unused Reserved Memory", GetByteLengthString(Profiler.GetTotalUnusedReservedMemoryLong()));
#else
DrawItem("Mono Used Size", GetByteLengthString(Profiler.GetMonoUsedSize()));
DrawItem("Mono Heap Size", GetByteLengthString(Profiler.GetMonoHeapSize()));
DrawItem("Used Heap Size", GetByteLengthString(Profiler.usedHeapSize));
DrawItem("Total Allocated Memory", GetByteLengthString(Profiler.GetTotalAllocatedMemory()));
DrawItem("Total Reserved Memory", GetByteLengthString(Profiler.GetTotalReservedMemory()));
DrawItem("Total Unused Reserved Memory", GetByteLengthString(Profiler.GetTotalUnusedReservedMemory()));
#endif
#if UNITY_2018_1_OR_NEWER
DrawItem("Allocated Memory For Graphics Driver", GetByteLengthString(Profiler.GetAllocatedMemoryForGraphicsDriver()));
#endif
#if UNITY_5_5_OR_NEWER
DrawItem("Temp Allocator Size", GetByteLengthString(Profiler.GetTempAllocatorSize()));
#endif
DrawItem("Marshal Cached HGlobal Size", GetByteLengthString(Utility.Marshal.CachedHGlobalSize));
}
GUILayout.EndVertical();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 10a0760b9718472586a653a79646f05d
timeCreated: 1680489774

View File

@@ -0,0 +1,102 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class QualityInformationWindow : ScrollableDebuggerWindowBase
{
private bool m_ApplyExpensiveChanges = false;
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Quality Level</b>");
GUILayout.BeginVertical("box");
{
int currentQualityLevel = QualitySettings.GetQualityLevel();
DrawItem("Current Quality Level", QualitySettings.names[currentQualityLevel]);
m_ApplyExpensiveChanges = GUILayout.Toggle(m_ApplyExpensiveChanges, "Apply expensive changes on quality level change.");
int newQualityLevel = GUILayout.SelectionGrid(currentQualityLevel, QualitySettings.names, 3, "toggle");
if (newQualityLevel != currentQualityLevel)
{
QualitySettings.SetQualityLevel(newQualityLevel, m_ApplyExpensiveChanges);
}
}
GUILayout.EndVertical();
GUILayout.Label("<b>Rendering Information</b>");
GUILayout.BeginVertical("box");
{
DrawItem("Active Color Space", QualitySettings.activeColorSpace.ToString());
DrawItem("Desired Color Space", QualitySettings.desiredColorSpace.ToString());
DrawItem("Max Queued Frames", QualitySettings.maxQueuedFrames.ToString());
DrawItem("Pixel Light Count", QualitySettings.pixelLightCount.ToString());
DrawItem("Master Texture Limit", QualitySettings.masterTextureLimit.ToString());
DrawItem("Anisotropic Filtering", QualitySettings.anisotropicFiltering.ToString());
DrawItem("Anti Aliasing", QualitySettings.antiAliasing.ToString());
#if UNITY_5_5_OR_NEWER
DrawItem("Soft Particles", QualitySettings.softParticles.ToString());
#endif
DrawItem("Soft Vegetation", QualitySettings.softVegetation.ToString());
DrawItem("Realtime Reflection Probes", QualitySettings.realtimeReflectionProbes.ToString());
DrawItem("Billboards Face Camera Position", QualitySettings.billboardsFaceCameraPosition.ToString());
#if UNITY_2017_1_OR_NEWER
DrawItem("Resolution Scaling Fixed DPI Factor", QualitySettings.resolutionScalingFixedDPIFactor.ToString());
#endif
#if UNITY_2018_2_OR_NEWER
DrawItem("Texture Streaming Enabled", QualitySettings.streamingMipmapsActive.ToString());
DrawItem("Texture Streaming Add All Cameras", QualitySettings.streamingMipmapsAddAllCameras.ToString());
DrawItem("Texture Streaming Memory Budget", QualitySettings.streamingMipmapsMemoryBudget.ToString());
DrawItem("Texture Streaming Renderers Per Frame", QualitySettings.streamingMipmapsRenderersPerFrame.ToString());
DrawItem("Texture Streaming Max Level Reduction", QualitySettings.streamingMipmapsMaxLevelReduction.ToString());
DrawItem("Texture Streaming Max File IO Requests", QualitySettings.streamingMipmapsMaxFileIORequests.ToString());
#endif
}
GUILayout.EndVertical();
GUILayout.Label("<b>Shadows Information</b>");
GUILayout.BeginVertical("box");
{
#if UNITY_2017_1_OR_NEWER
DrawItem("Shadowmask Mode", QualitySettings.shadowmaskMode.ToString());
#endif
#if UNITY_5_5_OR_NEWER
DrawItem("Shadow Quality", QualitySettings.shadows.ToString());
#endif
#if UNITY_5_4_OR_NEWER
DrawItem("Shadow Resolution", QualitySettings.shadowResolution.ToString());
#endif
DrawItem("Shadow Projection", QualitySettings.shadowProjection.ToString());
DrawItem("Shadow Distance", QualitySettings.shadowDistance.ToString());
DrawItem("Shadow Near Plane Offset", QualitySettings.shadowNearPlaneOffset.ToString());
DrawItem("Shadow Cascades", QualitySettings.shadowCascades.ToString());
DrawItem("Shadow Cascade 2 Split", QualitySettings.shadowCascade2Split.ToString());
DrawItem("Shadow Cascade 4 Split", QualitySettings.shadowCascade4Split.ToString());
}
GUILayout.EndVertical();
GUILayout.Label("<b>Other Information</b>");
GUILayout.BeginVertical("box");
{
#if UNITY_2019_1_OR_NEWER
DrawItem("Skin Weights", QualitySettings.skinWeights.ToString());
#else
DrawItem("Blend Weights", QualitySettings.blendWeights.ToString());
#endif
DrawItem("VSync Count", QualitySettings.vSyncCount.ToString());
DrawItem("LOD Bias", QualitySettings.lodBias.ToString());
DrawItem("Maximum LOD Level", QualitySettings.maximumLODLevel.ToString());
DrawItem("Particle Raycast Budget", QualitySettings.particleRaycastBudget.ToString());
DrawItem("Async Upload Time Slice", Utility.Text.Format("{0} ms", QualitySettings.asyncUploadTimeSlice));
DrawItem("Async Upload Buffer Size", Utility.Text.Format("{0} MB", QualitySettings.asyncUploadBufferSize));
#if UNITY_2018_3_OR_NEWER
DrawItem("Async Upload Persistent Buffer", QualitySettings.asyncUploadPersistentBuffer.ToString());
#endif
}
GUILayout.EndVertical();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9e0be8441f814651a4a238586278df12
timeCreated: 1680489774

View File

@@ -0,0 +1,60 @@
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed partial class RuntimeMemoryInformationWindow<T> : ScrollableDebuggerWindowBase where T : UnityEngine.Object
{
private sealed class Sample
{
private readonly string m_Name;
private readonly string m_Type;
private readonly long m_Size;
private bool m_Highlight;
public Sample(string name, string type, long size)
{
m_Name = name;
m_Type = type;
m_Size = size;
m_Highlight = false;
}
public string Name
{
get
{
return m_Name;
}
}
public string Type
{
get
{
return m_Type;
}
}
public long Size
{
get
{
return m_Size;
}
}
public bool Highlight
{
get
{
return m_Highlight;
}
set
{
m_Highlight = value;
}
}
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c056a5278fb046c693656d9b3c5d1639
timeCreated: 1680489774

View File

@@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_5_5_OR_NEWER
using UnityEngine.Profiling;
#endif
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed partial class RuntimeMemoryInformationWindow<T> : ScrollableDebuggerWindowBase where T : UnityEngine.Object
{
private const int ShowSampleCount = 300;
private readonly List<Sample> m_Samples = new List<Sample>();
private readonly Comparison<Sample> m_SampleComparer = SampleComparer;
private DateTime m_SampleTime = DateTime.MinValue;
private long m_SampleSize = 0L;
private long m_DuplicateSampleSize = 0L;
private int m_DuplicateSimpleCount = 0;
protected override void OnDrawScrollableWindow()
{
string typeName = typeof(T).Name;
GUILayout.Label(Utility.Text.Format("<b>{0} Runtime Memory Information</b>", typeName));
GUILayout.BeginVertical("box");
{
if (GUILayout.Button(Utility.Text.Format("Take Sample for {0}", typeName), GUILayout.Height(30f)))
{
TakeSample();
}
if (m_SampleTime <= DateTime.MinValue)
{
GUILayout.Label(Utility.Text.Format("<b>Please take sample for {0} first.</b>", typeName));
}
else
{
if (m_DuplicateSimpleCount > 0)
{
GUILayout.Label(Utility.Text.Format("<b>{0} {1}s ({2}) obtained at {3:yyyy-MM-dd HH:mm:ss}, while {4} {1}s ({5}) might be duplicated.</b>", m_Samples.Count, typeName, GetByteLengthString(m_SampleSize), m_SampleTime.ToLocalTime(), m_DuplicateSimpleCount, GetByteLengthString(m_DuplicateSampleSize)));
}
else
{
GUILayout.Label(Utility.Text.Format("<b>{0} {1}s ({2}) obtained at {3:yyyy-MM-dd HH:mm:ss}.</b>", m_Samples.Count, typeName, GetByteLengthString(m_SampleSize), m_SampleTime.ToLocalTime()));
}
if (m_Samples.Count > 0)
{
GUILayout.BeginHorizontal();
{
GUILayout.Label(Utility.Text.Format("<b>{0} Name</b>", typeName));
GUILayout.Label("<b>Type</b>", GUILayout.Width(240f));
GUILayout.Label("<b>Size</b>", GUILayout.Width(80f));
}
GUILayout.EndHorizontal();
}
int count = 0;
for (int i = 0; i < m_Samples.Count; i++)
{
GUILayout.BeginHorizontal();
{
GUILayout.Label(m_Samples[i].Highlight ? Utility.Text.Format("<color=yellow>{0}</color>", m_Samples[i].Name) : m_Samples[i].Name);
GUILayout.Label(m_Samples[i].Highlight ? Utility.Text.Format("<color=yellow>{0}</color>", m_Samples[i].Type) : m_Samples[i].Type, GUILayout.Width(240f));
GUILayout.Label(m_Samples[i].Highlight ? Utility.Text.Format("<color=yellow>{0}</color>", GetByteLengthString(m_Samples[i].Size)) : GetByteLengthString(m_Samples[i].Size), GUILayout.Width(80f));
}
GUILayout.EndHorizontal();
count++;
if (count >= ShowSampleCount)
{
break;
}
}
}
}
GUILayout.EndVertical();
}
private void TakeSample()
{
m_SampleTime = DateTime.UtcNow;
m_SampleSize = 0L;
m_DuplicateSampleSize = 0L;
m_DuplicateSimpleCount = 0;
m_Samples.Clear();
T[] samples = Resources.FindObjectsOfTypeAll<T>();
for (int i = 0; i < samples.Length; i++)
{
long sampleSize = 0L;
#if UNITY_5_6_OR_NEWER
sampleSize = Profiler.GetRuntimeMemorySizeLong(samples[i]);
#else
sampleSize = Profiler.GetRuntimeMemorySize(samples[i]);
#endif
m_SampleSize += sampleSize;
m_Samples.Add(new Sample(samples[i].name, samples[i].GetType().Name, sampleSize));
}
m_Samples.Sort(m_SampleComparer);
for (int i = 1; i < m_Samples.Count; i++)
{
if (m_Samples[i].Name == m_Samples[i - 1].Name && m_Samples[i].Type == m_Samples[i - 1].Type && m_Samples[i].Size == m_Samples[i - 1].Size)
{
m_Samples[i].Highlight = true;
m_DuplicateSampleSize += m_Samples[i].Size;
m_DuplicateSimpleCount++;
}
}
}
private static int SampleComparer(Sample a, Sample b)
{
int result = b.Size.CompareTo(a.Size);
if (result != 0)
{
return result;
}
result = a.Type.CompareTo(b.Type);
if (result != 0)
{
return result;
}
return a.Name.CompareTo(b.Name);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c46a0358d21f41a1bffbeb15874b7986
timeCreated: 1680489774

View File

@@ -0,0 +1,54 @@
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed partial class RuntimeMemorySummaryWindow : ScrollableDebuggerWindowBase
{
private sealed class Record
{
private readonly string m_Name;
private int m_Count;
private long m_Size;
public Record(string name)
{
m_Name = name;
m_Count = 0;
m_Size = 0L;
}
public string Name
{
get
{
return m_Name;
}
}
public int Count
{
get
{
return m_Count;
}
set
{
m_Count = value;
}
}
public long Size
{
get
{
return m_Size;
}
set
{
m_Size = value;
}
}
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0fe142cd19ea404092e714667f5e75d1
timeCreated: 1680489774

View File

@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_5_5_OR_NEWER
using UnityEngine.Profiling;
#endif
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed partial class RuntimeMemorySummaryWindow : ScrollableDebuggerWindowBase
{
private readonly List<Record> m_Records = new List<Record>();
private readonly Comparison<Record> m_RecordComparer = RecordComparer;
private DateTime m_SampleTime = DateTime.MinValue;
private int m_SampleCount = 0;
private long m_SampleSize = 0L;
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Runtime Memory Summary</b>");
GUILayout.BeginVertical("box");
{
if (GUILayout.Button("Take Sample", GUILayout.Height(30f)))
{
TakeSample();
}
if (m_SampleTime <= DateTime.MinValue)
{
GUILayout.Label("<b>Please take sample first.</b>");
}
else
{
GUILayout.Label(Utility.Text.Format("<b>{0} Objects ({1}) obtained at {2:yyyy-MM-dd HH:mm:ss}.</b>", m_SampleCount, GetByteLengthString(m_SampleSize), m_SampleTime.ToLocalTime()));
GUILayout.BeginHorizontal();
{
GUILayout.Label("<b>Type</b>");
GUILayout.Label("<b>Count</b>", GUILayout.Width(120f));
GUILayout.Label("<b>Size</b>", GUILayout.Width(120f));
}
GUILayout.EndHorizontal();
for (int i = 0; i < m_Records.Count; i++)
{
GUILayout.BeginHorizontal();
{
GUILayout.Label(m_Records[i].Name);
GUILayout.Label(m_Records[i].Count.ToString(), GUILayout.Width(120f));
GUILayout.Label(GetByteLengthString(m_Records[i].Size), GUILayout.Width(120f));
}
GUILayout.EndHorizontal();
}
}
}
GUILayout.EndVertical();
}
private void TakeSample()
{
m_Records.Clear();
m_SampleTime = DateTime.UtcNow;
m_SampleCount = 0;
m_SampleSize = 0L;
UnityEngine.Object[] samples = Resources.FindObjectsOfTypeAll<UnityEngine.Object>();
for (int i = 0; i < samples.Length; i++)
{
long sampleSize = 0L;
#if UNITY_5_6_OR_NEWER
sampleSize = Profiler.GetRuntimeMemorySizeLong(samples[i]);
#else
sampleSize = Profiler.GetRuntimeMemorySize(samples[i]);
#endif
string name = samples[i].GetType().Name;
m_SampleCount++;
m_SampleSize += sampleSize;
Record record = null;
foreach (Record r in m_Records)
{
if (r.Name == name)
{
record = r;
break;
}
}
if (record == null)
{
record = new Record(name);
m_Records.Add(record);
}
record.Count++;
record.Size += sampleSize;
}
m_Records.Sort(m_RecordComparer);
}
private static int RecordComparer(Record a, Record b)
{
int result = b.Size.CompareTo(a.Size);
if (result != 0)
{
return result;
}
result = a.Count.CompareTo(b.Count);
if (result != 0)
{
return result;
}
return a.Name.CompareTo(b.Name);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 57978b9ccd8246c8a63d3384f9010078
timeCreated: 1680489774

View File

@@ -0,0 +1,37 @@
using UnityEngine;
using UnityEngine.SceneManagement;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class SceneInformationWindow : ScrollableDebuggerWindowBase
{
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Scene Information</b>");
GUILayout.BeginVertical("box");
{
DrawItem("Scene Count", SceneManager.sceneCount.ToString());
DrawItem("Scene Count In Build Settings", SceneManager.sceneCountInBuildSettings.ToString());
Scene activeScene = SceneManager.GetActiveScene();
#if UNITY_2018_3_OR_NEWER
DrawItem("Active Scene Handle", activeScene.handle.ToString());
#endif
DrawItem("Active Scene Name", activeScene.name);
DrawItem("Active Scene Path", activeScene.path);
DrawItem("Active Scene Build Index", activeScene.buildIndex.ToString());
DrawItem("Active Scene Is Dirty", activeScene.isDirty.ToString());
DrawItem("Active Scene Is Loaded", activeScene.isLoaded.ToString());
DrawItem("Active Scene Is Valid", activeScene.IsValid().ToString());
DrawItem("Active Scene Root Count", activeScene.rootCount.ToString());
#if UNITY_2019_1_OR_NEWER
DrawItem("Active Scene Is Sub Scene", activeScene.isSubScene.ToString());
#endif
}
GUILayout.EndVertical();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 23188b9cc7074bbfaeb3023f6a2e317e
timeCreated: 1680489774

View File

@@ -0,0 +1,87 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class ScreenInformationWindow : ScrollableDebuggerWindowBase
{
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Screen Information</b>");
GUILayout.BeginVertical("box");
{
DrawItem("Current Resolution", GetResolutionString(Screen.currentResolution));
DrawItem("Screen Width", Utility.Text.Format("{0} px / {1:F2} in / {2:F2} cm", Screen.width, Utility.Converter.GetInchesFromPixels(Screen.width), Utility.Converter.GetCentimetersFromPixels(Screen.width)));
DrawItem("Screen Height", Utility.Text.Format("{0} px / {1:F2} in / {2:F2} cm", Screen.height, Utility.Converter.GetInchesFromPixels(Screen.height), Utility.Converter.GetCentimetersFromPixels(Screen.height)));
DrawItem("Screen DPI", Screen.dpi.ToString("F2"));
DrawItem("Screen Orientation", Screen.orientation.ToString());
DrawItem("Is Full Screen", Screen.fullScreen.ToString());
#if UNITY_2018_1_OR_NEWER
DrawItem("Full Screen Mode", Screen.fullScreenMode.ToString());
#endif
DrawItem("Sleep Timeout", GetSleepTimeoutDescription(Screen.sleepTimeout));
#if UNITY_2019_2_OR_NEWER
DrawItem("Brightness", Screen.brightness.ToString("F2"));
#endif
DrawItem("Cursor Visible", Cursor.visible.ToString());
DrawItem("Cursor Lock State", Cursor.lockState.ToString());
DrawItem("Auto Landscape Left", Screen.autorotateToLandscapeLeft.ToString());
DrawItem("Auto Landscape Right", Screen.autorotateToLandscapeRight.ToString());
DrawItem("Auto Portrait", Screen.autorotateToPortrait.ToString());
DrawItem("Auto Portrait Upside Down", Screen.autorotateToPortraitUpsideDown.ToString());
#if UNITY_2017_2_OR_NEWER && !UNITY_2017_2_0
DrawItem("Safe Area", Screen.safeArea.ToString());
#endif
#if UNITY_2019_2_OR_NEWER
DrawItem("Cutouts", GetCutoutsString(Screen.cutouts));
#endif
DrawItem("Support Resolutions", GetResolutionsString(Screen.resolutions));
}
GUILayout.EndVertical();
}
private string GetSleepTimeoutDescription(int sleepTimeout)
{
if (sleepTimeout == SleepTimeout.NeverSleep)
{
return "Never Sleep";
}
if (sleepTimeout == SleepTimeout.SystemSetting)
{
return "System Setting";
}
return sleepTimeout.ToString();
}
private string GetResolutionString(Resolution resolution)
{
return Utility.Text.Format("{0} x {1} @ {2}Hz", resolution.width, resolution.height, resolution.refreshRate);
}
private string GetCutoutsString(Rect[] cutouts)
{
string[] cutoutStrings = new string[cutouts.Length];
for (int i = 0; i < cutouts.Length; i++)
{
cutoutStrings[i] = cutouts[i].ToString();
}
return string.Join("; ", cutoutStrings);
}
private string GetResolutionsString(Resolution[] resolutions)
{
string[] resolutionStrings = new string[resolutions.Length];
for (int i = 0; i < resolutions.Length; i++)
{
resolutionStrings[i] = GetResolutionString(resolutions[i]);
}
return string.Join("; ", resolutionStrings);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b2e9629c3200474c83a384685f1b32d0
timeCreated: 1680489774

View File

@@ -0,0 +1,92 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private abstract class ScrollableDebuggerWindowBase : IDebuggerWindow
{
private const float TitleWidth = 240f;
private Vector2 m_ScrollPosition = Vector2.zero;
public virtual void Initialize(params object[] args)
{
}
public virtual void Shutdown()
{
}
public virtual void OnEnter()
{
}
public virtual void OnLeave()
{
}
public virtual void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
}
public void OnDraw()
{
m_ScrollPosition = GUILayout.BeginScrollView(m_ScrollPosition);
{
OnDrawScrollableWindow();
}
GUILayout.EndScrollView();
}
protected abstract void OnDrawScrollableWindow();
protected static void DrawItem(string title, string content)
{
GUILayout.BeginHorizontal();
{
GUILayout.Label(title, GUILayout.Width(TitleWidth));
if (GUILayout.Button(content, "label"))
{
CopyToClipboard(content);
}
}
GUILayout.EndHorizontal();
}
protected static string GetByteLengthString(long byteLength)
{
if (byteLength < 1024L) // 2 ^ 10
{
return Utility.Text.Format("{0} Bytes", byteLength);
}
if (byteLength < 1048576L) // 2 ^ 20
{
return Utility.Text.Format("{0:F2} KB", byteLength / 1024f);
}
if (byteLength < 1073741824L) // 2 ^ 30
{
return Utility.Text.Format("{0:F2} MB", byteLength / 1048576f);
}
if (byteLength < 1099511627776L) // 2 ^ 40
{
return Utility.Text.Format("{0:F2} GB", byteLength / 1073741824f);
}
if (byteLength < 1125899906842624L) // 2 ^ 50
{
return Utility.Text.Format("{0:F2} TB", byteLength / 1099511627776f);
}
if (byteLength < 1152921504606846976L) // 2 ^ 60
{
return Utility.Text.Format("{0:F2} PB", byteLength / 1125899906842624f);
}
return Utility.Text.Format("{0:F2} EB", byteLength / 1152921504606846976f);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1ab46898981a41189c05d040d7c9291e
timeCreated: 1680489774

View File

@@ -0,0 +1,212 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class SettingsWindow : ScrollableDebuggerWindowBase
{
private DebuggerComponent m_DebuggerComponent = null;
private SettingComponent m_SettingComponent = null;
private float m_LastIconX = 0f;
private float m_LastIconY = 0f;
private float m_LastWindowX = 0f;
private float m_LastWindowY = 0f;
private float m_LastWindowWidth = 0f;
private float m_LastWindowHeight = 0f;
private float m_LastWindowScale = 0f;
public override void Initialize(params object[] args)
{
m_DebuggerComponent = GameEntry.GetComponent<DebuggerComponent>();
if (m_DebuggerComponent == null)
{
Log.Fatal("Debugger component is invalid.");
return;
}
m_SettingComponent = GameEntry.GetComponent<SettingComponent>();
if (m_SettingComponent == null)
{
Log.Fatal("Setting component is invalid.");
return;
}
m_LastIconX = m_SettingComponent.GetFloat("Debugger.Icon.X", DefaultIconRect.x);
m_LastIconY = m_SettingComponent.GetFloat("Debugger.Icon.Y", DefaultIconRect.y);
m_LastWindowX = m_SettingComponent.GetFloat("Debugger.Window.X", DefaultWindowRect.x);
m_LastWindowY = m_SettingComponent.GetFloat("Debugger.Window.Y", DefaultWindowRect.y);
m_LastWindowWidth = m_SettingComponent.GetFloat("Debugger.Window.Width", DefaultWindowRect.width);
m_LastWindowHeight = m_SettingComponent.GetFloat("Debugger.Window.Height", DefaultWindowRect.height);
m_DebuggerComponent.WindowScale = m_LastWindowScale = m_SettingComponent.GetFloat("Debugger.Window.Scale", DefaultWindowScale);
m_DebuggerComponent.IconRect = new Rect(m_LastIconX, m_LastIconY, DefaultIconRect.width, DefaultIconRect.height);
m_DebuggerComponent.WindowRect = new Rect(m_LastWindowX, m_LastWindowY, m_LastWindowWidth, m_LastWindowHeight);
}
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
if (m_LastIconX != m_DebuggerComponent.IconRect.x)
{
m_LastIconX = m_DebuggerComponent.IconRect.x;
m_SettingComponent.SetFloat("Debugger.Icon.X", m_DebuggerComponent.IconRect.x);
}
if (m_LastIconY != m_DebuggerComponent.IconRect.y)
{
m_LastIconY = m_DebuggerComponent.IconRect.y;
m_SettingComponent.SetFloat("Debugger.Icon.Y", m_DebuggerComponent.IconRect.y);
}
if (m_LastWindowX != m_DebuggerComponent.WindowRect.x)
{
m_LastWindowX = m_DebuggerComponent.WindowRect.x;
m_SettingComponent.SetFloat("Debugger.Window.X", m_DebuggerComponent.WindowRect.x);
}
if (m_LastWindowY != m_DebuggerComponent.WindowRect.y)
{
m_LastWindowY = m_DebuggerComponent.WindowRect.y;
m_SettingComponent.SetFloat("Debugger.Window.Y", m_DebuggerComponent.WindowRect.y);
}
if (m_LastWindowWidth != m_DebuggerComponent.WindowRect.width)
{
m_LastWindowWidth = m_DebuggerComponent.WindowRect.width;
m_SettingComponent.SetFloat("Debugger.Window.Width", m_DebuggerComponent.WindowRect.width);
}
if (m_LastWindowHeight != m_DebuggerComponent.WindowRect.height)
{
m_LastWindowHeight = m_DebuggerComponent.WindowRect.height;
m_SettingComponent.SetFloat("Debugger.Window.Height", m_DebuggerComponent.WindowRect.height);
}
if (m_LastWindowScale != m_DebuggerComponent.WindowScale)
{
m_LastWindowScale = m_DebuggerComponent.WindowScale;
m_SettingComponent.SetFloat("Debugger.Window.Scale", m_DebuggerComponent.WindowScale);
}
}
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Window Settings</b>");
GUILayout.BeginVertical("box");
{
GUILayout.BeginHorizontal();
{
GUILayout.Label("Position:", GUILayout.Width(60f));
GUILayout.Label("Drag window caption to move position.");
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
{
float width = m_DebuggerComponent.WindowRect.width;
GUILayout.Label("Width:", GUILayout.Width(60f));
if (GUILayout.RepeatButton("-", GUILayout.Width(30f)))
{
width--;
}
width = GUILayout.HorizontalSlider(width, 100f, Screen.width - 20f);
if (GUILayout.RepeatButton("+", GUILayout.Width(30f)))
{
width++;
}
width = Mathf.Clamp(width, 100f, Screen.width - 20f);
if (width != m_DebuggerComponent.WindowRect.width)
{
m_DebuggerComponent.WindowRect = new Rect(m_DebuggerComponent.WindowRect.x, m_DebuggerComponent.WindowRect.y, width, m_DebuggerComponent.WindowRect.height);
}
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
{
float height = m_DebuggerComponent.WindowRect.height;
GUILayout.Label("Height:", GUILayout.Width(60f));
if (GUILayout.RepeatButton("-", GUILayout.Width(30f)))
{
height--;
}
height = GUILayout.HorizontalSlider(height, 100f, Screen.height - 20f);
if (GUILayout.RepeatButton("+", GUILayout.Width(30f)))
{
height++;
}
height = Mathf.Clamp(height, 100f, Screen.height - 20f);
if (height != m_DebuggerComponent.WindowRect.height)
{
m_DebuggerComponent.WindowRect = new Rect(m_DebuggerComponent.WindowRect.x, m_DebuggerComponent.WindowRect.y, m_DebuggerComponent.WindowRect.width, height);
}
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
{
float scale = m_DebuggerComponent.WindowScale;
GUILayout.Label("Scale:", GUILayout.Width(60f));
if (GUILayout.RepeatButton("-", GUILayout.Width(30f)))
{
scale -= 0.01f;
}
scale = GUILayout.HorizontalSlider(scale, 0.5f, 4f);
if (GUILayout.RepeatButton("+", GUILayout.Width(30f)))
{
scale += 0.01f;
}
scale = Mathf.Clamp(scale, 0.5f, 4f);
if (scale != m_DebuggerComponent.WindowScale)
{
m_DebuggerComponent.WindowScale = scale;
}
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
{
if (GUILayout.Button("0.5x", GUILayout.Height(60f)))
{
m_DebuggerComponent.WindowScale = 0.5f;
}
if (GUILayout.Button("1.0x", GUILayout.Height(60f)))
{
m_DebuggerComponent.WindowScale = 1f;
}
if (GUILayout.Button("1.5x", GUILayout.Height(60f)))
{
m_DebuggerComponent.WindowScale = 1.5f;
}
if (GUILayout.Button("2.0x", GUILayout.Height(60f)))
{
m_DebuggerComponent.WindowScale = 2f;
}
if (GUILayout.Button("2.5x", GUILayout.Height(60f)))
{
m_DebuggerComponent.WindowScale = 2.5f;
}
if (GUILayout.Button("3.0x", GUILayout.Height(60f)))
{
m_DebuggerComponent.WindowScale = 3f;
}
if (GUILayout.Button("3.5x", GUILayout.Height(60f)))
{
m_DebuggerComponent.WindowScale = 3.5f;
}
if (GUILayout.Button("4.0x", GUILayout.Height(60f)))
{
m_DebuggerComponent.WindowScale = 4f;
}
}
GUILayout.EndHorizontal();
if (GUILayout.Button("Reset Layout", GUILayout.Height(30f)))
{
m_DebuggerComponent.ResetLayout();
}
}
GUILayout.EndVertical();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d6cd4faabca74c3f9af9cd407d4663d5
timeCreated: 1680489774

View File

@@ -0,0 +1,54 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class SystemInformationWindow : ScrollableDebuggerWindowBase
{
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>System Information</b>");
GUILayout.BeginVertical("box");
{
DrawItem("Device Unique ID", SystemInfo.deviceUniqueIdentifier);
DrawItem("Device Name", SystemInfo.deviceName);
DrawItem("Device Type", SystemInfo.deviceType.ToString());
DrawItem("Device Model", SystemInfo.deviceModel);
DrawItem("Processor Type", SystemInfo.processorType);
DrawItem("Processor Count", SystemInfo.processorCount.ToString());
DrawItem("Processor Frequency", Utility.Text.Format("{0} MHz", SystemInfo.processorFrequency));
DrawItem("System Memory Size", Utility.Text.Format("{0} MB", SystemInfo.systemMemorySize));
#if UNITY_5_5_OR_NEWER
DrawItem("Operating System Family", SystemInfo.operatingSystemFamily.ToString());
#endif
DrawItem("Operating System", SystemInfo.operatingSystem);
#if UNITY_5_6_OR_NEWER
DrawItem("Battery Status", SystemInfo.batteryStatus.ToString());
DrawItem("Battery Level", GetBatteryLevelString(SystemInfo.batteryLevel));
#endif
#if UNITY_5_4_OR_NEWER
DrawItem("Supports Audio", SystemInfo.supportsAudio.ToString());
#endif
DrawItem("Supports Location Service", SystemInfo.supportsLocationService.ToString());
DrawItem("Supports Accelerometer", SystemInfo.supportsAccelerometer.ToString());
DrawItem("Supports Gyroscope", SystemInfo.supportsGyroscope.ToString());
DrawItem("Supports Vibration", SystemInfo.supportsVibration.ToString());
DrawItem("Genuine", Application.genuine.ToString());
DrawItem("Genuine Check Available", Application.genuineCheckAvailable.ToString());
}
GUILayout.EndVertical();
}
private string GetBatteryLevelString(float batteryLevel)
{
if (batteryLevel < 0f)
{
return "Unavailable";
}
return batteryLevel.ToString("P0");
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: dce6d86504004300ae4dbbd204f53f8b
timeCreated: 1680489774

View File

@@ -0,0 +1,68 @@
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class TimeInformationWindow : ScrollableDebuggerWindowBase
{
protected override void OnDrawScrollableWindow()
{
GUILayout.Label("<b>Time Information</b>");
GUILayout.BeginVertical("box");
{
DrawItem("Time Scale", Utility.Text.Format("{0} [{1}]", Time.timeScale, GetTimeScaleDescription(Time.timeScale)));
DrawItem("Realtime Since Startup", Time.realtimeSinceStartup.ToString());
DrawItem("Time Since Level Load", Time.timeSinceLevelLoad.ToString());
DrawItem("Time", Time.time.ToString());
DrawItem("Fixed Time", Time.fixedTime.ToString());
DrawItem("Unscaled Time", Time.unscaledTime.ToString());
#if UNITY_5_6_OR_NEWER
DrawItem("Fixed Unscaled Time", Time.fixedUnscaledTime.ToString());
#endif
DrawItem("Delta Time", Time.deltaTime.ToString());
DrawItem("Fixed Delta Time", Time.fixedDeltaTime.ToString());
DrawItem("Unscaled Delta Time", Time.unscaledDeltaTime.ToString());
#if UNITY_5_6_OR_NEWER
DrawItem("Fixed Unscaled Delta Time", Time.fixedUnscaledDeltaTime.ToString());
#endif
DrawItem("Smooth Delta Time", Time.smoothDeltaTime.ToString());
DrawItem("Maximum Delta Time", Time.maximumDeltaTime.ToString());
#if UNITY_5_5_OR_NEWER
DrawItem("Maximum Particle Delta Time", Time.maximumParticleDeltaTime.ToString());
#endif
DrawItem("Frame Count", Time.frameCount.ToString());
DrawItem("Rendered Frame Count", Time.renderedFrameCount.ToString());
DrawItem("Capture Framerate", Time.captureFramerate.ToString());
#if UNITY_2019_2_OR_NEWER
DrawItem("Capture Delta Time", Time.captureDeltaTime.ToString());
#endif
#if UNITY_5_6_OR_NEWER
DrawItem("In Fixed Time Step", Time.inFixedTimeStep.ToString());
#endif
}
GUILayout.EndVertical();
}
private string GetTimeScaleDescription(float timeScale)
{
if (timeScale <= 0f)
{
return "Pause";
}
if (timeScale < 1f)
{
return "Slower";
}
if (timeScale > 1f)
{
return "Faster";
}
return "Normal";
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 49e6de7a5fa043ba9c489ac67147bbee
timeCreated: 1680489775

View File

@@ -0,0 +1,28 @@
namespace TEngine
{
/// <summary>
/// 调试器激活窗口类型。
/// </summary>
public enum DebuggerActiveWindowType : byte
{
/// <summary>
/// 总是打开。
/// </summary>
AlwaysOpen = 0,
/// <summary>
/// 仅在开发模式时打开。
/// </summary>
OnlyOpenWhenDevelopment,
/// <summary>
/// 仅在编辑器中打开。
/// </summary>
OnlyOpenInEditor,
/// <summary>
/// 总是关闭。
/// </summary>
AlwaysClose,
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 71186a1869d3486e8a8b47c9053623c5
timeCreated: 1680489774

View File

@@ -0,0 +1,500 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
[Serializable]
private sealed class ConsoleWindow : IDebuggerWindow
{
private readonly Queue<LogNode> m_LogNodes = new Queue<LogNode>();
private SettingComponent m_SettingComponent = null;
private Vector2 m_LogScrollPosition = Vector2.zero;
private Vector2 m_StackScrollPosition = Vector2.zero;
private int m_InfoCount = 0;
private int m_WarningCount = 0;
private int m_ErrorCount = 0;
private int m_FatalCount = 0;
private LogNode m_SelectedNode = null;
private bool m_LastLockScroll = true;
private bool m_LastInfoFilter = true;
private bool m_LastWarningFilter = true;
private bool m_LastErrorFilter = true;
private bool m_LastFatalFilter = true;
[SerializeField]
private bool m_LockScroll = true;
[SerializeField]
private int m_MaxLine = 100;
[SerializeField]
private bool m_InfoFilter = true;
[SerializeField]
private bool m_WarningFilter = true;
[SerializeField]
private bool m_ErrorFilter = true;
[SerializeField]
private bool m_FatalFilter = true;
[SerializeField]
private Color32 m_InfoColor = Color.white;
[SerializeField]
private Color32 m_WarningColor = Color.yellow;
[SerializeField]
private Color32 m_ErrorColor = Color.red;
[SerializeField]
private Color32 m_FatalColor = new Color(0.7f, 0.2f, 0.2f);
public bool LockScroll
{
get
{
return m_LockScroll;
}
set
{
m_LockScroll = value;
}
}
public int MaxLine
{
get
{
return m_MaxLine;
}
set
{
m_MaxLine = value;
}
}
public bool InfoFilter
{
get
{
return m_InfoFilter;
}
set
{
m_InfoFilter = value;
}
}
public bool WarningFilter
{
get
{
return m_WarningFilter;
}
set
{
m_WarningFilter = value;
}
}
public bool ErrorFilter
{
get
{
return m_ErrorFilter;
}
set
{
m_ErrorFilter = value;
}
}
public bool FatalFilter
{
get
{
return m_FatalFilter;
}
set
{
m_FatalFilter = value;
}
}
public int InfoCount
{
get
{
return m_InfoCount;
}
}
public int WarningCount
{
get
{
return m_WarningCount;
}
}
public int ErrorCount
{
get
{
return m_ErrorCount;
}
}
public int FatalCount
{
get
{
return m_FatalCount;
}
}
public Color32 InfoColor
{
get
{
return m_InfoColor;
}
set
{
m_InfoColor = value;
}
}
public Color32 WarningColor
{
get
{
return m_WarningColor;
}
set
{
m_WarningColor = value;
}
}
public Color32 ErrorColor
{
get
{
return m_ErrorColor;
}
set
{
m_ErrorColor = value;
}
}
public Color32 FatalColor
{
get
{
return m_FatalColor;
}
set
{
m_FatalColor = value;
}
}
public void Initialize(params object[] args)
{
m_SettingComponent = GameEntry.GetComponent<SettingComponent>();
if (m_SettingComponent == null)
{
Log.Fatal("Setting component is invalid.");
return;
}
Application.logMessageReceived += OnLogMessageReceived;
m_LockScroll = m_LastLockScroll = m_SettingComponent.GetBool("Debugger.Console.LockScroll", true);
m_InfoFilter = m_LastInfoFilter = m_SettingComponent.GetBool("Debugger.Console.InfoFilter", true);
m_WarningFilter = m_LastWarningFilter = m_SettingComponent.GetBool("Debugger.Console.WarningFilter", true);
m_ErrorFilter = m_LastErrorFilter = m_SettingComponent.GetBool("Debugger.Console.ErrorFilter", true);
m_FatalFilter = m_LastFatalFilter = m_SettingComponent.GetBool("Debugger.Console.FatalFilter", true);
}
public void Shutdown()
{
Application.logMessageReceived -= OnLogMessageReceived;
Clear();
}
public void OnEnter()
{
}
public void OnLeave()
{
}
public void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
if (m_LastLockScroll != m_LockScroll)
{
m_LastLockScroll = m_LockScroll;
m_SettingComponent.SetBool("Debugger.Console.LockScroll", m_LockScroll);
}
if (m_LastInfoFilter != m_InfoFilter)
{
m_LastInfoFilter = m_InfoFilter;
m_SettingComponent.SetBool("Debugger.Console.InfoFilter", m_InfoFilter);
}
if (m_LastWarningFilter != m_WarningFilter)
{
m_LastWarningFilter = m_WarningFilter;
m_SettingComponent.SetBool("Debugger.Console.WarningFilter", m_WarningFilter);
}
if (m_LastErrorFilter != m_ErrorFilter)
{
m_LastErrorFilter = m_ErrorFilter;
m_SettingComponent.SetBool("Debugger.Console.ErrorFilter", m_ErrorFilter);
}
if (m_LastFatalFilter != m_FatalFilter)
{
m_LastFatalFilter = m_FatalFilter;
m_SettingComponent.SetBool("Debugger.Console.FatalFilter", m_FatalFilter);
}
}
public void OnDraw()
{
RefreshCount();
GUILayout.BeginHorizontal();
{
if (GUILayout.Button("Clear All", GUILayout.Width(100f)))
{
Clear();
}
m_LockScroll = GUILayout.Toggle(m_LockScroll, "Lock Scroll", GUILayout.Width(90f));
GUILayout.FlexibleSpace();
m_InfoFilter = GUILayout.Toggle(m_InfoFilter, Utility.Text.Format("Info ({0})", m_InfoCount), GUILayout.Width(90f));
m_WarningFilter = GUILayout.Toggle(m_WarningFilter, Utility.Text.Format("Warning ({0})", m_WarningCount), GUILayout.Width(90f));
m_ErrorFilter = GUILayout.Toggle(m_ErrorFilter, Utility.Text.Format("Error ({0})", m_ErrorCount), GUILayout.Width(90f));
m_FatalFilter = GUILayout.Toggle(m_FatalFilter, Utility.Text.Format("Fatal ({0})", m_FatalCount), GUILayout.Width(90f));
}
GUILayout.EndHorizontal();
GUILayout.BeginVertical("box");
{
if (m_LockScroll)
{
m_LogScrollPosition.y = float.MaxValue;
}
m_LogScrollPosition = GUILayout.BeginScrollView(m_LogScrollPosition);
{
bool selected = false;
foreach (LogNode logNode in m_LogNodes)
{
switch (logNode.LogType)
{
case LogType.Log:
if (!m_InfoFilter)
{
continue;
}
break;
case LogType.Warning:
if (!m_WarningFilter)
{
continue;
}
break;
case LogType.Error:
if (!m_ErrorFilter)
{
continue;
}
break;
case LogType.Exception:
if (!m_FatalFilter)
{
continue;
}
break;
}
if (GUILayout.Toggle(m_SelectedNode == logNode, GetLogString(logNode)))
{
selected = true;
if (m_SelectedNode != logNode)
{
m_SelectedNode = logNode;
m_StackScrollPosition = Vector2.zero;
}
}
}
if (!selected)
{
m_SelectedNode = null;
}
}
GUILayout.EndScrollView();
}
GUILayout.EndVertical();
GUILayout.BeginVertical("box");
{
m_StackScrollPosition = GUILayout.BeginScrollView(m_StackScrollPosition, GUILayout.Height(100f));
{
if (m_SelectedNode != null)
{
Color32 color = GetLogStringColor(m_SelectedNode.LogType);
if (GUILayout.Button(Utility.Text.Format("<color=#{0:x2}{1:x2}{2:x2}{3:x2}><b>{4}</b></color>{6}{6}{5}", color.r, color.g, color.b, color.a, m_SelectedNode.LogMessage, m_SelectedNode.StackTrack, Environment.NewLine), "label"))
{
CopyToClipboard(Utility.Text.Format("{0}{2}{2}{1}", m_SelectedNode.LogMessage, m_SelectedNode.StackTrack, Environment.NewLine));
}
}
}
GUILayout.EndScrollView();
}
GUILayout.EndVertical();
}
private void Clear()
{
m_LogNodes.Clear();
}
public void RefreshCount()
{
m_InfoCount = 0;
m_WarningCount = 0;
m_ErrorCount = 0;
m_FatalCount = 0;
foreach (LogNode logNode in m_LogNodes)
{
switch (logNode.LogType)
{
case LogType.Log:
m_InfoCount++;
break;
case LogType.Warning:
m_WarningCount++;
break;
case LogType.Error:
m_ErrorCount++;
break;
case LogType.Exception:
m_FatalCount++;
break;
}
}
}
public void GetRecentLogs(List<LogNode> results)
{
if (results == null)
{
Log.Error("Results is invalid.");
return;
}
results.Clear();
foreach (LogNode logNode in m_LogNodes)
{
results.Add(logNode);
}
}
public void GetRecentLogs(List<LogNode> results, int count)
{
if (results == null)
{
Log.Error("Results is invalid.");
return;
}
if (count <= 0)
{
Log.Error("Count is invalid.");
return;
}
int position = m_LogNodes.Count - count;
if (position < 0)
{
position = 0;
}
int index = 0;
results.Clear();
foreach (LogNode logNode in m_LogNodes)
{
if (index++ < position)
{
continue;
}
results.Add(logNode);
}
}
private void OnLogMessageReceived(string logMessage, string stackTrace, LogType logType)
{
if (logType == LogType.Assert)
{
logType = LogType.Error;
}
m_LogNodes.Enqueue(LogNode.Create(logType, logMessage, stackTrace));
while (m_LogNodes.Count > m_MaxLine)
{
MemoryPool.Release(m_LogNodes.Dequeue());
}
}
private string GetLogString(LogNode logNode)
{
Color32 color = GetLogStringColor(logNode.LogType);
return Utility.Text.Format("<color=#{0:x2}{1:x2}{2:x2}{3:x2}>[{4:HH:mm:ss.fff}][{5}] {6}</color>", color.r, color.g, color.b, color.a, logNode.LogTime.ToLocalTime(), logNode.LogFrameCount, logNode.LogMessage);
}
internal Color32 GetLogStringColor(LogType logType)
{
Color32 color = Color.white;
switch (logType)
{
case LogType.Log:
color = m_InfoColor;
break;
case LogType.Warning:
color = m_WarningColor;
break;
case LogType.Error:
color = m_ErrorColor;
break;
case LogType.Exception:
color = m_FatalColor;
break;
}
return color;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: dbdea71d14c947dab46792b72d024906
timeCreated: 1680489774

View File

@@ -0,0 +1,76 @@
namespace TEngine
{
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
private sealed class FpsCounter
{
private float m_UpdateInterval;
private float m_CurrentFps;
private int m_Frames;
private float m_Accumulator;
private float m_TimeLeft;
public FpsCounter(float updateInterval)
{
if (updateInterval <= 0f)
{
Log.Error("Update interval is invalid.");
return;
}
m_UpdateInterval = updateInterval;
Reset();
}
public float UpdateInterval
{
get
{
return m_UpdateInterval;
}
set
{
if (value <= 0f)
{
Log.Error("Update interval is invalid.");
return;
}
m_UpdateInterval = value;
Reset();
}
}
public float CurrentFps
{
get
{
return m_CurrentFps;
}
}
public void Update(float elapseSeconds, float realElapseSeconds)
{
m_Frames++;
m_Accumulator += realElapseSeconds;
m_TimeLeft -= realElapseSeconds;
if (m_TimeLeft <= 0f)
{
m_CurrentFps = m_Accumulator > 0f ? m_Frames / m_Accumulator : 0f;
m_Frames = 0;
m_Accumulator = 0f;
m_TimeLeft += m_UpdateInterval;
}
}
private void Reset()
{
m_CurrentFps = 0f;
m_Frames = 0;
m_Accumulator = 0f;
m_TimeLeft = 0f;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 37c643db0e8a488ebf3941df04d18c35
timeCreated: 1680489774

View File

@@ -0,0 +1,451 @@
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;
namespace TEngine
{
/// <summary>
/// 调试器组件。
/// </summary>
[DisallowMultipleComponent]
public sealed partial class DebuggerComponent : GameFrameworkComponent
{
/// <summary>
/// 默认调试器漂浮框大小。
/// </summary>
internal static readonly Rect DefaultIconRect = new Rect(10f, 10f, 60f, 60f);
/// <summary>
/// 默认调试器窗口大小。
/// </summary>
internal static readonly Rect DefaultWindowRect = new Rect(10f, 10f, 640f, 480f);
/// <summary>
/// 默认调试器窗口缩放比例。
/// </summary>
internal static readonly float DefaultWindowScale = 1.5f;
private static readonly TextEditor s_TextEditor = new TextEditor();
private IDebuggerManager m_DebuggerManager = null;
private Rect m_DragRect = new Rect(0f, 0f, float.MaxValue, 25f);
private Rect m_IconRect = DefaultIconRect;
private Rect m_WindowRect = DefaultWindowRect;
private float m_WindowScale = DefaultWindowScale;
[SerializeField]
private GUISkin m_Skin = null;
[SerializeField]
private DebuggerActiveWindowType m_ActiveWindow = DebuggerActiveWindowType.AlwaysOpen;
[SerializeField]
private bool m_ShowFullWindow = false;
[SerializeField]
private ConsoleWindow m_ConsoleWindow = new ConsoleWindow();
private SystemInformationWindow m_SystemInformationWindow = new SystemInformationWindow();
private EnvironmentInformationWindow m_EnvironmentInformationWindow = new EnvironmentInformationWindow();
private ScreenInformationWindow m_ScreenInformationWindow = new ScreenInformationWindow();
private GraphicsInformationWindow m_GraphicsInformationWindow = new GraphicsInformationWindow();
private InputSummaryInformationWindow m_InputSummaryInformationWindow = new InputSummaryInformationWindow();
private InputTouchInformationWindow m_InputTouchInformationWindow = new InputTouchInformationWindow();
private InputLocationInformationWindow m_InputLocationInformationWindow = new InputLocationInformationWindow();
private InputAccelerationInformationWindow m_InputAccelerationInformationWindow = new InputAccelerationInformationWindow();
private InputGyroscopeInformationWindow m_InputGyroscopeInformationWindow = new InputGyroscopeInformationWindow();
private InputCompassInformationWindow m_InputCompassInformationWindow = new InputCompassInformationWindow();
private PathInformationWindow m_PathInformationWindow = new PathInformationWindow();
private SceneInformationWindow m_SceneInformationWindow = new SceneInformationWindow();
private TimeInformationWindow m_TimeInformationWindow = new TimeInformationWindow();
private QualityInformationWindow m_QualityInformationWindow = new QualityInformationWindow();
private ProfilerInformationWindow m_ProfilerInformationWindow = new ProfilerInformationWindow();
private RuntimeMemorySummaryWindow m_RuntimeMemorySummaryWindow = new RuntimeMemorySummaryWindow();
private RuntimeMemoryInformationWindow<Object> m_RuntimeMemoryAllInformationWindow = new RuntimeMemoryInformationWindow<Object>();
private RuntimeMemoryInformationWindow<Texture> m_RuntimeMemoryTextureInformationWindow = new RuntimeMemoryInformationWindow<Texture>();
private RuntimeMemoryInformationWindow<Mesh> m_RuntimeMemoryMeshInformationWindow = new RuntimeMemoryInformationWindow<Mesh>();
private RuntimeMemoryInformationWindow<Material> m_RuntimeMemoryMaterialInformationWindow = new RuntimeMemoryInformationWindow<Material>();
private RuntimeMemoryInformationWindow<Shader> m_RuntimeMemoryShaderInformationWindow = new RuntimeMemoryInformationWindow<Shader>();
private RuntimeMemoryInformationWindow<AnimationClip> m_RuntimeMemoryAnimationClipInformationWindow = new RuntimeMemoryInformationWindow<AnimationClip>();
private RuntimeMemoryInformationWindow<AudioClip> m_RuntimeMemoryAudioClipInformationWindow = new RuntimeMemoryInformationWindow<AudioClip>();
private RuntimeMemoryInformationWindow<Font> m_RuntimeMemoryFontInformationWindow = new RuntimeMemoryInformationWindow<Font>();
private RuntimeMemoryInformationWindow<TextAsset> m_RuntimeMemoryTextAssetInformationWindow = new RuntimeMemoryInformationWindow<TextAsset>();
private RuntimeMemoryInformationWindow<ScriptableObject> m_RuntimeMemoryScriptableObjectInformationWindow = new RuntimeMemoryInformationWindow<ScriptableObject>();
private ObjectPoolInformationWindow m_ObjectPoolInformationWindow = new ObjectPoolInformationWindow();
private MemoryPoolPoolInformationWindow _mMemoryPoolPoolInformationWindow = new MemoryPoolPoolInformationWindow();
// private NetworkInformationWindow m_NetworkInformationWindow = new NetworkInformationWindow();
private SettingsWindow m_SettingsWindow = new SettingsWindow();
private OperationsWindow m_OperationsWindow = new OperationsWindow();
private FpsCounter m_FpsCounter = null;
/// <summary>
/// 获取或设置调试器窗口是否激活。
/// </summary>
public bool ActiveWindow
{
get
{
return m_DebuggerManager.ActiveWindow;
}
set
{
m_DebuggerManager.ActiveWindow = value;
enabled = value;
}
}
/// <summary>
/// 获取或设置是否显示完整调试器界面。
/// </summary>
public bool ShowFullWindow
{
get
{
return m_ShowFullWindow;
}
set
{
m_ShowFullWindow = value;
}
}
/// <summary>
/// 获取或设置调试器漂浮框大小。
/// </summary>
public Rect IconRect
{
get
{
return m_IconRect;
}
set
{
m_IconRect = value;
}
}
/// <summary>
/// 获取或设置调试器窗口大小。
/// </summary>
public Rect WindowRect
{
get
{
return m_WindowRect;
}
set
{
m_WindowRect = value;
}
}
/// <summary>
/// 获取或设置调试器窗口缩放比例。
/// </summary>
public float WindowScale
{
get
{
return m_WindowScale;
}
set
{
m_WindowScale = value;
}
}
private SettingComponent m_SettingComponent = null;
/// <summary>
/// 游戏框架组件初始化。
/// </summary>
protected override void Awake()
{
base.Awake();
m_DebuggerManager = GameFrameworkEntry.GetModule<IDebuggerManager>();
if (m_DebuggerManager == null)
{
Log.Fatal("Debugger manager is invalid.");
return;
}
m_FpsCounter = new FpsCounter(0.5f);
m_SettingComponent = GameEntry.GetComponent<SettingComponent>();
if (m_SettingComponent == null)
{
Log.Fatal("Setting component is invalid.");
return;
}
var lastIconX = m_SettingComponent.GetFloat("Debugger.Icon.X", DefaultIconRect.x);
var lastIconY = m_SettingComponent.GetFloat("Debugger.Icon.Y", DefaultIconRect.y);
var lastWindowX = m_SettingComponent.GetFloat("Debugger.Window.X", DefaultWindowRect.x);
var lastWindowY = m_SettingComponent.GetFloat("Debugger.Window.Y", DefaultWindowRect.y);
var lastWindowWidth = m_SettingComponent.GetFloat("Debugger.Window.Width", DefaultWindowRect.width);
var lastWindowHeight = m_SettingComponent.GetFloat("Debugger.Window.Height", DefaultWindowRect.height);
m_WindowScale = m_SettingComponent.GetFloat("Debugger.Window.Scale", DefaultWindowScale);
m_WindowRect = new Rect(lastIconX, lastIconY, DefaultIconRect.width, DefaultIconRect.height);
m_WindowRect = new Rect(lastWindowX, lastWindowY, lastWindowWidth, lastWindowHeight);
}
private void OnDestroy()
{
if (m_SettingComponent == null)
{
Log.Fatal("Setting component is invalid.");
return;
}
m_SettingComponent.Save();
}
private void Start()
{
RegisterDebuggerWindow("Console", m_ConsoleWindow);
RegisterDebuggerWindow("Information/System", m_SystemInformationWindow);
RegisterDebuggerWindow("Information/Environment", m_EnvironmentInformationWindow);
RegisterDebuggerWindow("Information/Screen", m_ScreenInformationWindow);
RegisterDebuggerWindow("Information/Graphics", m_GraphicsInformationWindow);
RegisterDebuggerWindow("Information/Input/Summary", m_InputSummaryInformationWindow);
RegisterDebuggerWindow("Information/Input/Touch", m_InputTouchInformationWindow);
RegisterDebuggerWindow("Information/Input/Location", m_InputLocationInformationWindow);
RegisterDebuggerWindow("Information/Input/Acceleration", m_InputAccelerationInformationWindow);
RegisterDebuggerWindow("Information/Input/Gyroscope", m_InputGyroscopeInformationWindow);
RegisterDebuggerWindow("Information/Input/Compass", m_InputCompassInformationWindow);
RegisterDebuggerWindow("Information/Other/Scene", m_SceneInformationWindow);
RegisterDebuggerWindow("Information/Other/Path", m_PathInformationWindow);
RegisterDebuggerWindow("Information/Other/Time", m_TimeInformationWindow);
RegisterDebuggerWindow("Information/Other/Quality", m_QualityInformationWindow);
RegisterDebuggerWindow("Profiler/Summary", m_ProfilerInformationWindow);
RegisterDebuggerWindow("Profiler/Memory/Summary", m_RuntimeMemorySummaryWindow);
RegisterDebuggerWindow("Profiler/Memory/All", m_RuntimeMemoryAllInformationWindow);
RegisterDebuggerWindow("Profiler/Memory/Texture", m_RuntimeMemoryTextureInformationWindow);
RegisterDebuggerWindow("Profiler/Memory/Mesh", m_RuntimeMemoryMeshInformationWindow);
RegisterDebuggerWindow("Profiler/Memory/Material", m_RuntimeMemoryMaterialInformationWindow);
RegisterDebuggerWindow("Profiler/Memory/Shader", m_RuntimeMemoryShaderInformationWindow);
RegisterDebuggerWindow("Profiler/Memory/AnimationClip", m_RuntimeMemoryAnimationClipInformationWindow);
RegisterDebuggerWindow("Profiler/Memory/AudioClip", m_RuntimeMemoryAudioClipInformationWindow);
RegisterDebuggerWindow("Profiler/Memory/Font", m_RuntimeMemoryFontInformationWindow);
RegisterDebuggerWindow("Profiler/Memory/TextAsset", m_RuntimeMemoryTextAssetInformationWindow);
RegisterDebuggerWindow("Profiler/Memory/ScriptableObject", m_RuntimeMemoryScriptableObjectInformationWindow);
RegisterDebuggerWindow("Profiler/Object Pool", m_ObjectPoolInformationWindow);
RegisterDebuggerWindow("Profiler/Reference Pool", _mMemoryPoolPoolInformationWindow);
// RegisterDebuggerWindow("Profiler/Network", m_NetworkInformationWindow);
RegisterDebuggerWindow("Other/Settings", m_SettingsWindow);
RegisterDebuggerWindow("Other/Operations", m_OperationsWindow);
switch (m_ActiveWindow)
{
case DebuggerActiveWindowType.AlwaysOpen:
ActiveWindow = true;
break;
case DebuggerActiveWindowType.OnlyOpenWhenDevelopment:
ActiveWindow = Debug.isDebugBuild;
break;
case DebuggerActiveWindowType.OnlyOpenInEditor:
ActiveWindow = Application.isEditor;
break;
default:
ActiveWindow = false;
break;
}
}
private void Update()
{
m_FpsCounter.Update(Time.deltaTime, Time.unscaledDeltaTime);
}
private void OnGUI()
{
if (m_DebuggerManager == null || !m_DebuggerManager.ActiveWindow)
{
return;
}
GUISkin cachedGuiSkin = GUI.skin;
Matrix4x4 cachedMatrix = GUI.matrix;
GUI.skin = m_Skin;
GUI.matrix = Matrix4x4.Scale(new Vector3(m_WindowScale, m_WindowScale, 1f));
if (m_ShowFullWindow)
{
m_WindowRect = GUILayout.Window(0, m_WindowRect, DrawWindow, "<b>TENGINE DEBUGGER</b>");
}
else
{
m_IconRect = GUILayout.Window(0, m_IconRect, DrawDebuggerWindowIcon, "<b>DEBUGGER</b>");
}
GUI.matrix = cachedMatrix;
GUI.skin = cachedGuiSkin;
}
/// <summary>
/// 注册调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <param name="debuggerWindow">要注册的调试器窗口。</param>
/// <param name="args">初始化调试器窗口参数。</param>
public void RegisterDebuggerWindow(string path, IDebuggerWindow debuggerWindow, params object[] args)
{
m_DebuggerManager.RegisterDebuggerWindow(path, debuggerWindow, args);
}
/// <summary>
/// 解除注册调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <returns>是否解除注册调试器窗口成功。</returns>
public bool UnregisterDebuggerWindow(string path)
{
return m_DebuggerManager.UnregisterDebuggerWindow(path);
}
/// <summary>
/// 获取调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <returns>要获取的调试器窗口。</returns>
public IDebuggerWindow GetDebuggerWindow(string path)
{
return m_DebuggerManager.GetDebuggerWindow(path);
}
/// <summary>
/// 选中调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <returns>是否成功选中调试器窗口。</returns>
public bool SelectDebuggerWindow(string path)
{
return m_DebuggerManager.SelectDebuggerWindow(path);
}
/// <summary>
/// 还原调试器窗口布局。
/// </summary>
public void ResetLayout()
{
IconRect = DefaultIconRect;
WindowRect = DefaultWindowRect;
WindowScale = DefaultWindowScale;
}
/// <summary>
/// 获取记录的所有日志。
/// </summary>
/// <param name="results">要获取的日志。</param>
public void GetRecentLogs(List<LogNode> results)
{
m_ConsoleWindow.GetRecentLogs(results);
}
/// <summary>
/// 获取记录的最近日志。
/// </summary>
/// <param name="results">要获取的日志。</param>
/// <param name="count">要获取最近日志的数量。</param>
public void GetRecentLogs(List<LogNode> results, int count)
{
m_ConsoleWindow.GetRecentLogs(results, count);
}
private void DrawWindow(int windowId)
{
GUI.DragWindow(m_DragRect);
DrawDebuggerWindowGroup(m_DebuggerManager.DebuggerWindowRoot);
}
private void DrawDebuggerWindowGroup(IDebuggerWindowGroup debuggerWindowGroup)
{
if (debuggerWindowGroup == null)
{
return;
}
List<string> names = new List<string>();
string[] debuggerWindowNames = debuggerWindowGroup.GetDebuggerWindowNames();
for (int i = 0; i < debuggerWindowNames.Length; i++)
{
names.Add(Utility.Text.Format("<b>{0}</b>", debuggerWindowNames[i]));
}
if (debuggerWindowGroup == m_DebuggerManager.DebuggerWindowRoot)
{
names.Add("<b>Close</b>");
}
int toolbarIndex = GUILayout.Toolbar(debuggerWindowGroup.SelectedIndex, names.ToArray(), GUILayout.Height(30f), GUILayout.MaxWidth(Screen.width));
if (toolbarIndex >= debuggerWindowGroup.DebuggerWindowCount)
{
m_ShowFullWindow = false;
return;
}
if (debuggerWindowGroup.SelectedWindow == null)
{
return;
}
if (debuggerWindowGroup.SelectedIndex != toolbarIndex)
{
debuggerWindowGroup.SelectedWindow.OnLeave();
debuggerWindowGroup.SelectedIndex = toolbarIndex;
debuggerWindowGroup.SelectedWindow.OnEnter();
}
IDebuggerWindowGroup subDebuggerWindowGroup = debuggerWindowGroup.SelectedWindow as IDebuggerWindowGroup;
if (subDebuggerWindowGroup != null)
{
DrawDebuggerWindowGroup(subDebuggerWindowGroup);
}
debuggerWindowGroup.SelectedWindow.OnDraw();
}
private void DrawDebuggerWindowIcon(int windowId)
{
GUI.DragWindow(m_DragRect);
GUILayout.Space(5);
Color32 color = Color.white;
m_ConsoleWindow.RefreshCount();
if (m_ConsoleWindow.FatalCount > 0)
{
color = m_ConsoleWindow.GetLogStringColor(LogType.Exception);
}
else if (m_ConsoleWindow.ErrorCount > 0)
{
color = m_ConsoleWindow.GetLogStringColor(LogType.Error);
}
else if (m_ConsoleWindow.WarningCount > 0)
{
color = m_ConsoleWindow.GetLogStringColor(LogType.Warning);
}
else
{
color = m_ConsoleWindow.GetLogStringColor(LogType.Log);
}
string title = Utility.Text.Format("<color=#{0:x2}{1:x2}{2:x2}{3:x2}><b>FPS: {4:F2}</b></color>", color.r, color.g, color.b, color.a, m_FpsCounter.CurrentFps);
if (GUILayout.Button(title, GUILayout.Width(100f), GUILayout.Height(40f)))
{
m_ShowFullWindow = true;
}
}
private static void CopyToClipboard(string content)
{
s_TextEditor.text = content;
s_TextEditor.OnFocus();
s_TextEditor.Copy();
s_TextEditor.text = string.Empty;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d58978a9ed0f473ca3cc5a302c3bf87b
timeCreated: 1680489774

View File

@@ -0,0 +1,300 @@
using System.Collections.Generic;
namespace TEngine
{
internal sealed partial class DebuggerManager : GameFrameworkModule, IDebuggerManager
{
/// <summary>
/// 调试器窗口组。
/// </summary>
private sealed class DebuggerWindowGroup : IDebuggerWindowGroup
{
private readonly List<KeyValuePair<string, IDebuggerWindow>> m_DebuggerWindows;
private int m_SelectedIndex;
private string[] m_DebuggerWindowNames;
public DebuggerWindowGroup()
{
m_DebuggerWindows = new List<KeyValuePair<string, IDebuggerWindow>>();
m_SelectedIndex = 0;
m_DebuggerWindowNames = null;
}
/// <summary>
/// 获取调试器窗口数量。
/// </summary>
public int DebuggerWindowCount
{
get
{
return m_DebuggerWindows.Count;
}
}
/// <summary>
/// 获取或设置当前选中的调试器窗口索引。
/// </summary>
public int SelectedIndex
{
get
{
return m_SelectedIndex;
}
set
{
m_SelectedIndex = value;
}
}
/// <summary>
/// 获取当前选中的调试器窗口。
/// </summary>
public IDebuggerWindow SelectedWindow
{
get
{
if (m_SelectedIndex >= m_DebuggerWindows.Count)
{
return null;
}
return m_DebuggerWindows[m_SelectedIndex].Value;
}
}
/// <summary>
/// 初始化调试组。
/// </summary>
/// <param name="args">初始化调试组参数。</param>
public void Initialize(params object[] args)
{
}
/// <summary>
/// 关闭调试组。
/// </summary>
public void Shutdown()
{
foreach (KeyValuePair<string, IDebuggerWindow> debuggerWindow in m_DebuggerWindows)
{
debuggerWindow.Value.Shutdown();
}
m_DebuggerWindows.Clear();
}
/// <summary>
/// 进入调试器窗口。
/// </summary>
public void OnEnter()
{
SelectedWindow.OnEnter();
}
/// <summary>
/// 离开调试器窗口。
/// </summary>
public void OnLeave()
{
SelectedWindow.OnLeave();
}
/// <summary>
/// 调试组轮询。
/// </summary>
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
public void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
SelectedWindow.OnUpdate(elapseSeconds, realElapseSeconds);
}
/// <summary>
/// 调试器窗口绘制。
/// </summary>
public void OnDraw()
{
}
private void RefreshDebuggerWindowNames()
{
int index = 0;
m_DebuggerWindowNames = new string[m_DebuggerWindows.Count];
foreach (KeyValuePair<string, IDebuggerWindow> debuggerWindow in m_DebuggerWindows)
{
m_DebuggerWindowNames[index++] = debuggerWindow.Key;
}
}
/// <summary>
/// 获取调试组的调试器窗口名称集合。
/// </summary>
public string[] GetDebuggerWindowNames()
{
return m_DebuggerWindowNames;
}
/// <summary>
/// 获取调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <returns>要获取的调试器窗口。</returns>
public IDebuggerWindow GetDebuggerWindow(string path)
{
if (string.IsNullOrEmpty(path))
{
return null;
}
int pos = path.IndexOf('/');
if (pos < 0 || pos >= path.Length - 1)
{
return InternalGetDebuggerWindow(path);
}
string debuggerWindowGroupName = path.Substring(0, pos);
string leftPath = path.Substring(pos + 1);
DebuggerWindowGroup debuggerWindowGroup = (DebuggerWindowGroup)InternalGetDebuggerWindow(debuggerWindowGroupName);
if (debuggerWindowGroup == null)
{
return null;
}
return debuggerWindowGroup.GetDebuggerWindow(leftPath);
}
/// <summary>
/// 选中调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <returns>是否成功选中调试器窗口。</returns>
public bool SelectDebuggerWindow(string path)
{
if (string.IsNullOrEmpty(path))
{
return false;
}
int pos = path.IndexOf('/');
if (pos < 0 || pos >= path.Length - 1)
{
return InternalSelectDebuggerWindow(path);
}
string debuggerWindowGroupName = path.Substring(0, pos);
string leftPath = path.Substring(pos + 1);
DebuggerWindowGroup debuggerWindowGroup = (DebuggerWindowGroup)InternalGetDebuggerWindow(debuggerWindowGroupName);
if (debuggerWindowGroup == null || !InternalSelectDebuggerWindow(debuggerWindowGroupName))
{
return false;
}
return debuggerWindowGroup.SelectDebuggerWindow(leftPath);
}
/// <summary>
/// 注册调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <param name="debuggerWindow">要注册的调试器窗口。</param>
public void RegisterDebuggerWindow(string path, IDebuggerWindow debuggerWindow)
{
if (string.IsNullOrEmpty(path))
{
throw new GameFrameworkException("Path is invalid.");
}
int pos = path.IndexOf('/');
if (pos < 0 || pos >= path.Length - 1)
{
if (InternalGetDebuggerWindow(path) != null)
{
throw new GameFrameworkException("Debugger window has been registered.");
}
m_DebuggerWindows.Add(new KeyValuePair<string, IDebuggerWindow>(path, debuggerWindow));
RefreshDebuggerWindowNames();
}
else
{
string debuggerWindowGroupName = path.Substring(0, pos);
string leftPath = path.Substring(pos + 1);
DebuggerWindowGroup debuggerWindowGroup = (DebuggerWindowGroup)InternalGetDebuggerWindow(debuggerWindowGroupName);
if (debuggerWindowGroup == null)
{
if (InternalGetDebuggerWindow(debuggerWindowGroupName) != null)
{
throw new GameFrameworkException("Debugger window has been registered, can not create debugger window group.");
}
debuggerWindowGroup = new DebuggerWindowGroup();
m_DebuggerWindows.Add(new KeyValuePair<string, IDebuggerWindow>(debuggerWindowGroupName, debuggerWindowGroup));
RefreshDebuggerWindowNames();
}
debuggerWindowGroup.RegisterDebuggerWindow(leftPath, debuggerWindow);
}
}
/// <summary>
/// 解除注册调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <returns>是否解除注册调试器窗口成功。</returns>
public bool UnregisterDebuggerWindow(string path)
{
if (string.IsNullOrEmpty(path))
{
return false;
}
int pos = path.IndexOf('/');
if (pos < 0 || pos >= path.Length - 1)
{
IDebuggerWindow debuggerWindow = InternalGetDebuggerWindow(path);
bool result = m_DebuggerWindows.Remove(new KeyValuePair<string, IDebuggerWindow>(path, debuggerWindow));
debuggerWindow.Shutdown();
RefreshDebuggerWindowNames();
return result;
}
string debuggerWindowGroupName = path.Substring(0, pos);
string leftPath = path.Substring(pos + 1);
DebuggerWindowGroup debuggerWindowGroup = (DebuggerWindowGroup)InternalGetDebuggerWindow(debuggerWindowGroupName);
if (debuggerWindowGroup == null)
{
return false;
}
return debuggerWindowGroup.UnregisterDebuggerWindow(leftPath);
}
private IDebuggerWindow InternalGetDebuggerWindow(string name)
{
foreach (KeyValuePair<string, IDebuggerWindow> debuggerWindow in m_DebuggerWindows)
{
if (debuggerWindow.Key == name)
{
return debuggerWindow.Value;
}
}
return null;
}
private bool InternalSelectDebuggerWindow(string name)
{
for (int i = 0; i < m_DebuggerWindows.Count; i++)
{
if (m_DebuggerWindows[i].Key == name)
{
m_SelectedIndex = i;
return true;
}
}
return false;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d4a3c5214e924154ad543eae04e6cb7e
timeCreated: 1680489597

View File

@@ -0,0 +1,134 @@
namespace TEngine
{
/// <summary>
/// 调试器管理器。
/// </summary>
internal sealed partial class DebuggerManager : GameFrameworkModule, IDebuggerManager
{
private readonly DebuggerWindowGroup m_DebuggerWindowRoot;
private bool m_ActiveWindow;
/// <summary>
/// 初始化调试器管理器的新实例。
/// </summary>
public DebuggerManager()
{
m_DebuggerWindowRoot = new DebuggerWindowGroup();
m_ActiveWindow = false;
}
/// <summary>
/// 获取游戏框架模块优先级。
/// </summary>
/// <remarks>优先级较高的模块会优先轮询,并且关闭操作会后进行。</remarks>
internal override int Priority
{
get
{
return -1;
}
}
/// <summary>
/// 获取或设置调试器窗口是否激活。
/// </summary>
public bool ActiveWindow
{
get
{
return m_ActiveWindow;
}
set
{
m_ActiveWindow = value;
}
}
/// <summary>
/// 调试器窗口根结点。
/// </summary>
public IDebuggerWindowGroup DebuggerWindowRoot
{
get
{
return m_DebuggerWindowRoot;
}
}
/// <summary>
/// 调试器管理器轮询。
/// </summary>
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
internal override void Update(float elapseSeconds, float realElapseSeconds)
{
if (!m_ActiveWindow)
{
return;
}
m_DebuggerWindowRoot.OnUpdate(elapseSeconds, realElapseSeconds);
}
/// <summary>
/// 关闭并清理调试器管理器。
/// </summary>
internal override void Shutdown()
{
m_ActiveWindow = false;
m_DebuggerWindowRoot.Shutdown();
}
/// <summary>
/// 注册调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <param name="debuggerWindow">要注册的调试器窗口。</param>
/// <param name="args">初始化调试器窗口参数。</param>
public void RegisterDebuggerWindow(string path, IDebuggerWindow debuggerWindow, params object[] args)
{
if (string.IsNullOrEmpty(path))
{
throw new GameFrameworkException("Path is invalid.");
}
if (debuggerWindow == null)
{
throw new GameFrameworkException("Debugger window is invalid.");
}
m_DebuggerWindowRoot.RegisterDebuggerWindow(path, debuggerWindow);
debuggerWindow.Initialize(args);
}
/// <summary>
/// 解除注册调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <returns>是否解除注册调试器窗口成功。</returns>
public bool UnregisterDebuggerWindow(string path)
{
return m_DebuggerWindowRoot.UnregisterDebuggerWindow(path);
}
/// <summary>
/// 获取调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <returns>要获取的调试器窗口。</returns>
public IDebuggerWindow GetDebuggerWindow(string path)
{
return m_DebuggerWindowRoot.GetDebuggerWindow(path);
}
/// <summary>
/// 选中调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <returns>是否成功选中调试器窗口。</returns>
public bool SelectDebuggerWindow(string path)
{
return m_DebuggerWindowRoot.SelectDebuggerWindow(path);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9ac1ec4655aa4faba2d1a0ddd044712b
timeCreated: 1680489597

View File

@@ -0,0 +1,54 @@
namespace TEngine
{
/// <summary>
/// 调试器管理器接口。
/// </summary>
public interface IDebuggerManager
{
/// <summary>
/// 获取或设置调试器窗口是否激活。
/// </summary>
bool ActiveWindow
{
get;
set;
}
/// <summary>
/// 调试器窗口根结点。
/// </summary>
IDebuggerWindowGroup DebuggerWindowRoot
{
get;
}
/// <summary>
/// 注册调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <param name="debuggerWindow">要注册的调试器窗口。</param>
/// <param name="args">初始化调试器窗口参数。</param>
void RegisterDebuggerWindow(string path, IDebuggerWindow debuggerWindow, params object[] args);
/// <summary>
/// 解除注册调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <returns>是否解除注册调试器窗口成功。</returns>
bool UnregisterDebuggerWindow(string path);
/// <summary>
/// 获取调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <returns>要获取的调试器窗口。</returns>
IDebuggerWindow GetDebuggerWindow(string path);
/// <summary>
/// 选中调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <returns>是否成功选中调试器窗口。</returns>
bool SelectDebuggerWindow(string path);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d27aae441b2a4e299c230c968c76e839
timeCreated: 1680489597

View File

@@ -0,0 +1,41 @@
namespace TEngine
{
/// <summary>
/// 调试器窗口接口。
/// </summary>
public interface IDebuggerWindow
{
/// <summary>
/// 初始化调试器窗口。
/// </summary>
/// <param name="args">初始化调试器窗口参数。</param>
void Initialize(params object[] args);
/// <summary>
/// 关闭调试器窗口。
/// </summary>
void Shutdown();
/// <summary>
/// 进入调试器窗口。
/// </summary>
void OnEnter();
/// <summary>
/// 离开调试器窗口。
/// </summary>
void OnLeave();
/// <summary>
/// 调试器窗口轮询。
/// </summary>
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
void OnUpdate(float elapseSeconds, float realElapseSeconds);
/// <summary>
/// 调试器窗口绘制。
/// </summary>
void OnDraw();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 41aa48cd603d432d8dffd4edc72f188d
timeCreated: 1680489597

View File

@@ -0,0 +1,52 @@
namespace TEngine
{
/// <summary>
/// 调试器窗口组接口。
/// </summary>
public interface IDebuggerWindowGroup : IDebuggerWindow
{
/// <summary>
/// 获取调试器窗口数量。
/// </summary>
int DebuggerWindowCount
{
get;
}
/// <summary>
/// 获取或设置当前选中的调试器窗口索引。
/// </summary>
int SelectedIndex
{
get;
set;
}
/// <summary>
/// 获取当前选中的调试器窗口。
/// </summary>
IDebuggerWindow SelectedWindow
{
get;
}
/// <summary>
/// 获取调试组的调试器窗口名称集合。
/// </summary>
string[] GetDebuggerWindowNames();
/// <summary>
/// 获取调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <returns>要获取的调试器窗口。</returns>
IDebuggerWindow GetDebuggerWindow(string path);
/// <summary>
/// 注册调试器窗口。
/// </summary>
/// <param name="path">调试器窗口路径。</param>
/// <param name="debuggerWindow">要注册的调试器窗口。</param>
void RegisterDebuggerWindow(string path, IDebuggerWindow debuggerWindow);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2fff84d86dd44f16b3bb44dfa29081c6
timeCreated: 1680489597

View File

@@ -48,12 +48,12 @@ namespace TEngine
public static T GetModule<T>() where T : class
{
Type interfaceType = typeof(T);
// if (!interfaceType.IsInterface)
// {
// throw new GameFrameworkException(Utility.Text.Format("You must get module by interface, but '{0}' is not.", interfaceType.FullName));
// }
if (!interfaceType.IsInterface)
{
throw new GameFrameworkException(Utility.Text.Format("You must get module by interface, but '{0}' is not.", interfaceType.FullName));
}
if (!interfaceType.FullName.StartsWith("GameFramework.", StringComparison.Ordinal))
if (!interfaceType.FullName.StartsWith("TEngine.", StringComparison.Ordinal))
{
throw new GameFrameworkException(Utility.Text.Format("You must get a Game Framework module, but '{0}' is not.", interfaceType.FullName));
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8236a71bbd2a4ac4997bcb16ebff6f31
timeCreated: 1680501170

View File

@@ -0,0 +1,211 @@
using System;
namespace TEngine
{
/// <summary>
/// 对象池接口。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
public interface IObjectPool<T> where T : ObjectBase
{
/// <summary>
/// 获取对象池名称。
/// </summary>
string Name
{
get;
}
/// <summary>
/// 获取对象池完整名称。
/// </summary>
string FullName
{
get;
}
/// <summary>
/// 获取对象池对象类型。
/// </summary>
Type ObjectType
{
get;
}
/// <summary>
/// 获取对象池中对象的数量。
/// </summary>
int Count
{
get;
}
/// <summary>
/// 获取对象池中能被释放的对象的数量。
/// </summary>
int CanReleaseCount
{
get;
}
/// <summary>
/// 获取是否允许对象被多次获取。
/// </summary>
bool AllowMultiSpawn
{
get;
}
/// <summary>
/// 获取或设置对象池自动释放可释放对象的间隔秒数。
/// </summary>
float AutoReleaseInterval
{
get;
set;
}
/// <summary>
/// 获取或设置对象池的容量。
/// </summary>
int Capacity
{
get;
set;
}
/// <summary>
/// 获取或设置对象池对象过期秒数。
/// </summary>
float ExpireTime
{
get;
set;
}
/// <summary>
/// 获取或设置对象池的优先级。
/// </summary>
int Priority
{
get;
set;
}
/// <summary>
/// 创建对象。
/// </summary>
/// <param name="obj">对象。</param>
/// <param name="spawned">对象是否已被获取。</param>
void Register(T obj, bool spawned);
/// <summary>
/// 检查对象。
/// </summary>
/// <returns>要检查的对象是否存在。</returns>
bool CanSpawn();
/// <summary>
/// 检查对象。
/// </summary>
/// <param name="name">对象名称。</param>
/// <returns>要检查的对象是否存在。</returns>
bool CanSpawn(string name);
/// <summary>
/// 获取对象。
/// </summary>
/// <returns>要获取的对象。</returns>
T Spawn();
/// <summary>
/// 获取对象。
/// </summary>
/// <param name="name">对象名称。</param>
/// <returns>要获取的对象。</returns>
T Spawn(string name);
/// <summary>
/// 回收对象。
/// </summary>
/// <param name="obj">要回收的对象。</param>
void Unspawn(T obj);
/// <summary>
/// 回收对象。
/// </summary>
/// <param name="target">要回收的对象。</param>
void Unspawn(object target);
/// <summary>
/// 设置对象是否被加锁。
/// </summary>
/// <param name="obj">要设置被加锁的对象。</param>
/// <param name="locked">是否被加锁。</param>
void SetLocked(T obj, bool locked);
/// <summary>
/// 设置对象是否被加锁。
/// </summary>
/// <param name="target">要设置被加锁的对象。</param>
/// <param name="locked">是否被加锁。</param>
void SetLocked(object target, bool locked);
/// <summary>
/// 设置对象的优先级。
/// </summary>
/// <param name="obj">要设置优先级的对象。</param>
/// <param name="priority">优先级。</param>
void SetPriority(T obj, int priority);
/// <summary>
/// 设置对象的优先级。
/// </summary>
/// <param name="target">要设置优先级的对象。</param>
/// <param name="priority">优先级。</param>
void SetPriority(object target, int priority);
/// <summary>
/// 释放对象。
/// </summary>
/// <param name="obj">要释放的对象。</param>
/// <returns>释放对象是否成功。</returns>
bool ReleaseObject(T obj);
/// <summary>
/// 释放对象。
/// </summary>
/// <param name="target">要释放的对象。</param>
/// <returns>释放对象是否成功。</returns>
bool ReleaseObject(object target);
/// <summary>
/// 释放对象池中的可释放对象。
/// </summary>
void Release();
/// <summary>
/// 释放对象池中的可释放对象。
/// </summary>
/// <param name="toReleaseCount">尝试释放对象数量。</param>
void Release(int toReleaseCount);
/// <summary>
/// 释放对象池中的可释放对象。
/// </summary>
/// <param name="releaseObjectFilterCallback">释放对象筛选函数。</param>
void Release(ReleaseObjectFilterCallback<T> releaseObjectFilterCallback);
/// <summary>
/// 释放对象池中的可释放对象。
/// </summary>
/// <param name="toReleaseCount">尝试释放对象数量。</param>
/// <param name="releaseObjectFilterCallback">释放对象筛选函数。</param>
void Release(int toReleaseCount, ReleaseObjectFilterCallback<T> releaseObjectFilterCallback);
/// <summary>
/// 释放对象池中的所有未使用对象。
/// </summary>
void ReleaseAllUnused();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1582208c233e48f9b3707a8ebc230df7
timeCreated: 1680501171

View File

@@ -0,0 +1,744 @@
using System;
using System.Collections.Generic;
namespace TEngine
{
/// <summary>
/// 对象池管理器。
/// </summary>
public interface IObjectPoolManager
{
/// <summary>
/// 获取对象池数量。
/// </summary>
int Count
{
get;
}
/// <summary>
/// 检查是否存在对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <returns>是否存在对象池。</returns>
bool HasObjectPool<T>() where T : ObjectBase;
/// <summary>
/// 检查是否存在对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <returns>是否存在对象池。</returns>
bool HasObjectPool(Type objectType);
/// <summary>
/// 检查是否存在对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <returns>是否存在对象池。</returns>
bool HasObjectPool<T>(string name) where T : ObjectBase;
/// <summary>
/// 检查是否存在对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <returns>是否存在对象池。</returns>
bool HasObjectPool(Type objectType, string name);
/// <summary>
/// 检查是否存在对象池。
/// </summary>
/// <param name="condition">要检查的条件。</param>
/// <returns>是否存在对象池。</returns>
bool HasObjectPool(Predicate<ObjectPoolBase> condition);
/// <summary>
/// 获取对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <returns>要获取的对象池。</returns>
IObjectPool<T> GetObjectPool<T>() where T : ObjectBase;
/// <summary>
/// 获取对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <returns>要获取的对象池。</returns>
ObjectPoolBase GetObjectPool(Type objectType);
/// <summary>
/// 获取对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <returns>要获取的对象池。</returns>
IObjectPool<T> GetObjectPool<T>(string name) where T : ObjectBase;
/// <summary>
/// 获取对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <returns>要获取的对象池。</returns>
ObjectPoolBase GetObjectPool(Type objectType, string name);
/// <summary>
/// 获取对象池。
/// </summary>
/// <param name="condition">要检查的条件。</param>
/// <returns>要获取的对象池。</returns>
ObjectPoolBase GetObjectPool(Predicate<ObjectPoolBase> condition);
/// <summary>
/// 获取对象池。
/// </summary>
/// <param name="condition">要检查的条件。</param>
/// <returns>要获取的对象池。</returns>
ObjectPoolBase[] GetObjectPools(Predicate<ObjectPoolBase> condition);
/// <summary>
/// 获取对象池。
/// </summary>
/// <param name="condition">要检查的条件。</param>
/// <param name="results">要获取的对象池。</param>
void GetObjectPools(Predicate<ObjectPoolBase> condition, List<ObjectPoolBase> results);
/// <summary>
/// 获取所有对象池。
/// </summary>
/// <returns>所有对象池。</returns>
ObjectPoolBase[] GetAllObjectPools();
/// <summary>
/// 获取所有对象池。
/// </summary>
/// <param name="results">所有对象池。</param>
void GetAllObjectPools(List<ObjectPoolBase> results);
/// <summary>
/// 获取所有对象池。
/// </summary>
/// <param name="sort">是否根据对象池的优先级排序。</param>
/// <returns>所有对象池。</returns>
ObjectPoolBase[] GetAllObjectPools(bool sort);
/// <summary>
/// 获取所有对象池。
/// </summary>
/// <param name="sort">是否根据对象池的优先级排序。</param>
/// <param name="results">所有对象池。</param>
void GetAllObjectPools(bool sort, List<ObjectPoolBase> results);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>() where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name) where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="capacity">对象池的容量。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>(int capacity) where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="capacity">对象池的容量。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>(float expireTime) where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, float expireTime);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, int capacity) where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, float expireTime) where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float expireTime);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>(int capacity, float expireTime) where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, float expireTime);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="capacity">对象池的容量。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>(int capacity, int priority) where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, int priority);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>(float expireTime, int priority) where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, float expireTime, int priority);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, int capacity, float expireTime) where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, float expireTime);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, int capacity, int priority) where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, int priority);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, float expireTime, int priority) where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float expireTime, int priority);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>(int capacity, float expireTime, int priority) where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, int capacity, float expireTime, int priority);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, int capacity, float expireTime, int priority) where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, int capacity, float expireTime, int priority);
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <param name="autoReleaseInterval">对象池自动释放可释放对象的间隔秒数。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
IObjectPool<T> CreateSingleSpawnObjectPool<T>(string name, float autoReleaseInterval, int capacity, float expireTime, int priority) where T : ObjectBase;
/// <summary>
/// 创建允许单次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <param name="autoReleaseInterval">对象池自动释放可释放对象的间隔秒数。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许单次获取的对象池。</returns>
ObjectPoolBase CreateSingleSpawnObjectPool(Type objectType, string name, float autoReleaseInterval, int capacity, float expireTime, int priority);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>() where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name) where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="capacity">对象池的容量。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>(int capacity) where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="capacity">对象池的容量。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>(float expireTime) where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, float expireTime);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, int capacity) where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, float expireTime) where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float expireTime);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>(int capacity, float expireTime) where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, float expireTime);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="capacity">对象池的容量。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>(int capacity, int priority) where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, int priority);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>(float expireTime, int priority) where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, float expireTime, int priority);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, int capacity, float expireTime) where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, float expireTime);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, int capacity, int priority) where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, int priority);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, float expireTime, int priority) where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float expireTime, int priority);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>(int capacity, float expireTime, int priority) where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, int capacity, float expireTime, int priority);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, int capacity, float expireTime, int priority) where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, int capacity, float expireTime, int priority);
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">对象池名称。</param>
/// <param name="autoReleaseInterval">对象池自动释放可释放对象的间隔秒数。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
IObjectPool<T> CreateMultiSpawnObjectPool<T>(string name, float autoReleaseInterval, int capacity, float expireTime, int priority) where T : ObjectBase;
/// <summary>
/// 创建允许多次获取的对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">对象池名称。</param>
/// <param name="autoReleaseInterval">对象池自动释放可释放对象的间隔秒数。</param>
/// <param name="capacity">对象池的容量。</param>
/// <param name="expireTime">对象池对象过期秒数。</param>
/// <param name="priority">对象池的优先级。</param>
/// <returns>要创建的允许多次获取的对象池。</returns>
ObjectPoolBase CreateMultiSpawnObjectPool(Type objectType, string name, float autoReleaseInterval, int capacity, float expireTime, int priority);
/// <summary>
/// 销毁对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <returns>是否销毁对象池成功。</returns>
bool DestroyObjectPool<T>() where T : ObjectBase;
/// <summary>
/// 销毁对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <returns>是否销毁对象池成功。</returns>
bool DestroyObjectPool(Type objectType);
/// <summary>
/// 销毁对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="name">要销毁的对象池名称。</param>
/// <returns>是否销毁对象池成功。</returns>
bool DestroyObjectPool<T>(string name) where T : ObjectBase;
/// <summary>
/// 销毁对象池。
/// </summary>
/// <param name="objectType">对象类型。</param>
/// <param name="name">要销毁的对象池名称。</param>
/// <returns>是否销毁对象池成功。</returns>
bool DestroyObjectPool(Type objectType, string name);
/// <summary>
/// 销毁对象池。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="objectPool">要销毁的对象池。</param>
/// <returns>是否销毁对象池成功。</returns>
bool DestroyObjectPool<T>(IObjectPool<T> objectPool) where T : ObjectBase;
/// <summary>
/// 销毁对象池。
/// </summary>
/// <param name="objectPool">要销毁的对象池。</param>
/// <returns>是否销毁对象池成功。</returns>
bool DestroyObjectPool(ObjectPoolBase objectPool);
/// <summary>
/// 释放对象池中的可释放对象。
/// </summary>
void Release();
/// <summary>
/// 释放对象池中的所有未使用对象。
/// </summary>
void ReleaseAllUnused();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 669817740b024599b6f700ecc9fd0db8
timeCreated: 1680501171

View File

@@ -0,0 +1,200 @@
using System;
namespace TEngine
{
/// <summary>
/// 对象基类。
/// </summary>
public abstract class ObjectBase : IMemory
{
private string m_Name;
private object m_Target;
private bool m_Locked;
private int m_Priority;
private DateTime m_LastUseTime;
/// <summary>
/// 初始化对象基类的新实例。
/// </summary>
public ObjectBase()
{
m_Name = null;
m_Target = null;
m_Locked = false;
m_Priority = 0;
m_LastUseTime = default(DateTime);
}
/// <summary>
/// 获取对象名称。
/// </summary>
public string Name
{
get
{
return m_Name;
}
}
/// <summary>
/// 获取对象。
/// </summary>
public object Target
{
get
{
return m_Target;
}
}
/// <summary>
/// 获取或设置对象是否被加锁。
/// </summary>
public bool Locked
{
get
{
return m_Locked;
}
set
{
m_Locked = value;
}
}
/// <summary>
/// 获取或设置对象的优先级。
/// </summary>
public int Priority
{
get
{
return m_Priority;
}
set
{
m_Priority = value;
}
}
/// <summary>
/// 获取自定义释放检查标记。
/// </summary>
public virtual bool CustomCanReleaseFlag
{
get
{
return true;
}
}
/// <summary>
/// 获取对象上次使用时间。
/// </summary>
public DateTime LastUseTime
{
get
{
return m_LastUseTime;
}
internal set
{
m_LastUseTime = value;
}
}
/// <summary>
/// 初始化对象基类。
/// </summary>
/// <param name="target">对象。</param>
protected void Initialize(object target)
{
Initialize(null, target, false, 0);
}
/// <summary>
/// 初始化对象基类。
/// </summary>
/// <param name="name">对象名称。</param>
/// <param name="target">对象。</param>
protected void Initialize(string name, object target)
{
Initialize(name, target, false, 0);
}
/// <summary>
/// 初始化对象基类。
/// </summary>
/// <param name="name">对象名称。</param>
/// <param name="target">对象。</param>
/// <param name="locked">对象是否被加锁。</param>
protected void Initialize(string name, object target, bool locked)
{
Initialize(name, target, locked, 0);
}
/// <summary>
/// 初始化对象基类。
/// </summary>
/// <param name="name">对象名称。</param>
/// <param name="target">对象。</param>
/// <param name="priority">对象的优先级。</param>
protected void Initialize(string name, object target, int priority)
{
Initialize(name, target, false, priority);
}
/// <summary>
/// 初始化对象基类。
/// </summary>
/// <param name="name">对象名称。</param>
/// <param name="target">对象。</param>
/// <param name="locked">对象是否被加锁。</param>
/// <param name="priority">对象的优先级。</param>
protected void Initialize(string name, object target, bool locked, int priority)
{
if (target == null)
{
throw new GameFrameworkException(Utility.Text.Format("Target '{0}' is invalid.", name));
}
m_Name = name ?? string.Empty;
m_Target = target;
m_Locked = locked;
m_Priority = priority;
m_LastUseTime = DateTime.UtcNow;
}
/// <summary>
/// 清理对象基类。
/// </summary>
public virtual void Clear()
{
m_Name = null;
m_Target = null;
m_Locked = false;
m_Priority = 0;
m_LastUseTime = default(DateTime);
}
/// <summary>
/// 获取对象时的事件。
/// </summary>
protected internal virtual void OnSpawn()
{
}
/// <summary>
/// 回收对象时的事件。
/// </summary>
protected internal virtual void OnUnspawn()
{
}
/// <summary>
/// 释放对象。
/// </summary>
/// <param name="isShutdown">是否是关闭对象池时触发。</param>
protected internal abstract void Release(bool isShutdown);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 524a94dffe1f4918a09b5922fba3778b
timeCreated: 1680501171

View File

@@ -0,0 +1,115 @@
using System;
using System.Runtime.InteropServices;
namespace TEngine
{
/// <summary>
/// 对象信息。
/// </summary>
[StructLayout(LayoutKind.Auto)]
public struct ObjectInfo
{
private readonly string m_Name;
private readonly bool m_Locked;
private readonly bool m_CustomCanReleaseFlag;
private readonly int m_Priority;
private readonly DateTime m_LastUseTime;
private readonly int m_SpawnCount;
/// <summary>
/// 初始化对象信息的新实例。
/// </summary>
/// <param name="name">对象名称。</param>
/// <param name="locked">对象是否被加锁。</param>
/// <param name="customCanReleaseFlag">对象自定义释放检查标记。</param>
/// <param name="priority">对象的优先级。</param>
/// <param name="lastUseTime">对象上次使用时间。</param>
/// <param name="spawnCount">对象的获取计数。</param>
public ObjectInfo(string name, bool locked, bool customCanReleaseFlag, int priority, DateTime lastUseTime, int spawnCount)
{
m_Name = name;
m_Locked = locked;
m_CustomCanReleaseFlag = customCanReleaseFlag;
m_Priority = priority;
m_LastUseTime = lastUseTime;
m_SpawnCount = spawnCount;
}
/// <summary>
/// 获取对象名称。
/// </summary>
public string Name
{
get
{
return m_Name;
}
}
/// <summary>
/// 获取对象是否被加锁。
/// </summary>
public bool Locked
{
get
{
return m_Locked;
}
}
/// <summary>
/// 获取对象自定义释放检查标记。
/// </summary>
public bool CustomCanReleaseFlag
{
get
{
return m_CustomCanReleaseFlag;
}
}
/// <summary>
/// 获取对象的优先级。
/// </summary>
public int Priority
{
get
{
return m_Priority;
}
}
/// <summary>
/// 获取对象上次使用时间。
/// </summary>
public DateTime LastUseTime
{
get
{
return m_LastUseTime;
}
}
/// <summary>
/// 获取对象是否正在使用。
/// </summary>
public bool IsInUse
{
get
{
return m_SpawnCount > 0;
}
}
/// <summary>
/// 获取对象的获取计数。
/// </summary>
public int SpawnCount
{
get
{
return m_SpawnCount;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5269851c1924478e8f3150fc57f8d36f
timeCreated: 1680501171

View File

@@ -0,0 +1,145 @@
using System;
namespace TEngine
{
/// <summary>
/// 对象池基类。
/// </summary>
public abstract class ObjectPoolBase
{
private readonly string m_Name;
/// <summary>
/// 初始化对象池基类的新实例。
/// </summary>
public ObjectPoolBase()
: this(null)
{
}
/// <summary>
/// 初始化对象池基类的新实例。
/// </summary>
/// <param name="name">对象池名称。</param>
public ObjectPoolBase(string name)
{
m_Name = name ?? string.Empty;
}
/// <summary>
/// 获取对象池名称。
/// </summary>
public string Name
{
get
{
return m_Name;
}
}
/// <summary>
/// 获取对象池完整名称。
/// </summary>
public string FullName
{
get
{
return new TypeNamePair(ObjectType, m_Name).ToString();
}
}
/// <summary>
/// 获取对象池对象类型。
/// </summary>
public abstract Type ObjectType
{
get;
}
/// <summary>
/// 获取对象池中对象的数量。
/// </summary>
public abstract int Count
{
get;
}
/// <summary>
/// 获取对象池中能被释放的对象的数量。
/// </summary>
public abstract int CanReleaseCount
{
get;
}
/// <summary>
/// 获取是否允许对象被多次获取。
/// </summary>
public abstract bool AllowMultiSpawn
{
get;
}
/// <summary>
/// 获取或设置对象池自动释放可释放对象的间隔秒数。
/// </summary>
public abstract float AutoReleaseInterval
{
get;
set;
}
/// <summary>
/// 获取或设置对象池的容量。
/// </summary>
public abstract int Capacity
{
get;
set;
}
/// <summary>
/// 获取或设置对象池对象过期秒数。
/// </summary>
public abstract float ExpireTime
{
get;
set;
}
/// <summary>
/// 获取或设置对象池的优先级。
/// </summary>
public abstract int Priority
{
get;
set;
}
/// <summary>
/// 释放对象池中的可释放对象。
/// </summary>
public abstract void Release();
/// <summary>
/// 释放对象池中的可释放对象。
/// </summary>
/// <param name="toReleaseCount">尝试释放对象数量。</param>
public abstract void Release(int toReleaseCount);
/// <summary>
/// 释放对象池中的所有未使用对象。
/// </summary>
public abstract void ReleaseAllUnused();
/// <summary>
/// 获取所有对象信息。
/// </summary>
/// <returns>所有对象信息。</returns>
public abstract ObjectInfo[] GetAllObjectInfos();
internal abstract void Update(float elapseSeconds, float realElapseSeconds);
internal abstract void Shutdown();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f8ab28e091804ce3ba660e7948f37ca8
timeCreated: 1680501171

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More