A game about forced loneliness, made by TACStudios
1using System; 2using UnityEditor; 3using Unity.Collections; 4using Unity.Collections.LowLevel.Unsafe; 5using Unity.Jobs.LowLevel.Unsafe; 6using UnityEngine; 7 8// This menu is available from the editor directly on later versions 9#if !UNITY_2022_2_14F1_OR_NEWER 10class JobsMenu 11{ 12 private static int savedJobWorkerCount = JobsUtility.JobWorkerCount; 13 14 [SettingsProvider] 15 private static SettingsProvider JobsPreferencesItem() 16 { 17 var provider = new SettingsProvider("Preferences/Jobs", SettingsScope.User) 18 { 19 label = "Jobs", 20 keywords = new[]{"Jobs"}, 21 guiHandler = (searchContext) => 22 { 23 var originalWidth = EditorGUIUtility.labelWidth; 24 EditorGUIUtility.labelWidth = 200f; 25 EditorGUILayout.BeginVertical(); 26 27 GUILayout.BeginVertical(); 28 EditorGUILayout.LabelField("For safety, these values are reset on editor restart."); 29 30 bool madeChange = false; 31 32 bool oldWorkerCount = (JobsUtility.JobWorkerCount > 0); 33 bool newWorkerCount = EditorGUILayout.Toggle(new GUIContent("Use Job Threads:"), oldWorkerCount); 34 if (newWorkerCount != oldWorkerCount) 35 { 36 madeChange = true; 37 SwitchUseJobThreads(); 38 } 39 40 bool oldUseJobsDebugger = JobsUtility.JobDebuggerEnabled; 41 var newUseJobsDebugger = EditorGUILayout.Toggle(new GUIContent("Enable Jobs Debugger"), JobsUtility.JobDebuggerEnabled); 42 if (newUseJobsDebugger != oldUseJobsDebugger) 43 { 44 madeChange = true; 45 SetUseJobsDebugger(newUseJobsDebugger); 46 } 47 48 var oldLeakDetectionMode = NativeLeakDetection.Mode; 49 var newLeakDetectionMode = (NativeLeakDetectionMode) EditorGUILayout.EnumPopup(new GUIContent("Leak Detection Level"), oldLeakDetectionMode); 50 if (newLeakDetectionMode != oldLeakDetectionMode) 51 { 52 madeChange = true; 53 SetLeakDetection(newLeakDetectionMode); 54 } 55 56 if (madeChange) 57 Telemetry.LogMenuPreferences(new Telemetry.MenuPreferencesEvent { useJobsThreads = newUseJobsDebugger, enableJobsDebugger = newUseJobsDebugger, nativeLeakDetectionMode = newLeakDetectionMode }); 58 59 GUILayout.EndVertical(); 60 EditorGUILayout.EndVertical(); 61 62 EditorGUIUtility.labelWidth = originalWidth; 63 } 64 65 }; 66 67 return provider; 68 } 69 70 static void SwitchUseJobThreads() 71 { 72 if (JobsUtility.JobWorkerCount > 0) 73 { 74 savedJobWorkerCount = JobsUtility.JobWorkerCount; 75 JobsUtility.JobWorkerCount = 0; 76 } 77 else 78 { 79 JobsUtility.JobWorkerCount = savedJobWorkerCount; 80 if (savedJobWorkerCount == 0) 81 { 82 JobsUtility.ResetJobWorkerCount(); 83 } 84 } 85 } 86 87 static void SetUseJobsDebugger(bool value) 88 { 89 JobsUtility.JobDebuggerEnabled = value; 90 } 91 92 static void SetLeakDetection(NativeLeakDetectionMode value) 93 { 94 switch(value) 95 { 96 case NativeLeakDetectionMode.Disabled: 97 { 98 // In the case where someone enables, disables, then re-enables leak checking, we might miss some frees 99 // while disabled. So to avoid spurious leak warnings, just forgive the leaks every time someone disables 100 // leak checking through the menu. 101 UnsafeUtility.ForgiveLeaks(); 102 Debug.LogWarning("Leak detection has been disabled. Leak warnings will not be generated, and all leaks up to now are forgotten."); 103 break; 104 } 105 case NativeLeakDetectionMode.Enabled: 106 { 107 Debug.Log("Leak detection has been enabled. Leak warnings will be generated upon exiting play mode."); 108 break; 109 } 110 case NativeLeakDetectionMode.EnabledWithStackTrace: 111 { 112 Debug.Log("Leak detection with stack traces has been enabled. Leak warnings will be generated upon exiting play mode."); 113 break; 114 } 115 default: 116 { 117 throw new Exception($"Unhandled {nameof(NativeLeakDetectionMode)}"); 118 } 119 } 120 121 NativeLeakDetection.Mode = value; 122 } 123} 124#endif