using System; using System.Collections.Generic; using MLAPI.Profiling; using Unity.Profiling; using UnityEditor; using UnityEngine; namespace MLAPI { [InitializeOnLoad] internal static class MLAPIProfilerModule { #if UNITY_2020_2_OR_NEWER && ENABLE_PROFILER private const string k_RpcModuleName = "MLAPI RPCs"; private const string k_OperationModuleName = "MLAPI Operations"; private const string k_MessageModuleName = "MLAPI Messages"; /// /// This needs to be in synced with the internal dynamic module structure to provide our own counters /// [Serializable] private class MLAPIProfilerCounter { // Note: These fields are named this way for internal serialization public string m_Name; public string m_Category; } /// /// This needs to be in synced with the internal dynamic module structure to provide our own counters /// [Serializable] private class MLAPIProfilerModuleData { // Note: These fields are named this way for internal serialization public List m_ChartCounters = new List(); public List m_DetailCounters = new List(); public string m_Name; } [Serializable] private class MLAPIModules { // Note: These fields are named this way for internal serialization public List m_Modules; } private static List CreateRPCCounters() => new List() { new MLAPIProfilerCounter { m_Name = ProfilerConstants.RpcSent, m_Category = ProfilerCategory.Network.Name }, new MLAPIProfilerCounter { m_Name = ProfilerConstants.RpcReceived, m_Category = ProfilerCategory.Network.Name }, new MLAPIProfilerCounter { m_Name = ProfilerConstants.RpcBatchesSent, m_Category = ProfilerCategory.Network.Name }, new MLAPIProfilerCounter { m_Name = ProfilerConstants.RpcBatchesReceived, m_Category = ProfilerCategory.Network.Name }, new MLAPIProfilerCounter { m_Name = ProfilerConstants.RpcQueueProcessed, m_Category = ProfilerCategory.Network.Name }, new MLAPIProfilerCounter { m_Name = ProfilerConstants.RpcInQueueSize, m_Category = ProfilerCategory.Network.Name }, new MLAPIProfilerCounter { m_Name = ProfilerConstants.RpcOutQueueSize, m_Category = ProfilerCategory.Network.Name }, }; private static List CreateOperationsCounters() => new List() { new MLAPIProfilerCounter { m_Name = ProfilerConstants.Connections, m_Category = ProfilerCategory.Network.Name }, new MLAPIProfilerCounter { m_Name = ProfilerConstants.ReceiveTickRate, m_Category = ProfilerCategory.Network.Name }, }; private static List CreateMessagesCounters() => new List() { new MLAPIProfilerCounter { m_Name = ProfilerConstants.NamedMessageReceived, m_Category = ProfilerCategory.Network.Name }, new MLAPIProfilerCounter { m_Name = ProfilerConstants.UnnamedMessageReceived, m_Category = ProfilerCategory.Network.Name }, new MLAPIProfilerCounter { m_Name = ProfilerConstants.NamedMessageSent, m_Category = ProfilerCategory.Network.Name }, new MLAPIProfilerCounter { m_Name = ProfilerConstants.UnnamedMessageSent, m_Category = ProfilerCategory.Network.Name }, new MLAPIProfilerCounter { m_Name = ProfilerConstants.ByteSent, m_Category = ProfilerCategory.Network.Name }, new MLAPIProfilerCounter { m_Name = ProfilerConstants.ByteReceived, m_Category = ProfilerCategory.Network.Name }, new MLAPIProfilerCounter { m_Name = ProfilerConstants.NetworkVarUpdates, m_Category = ProfilerCategory.Network.Name }, new MLAPIProfilerCounter { m_Name = ProfilerConstants.NetworkVarDeltas, m_Category = ProfilerCategory.Network.Name }, }; private delegate List CounterListFactoryDelegate(); private static bool CreateMLAPIDynamicModule(ref MLAPIModules mlapiModules, string moduleName, CounterListFactoryDelegate counterListFactoryDelegate) { var module = mlapiModules.m_Modules.Find(x => x.m_Name == moduleName); if (module == null) { var newModule = new MLAPIProfilerModuleData { m_Name = moduleName, m_ChartCounters = counterListFactoryDelegate(), m_DetailCounters = counterListFactoryDelegate(), }; mlapiModules.m_Modules.Add(newModule); return true; } return false; } #endif static MLAPIProfilerModule() { #if UNITY_2020_2_OR_NEWER && ENABLE_PROFILER var dynamicModulesJson = EditorPrefs.GetString("ProfilerWindow.DynamicModules"); var dynamicModules = JsonUtility.FromJson(dynamicModulesJson); if (dynamicModules != null) { bool wasCreated = CreateMLAPIDynamicModule(ref dynamicModules, k_RpcModuleName, CreateRPCCounters); wasCreated |= CreateMLAPIDynamicModule(ref dynamicModules, k_OperationModuleName, CreateOperationsCounters); wasCreated |= CreateMLAPIDynamicModule(ref dynamicModules, k_MessageModuleName, CreateMessagesCounters); if (wasCreated) { EditorPrefs.SetString("ProfilerWindow.DynamicModules", JsonUtility.ToJson(dynamicModules)); } } #endif } } }