public void OnEnable() { if (_treeView == null) { _treeView = new BurstMethodTreeView(new TreeViewState()); } _safetyChecks = BurstCompiler.Options.EnableBurstSafetyChecks; var assemblyList = BurstReflection.GetAssemblyList(AssembliesType.Editor, onlyAssembliesThatPossiblyContainJobs: true); Task.Run( () => { // Do this stuff asynchronously. var result = BurstReflection.FindExecuteMethods(assemblyList); _targets = result.CompileTargets; _targets.Sort((left, right) => string.Compare(left.GetDisplayName(), right.GetDisplayName(), StringComparison.Ordinal)); return(result); }) .ContinueWith(t => { // Do this stuff on the main (UI) thread. if (t.Status == TaskStatus.RanToCompletion) { foreach (var logMessage in t.Result.LogMessages) { switch (logMessage.LogType) { case BurstReflection.LogType.Warning: Debug.LogWarning(logMessage.Message); break; case BurstReflection.LogType.Exception: Debug.LogException(logMessage.Exception); break; default: throw new InvalidOperationException(); } } _treeView.Targets = _targets; _treeView.Reload(); if (_selectedItem != null) { _treeView.TrySelectByDisplayName(_selectedItem); } _requiresRepaint = true; _initialized = true; } else if (t.Exception != null) { Debug.LogError($"Could not load Inspector: {t.Exception}"); } }); }
public void OnGUI() { // Make sure that editor options are synchronized BurstEditorOptions.EnsureSynchronized(); if (_targets == null) { _targets = BurstReflection.FindExecuteMethods(AssembliesType.Editor); foreach (var target in _targets) { // Enable burst compilation by default (override globals for the inspector) // This is not working as expected. This changes indirectly the global options while it shouldn't // Unable to explain how it can happen // so for now, if global enable burst compilation is disabled, then inspector is too //target.Options.EnableBurstCompilation = true; } // Order targets per name _targets.Sort((left, right) => string.Compare(left.GetDisplayName(), right.GetDisplayName(), StringComparison.Ordinal)); _treeView.Targets = _targets; _treeView.Reload(); if (_selectedItem != null) { _treeView.TrySelectByDisplayName(_selectedItem); } } if (_fontSizesText == null) { _fontSizesText = new string[FontSizes.Length]; for (var i = 0; i < FontSizes.Length; ++i) { _fontSizesText[i] = FontSizes[i].ToString(); } } if (_fontSizeIndex == -1) { _fontSizeIndex = EditorPrefs.GetInt(FontSizeIndexPref, 5); _fontSizeIndex = Math.Max(0, _fontSizeIndex); _fontSizeIndex = Math.Min(_fontSizeIndex, FontSizes.Length - 1); } if (_fixedFontStyle == null) { _fixedFontStyle = new GUIStyle(GUI.skin.label); string fontName; if (Application.platform == RuntimePlatform.WindowsEditor) { fontName = "Consolas"; } else { fontName = "Courier"; } CleanupFont(); _font = Font.CreateDynamicFontFromOSFont(fontName, FontSize); _fixedFontStyle.font = _font; _fixedFontStyle.fontSize = FontSize; } if (_searchField == null) { _searchField = new SearchField(); } if (_textArea == null) { _textArea = new LongTextArea(); } GUILayout.BeginHorizontal(); GUILayout.BeginVertical(GUILayout.Width(position.width / 3)); GUILayout.Label("Compile Targets", EditorStyles.boldLabel); var newFilter = _searchField.OnGUI(_treeView.Filter); if (newFilter != _treeView.Filter) { _treeView.Filter = newFilter; _treeView.Reload(); } _treeView.OnGUI(GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true))); GUILayout.EndVertical(); GUILayout.BeginVertical(); var selection = _treeView.GetSelection(); if (selection.Count == 1) { var id = selection[0]; var target = _targets[id - 1]; // Stash selected item name to handle domain reloads more gracefully _selectedItem = target.GetDisplayName(); bool doRefresh = false; bool doCopy = false; int fsi = _fontSizeIndex; RenderButtonBars((position.width * 2) / 3, target, out doRefresh, out doCopy, out fsi); var disasm = target.Disassembly != null ? target.Disassembly[(int)_disasmKind] : null; var methodOptions = target.Options.Clone(); if (doRefresh) { // TODO: refactor this code with a proper AppendOption to avoid these "\n" var options = new StringBuilder(); methodOptions.EnableBurstSafetyChecks = _safetyChecks; methodOptions.EnableEnhancedAssembly = _enhancedDisassembly; methodOptions.DisableOptimizations = !_optimizations; methodOptions.EnableFastMath = _fastMath; // force synchronouze compilation for the inspector methodOptions.EnableBurstCompileSynchronously = true; string defaultOptions; bool debug; // We still show disassembly even if method has [BurstCompile(Debug = true)] if (methodOptions.TryGetOptions(target.IsStaticMethod ? (MemberInfo)target.Method : target.JobType, true, out defaultOptions, out debug)) { options.Append(defaultOptions); options.AppendFormat("\n" + BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionTarget, CodeGenOptions[_codeGenOptions])); var baseOptions = options.ToString().Trim('\n', ' '); target.Disassembly = new string[DisasmOptions.Length]; for (var i = 0; i < DisasmOptions.Length; ++i) { target.Disassembly[i] = GetDisassembly(target.Method, baseOptions + DisasmOptions[i]); } if (_enhancedDisassembly && (int)DisassemblyKind.Asm < target.Disassembly.Length) { var processor = new BurstDisassembler(); target.Disassembly[(int)DisassemblyKind.Asm] = processor.Process(target.Disassembly[(int)DisassemblyKind.Asm]); } disasm = target.Disassembly[(int)_disasmKind]; } } if (disasm != null) { _textArea.Text = disasm; _scrollPos = GUILayout.BeginScrollView(_scrollPos); _textArea.Render(_fixedFontStyle); GUILayout.EndScrollView(); } if (doCopy) { EditorGUIUtility.systemCopyBuffer = disasm == null ? "" : disasm; } if (fsi != _fontSizeIndex) { _fontSizeIndex = fsi; EditorPrefs.SetInt(FontSizeIndexPref, fsi); _fixedFontStyle = null; } } GUILayout.EndVertical(); GUILayout.EndHorizontal(); }
public void OnGUI() { if (_targets == null) { _targets = BurstReflection.FindExecuteMethods(AssembliesType.Editor); _treeView.Targets = _targets; _treeView.Reload(); if (_selectedItem != null) { _treeView.TrySelectByDisplayName(_selectedItem); } } if (_fontSizesText == null) { _fontSizesText = new string[FontSizes.Length]; for (var i = 0; i < FontSizes.Length; ++i) { _fontSizesText[i] = FontSizes[i].ToString(); } } if (_fontSizeIndex == -1) { _fontSizeIndex = EditorPrefs.GetInt(FontSizeIndexPref, 5); _fontSizeIndex = Math.Max(0, _fontSizeIndex); _fontSizeIndex = Math.Min(_fontSizeIndex, FontSizes.Length - 1); } if (_fixedFontStyle == null) { _fixedFontStyle = new GUIStyle(GUI.skin.label); string fontName; if (Application.platform == RuntimePlatform.WindowsEditor) { fontName = "Consolas"; } else { fontName = "Courier"; } _fixedFontStyle.font = Font.CreateDynamicFontFromOSFont(fontName, FontSize); } if (_searchField == null) { _searchField = new SearchField(); } if (_textArea == null) { _textArea = new LongTextArea(); } GUILayout.BeginHorizontal(); GUILayout.BeginVertical(GUILayout.Width(position.width / 3)); GUILayout.Label("Compile Targets", EditorStyles.boldLabel); var newFilter = _searchField.OnGUI(_treeView.Filter); if (newFilter != _treeView.Filter) { _treeView.Filter = newFilter; _treeView.Reload(); } _treeView.OnGUI(GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true))); GUILayout.EndVertical(); GUILayout.BeginVertical(); var selection = _treeView.GetSelection(); if (selection.Count == 1) { var id = selection[0]; var target = _targets[id - 1]; // Stash selected item name to handle domain reloads more gracefully _selectedItem = target.GetDisplayName(); GUILayout.BeginHorizontal(); _enhancedDisassembly = GUILayout.Toggle(_enhancedDisassembly, "Enhanced Disassembly"); _safetyChecks = GUILayout.Toggle(_safetyChecks, "Safety Checks"); _optimizations = GUILayout.Toggle(_optimizations, "Optimizations"); _fastMath = GUILayout.Toggle(_fastMath, "Fast Math"); EditorGUI.BeginDisabledGroup(!target.SupportsBurst); _codeGenOptions = EditorGUILayout.Popup(_codeGenOptions, CodeGenOptions); GUILayout.Label("Font Size"); var fsi = EditorGUILayout.Popup(_fontSizeIndex, _fontSizesText); var doRefresh = GUILayout.Button("Refresh Disassembly"); var doCopy = GUILayout.Button("Copy to Clipboard"); EditorGUI.EndDisabledGroup(); GUILayout.EndHorizontal(); _disasmKind = (DisassemblyKind)GUILayout.Toolbar((int)_disasmKind, DisassemblyKindNames); var disasm = target.Disassembly != null ? target.Disassembly[(int)_disasmKind] : null; if (doRefresh) { // TODO: refactor this code with a proper AppendOption to avoid these "\n" var options = new StringBuilder(); if (!_safetyChecks) { options.Append("\n" + GetOption(OptionDisableSafetyChecks) + "\n" + GetOption(OptionNoAlias)); } if (_enhancedDisassembly) { options.Append("\n" + GetOption(OptionDebug)); } if (!_optimizations) { options.Append("\n" + GetOption(OptionDisableOpt)); } if (_fastMath) { options.Append("\n" + GetOption(OptionFastMath)); } options.AppendFormat("\n" + GetOption(OptionTarget, CodeGenOptions[_codeGenOptions])); var baseOptions = options.ToString().Trim('\n', ' '); target.Disassembly = new string[DisasmOptions.Length]; for (var i = 0; i < DisasmOptions.Length; ++i) { target.Disassembly[i] = GetDisassembly(target.Method, baseOptions + DisasmOptions[i]); } if (_enhancedDisassembly && (int)DisassemblyKind.Asm < target.Disassembly.Length) { var processor = new BurstDisassembler(); target.Disassembly[(int)DisassemblyKind.Asm] = processor.Process(target.Disassembly[(int)DisassemblyKind.Asm]); } disasm = target.Disassembly[(int)_disasmKind]; } if (disasm != null) { _textArea.Text = disasm; _scrollPos = GUILayout.BeginScrollView(_scrollPos); _textArea.Render(_fixedFontStyle); GUILayout.EndScrollView(); } if (doCopy) { EditorGUIUtility.systemCopyBuffer = disasm == null ? "" : disasm; } if (fsi != _fontSizeIndex) { _fontSizeIndex = fsi; EditorPrefs.SetInt(FontSizeIndexPref, fsi); _fixedFontStyle = null; } } GUILayout.EndVertical(); GUILayout.EndHorizontal(); }
public void OnGUI() { // Make sure that editor options are synchronized BurstEditorOptions.EnsureSynchronized(); if (_targets == null) { _targets = BurstReflection.FindExecuteMethods(AssembliesType.Editor); foreach (var target in _targets) { // Enable burst compilation by default (override globals for the inspector) // This is not working as expected. This changes indirectly the global options while it shouldn't // Unable to explain how it can happen // so for now, if global enable burst compilation is disabled, then inspector is too //target.Options.EnableBurstCompilation = true; } // Order targets per name _targets.Sort((left, right) => string.Compare(left.GetDisplayName(), right.GetDisplayName(), StringComparison.Ordinal)); _treeView.Targets = _targets; _treeView.Reload(); if (_selectedItem != null) { _treeView.TrySelectByDisplayName(_selectedItem); } } if (_fontSizesText == null) { _fontSizesText = new string[FontSizes.Length]; for (var i = 0; i < FontSizes.Length; ++i) { _fontSizesText[i] = FontSizes[i].ToString(); } } if (_fontSizeIndex == -1) { _fontSizeIndex = EditorPrefs.GetInt(FontSizeIndexPref, 5); _fontSizeIndex = Math.Max(0, _fontSizeIndex); _fontSizeIndex = Math.Min(_fontSizeIndex, FontSizes.Length - 1); } if (_fixedFontStyle == null) { _fixedFontStyle = new GUIStyle(GUI.skin.label); string fontName; if (Application.platform == RuntimePlatform.WindowsEditor) { fontName = "Consolas"; } else { fontName = "Courier"; } CleanupFont(); _font = Font.CreateDynamicFontFromOSFont(fontName, FontSize); _fixedFontStyle.font = _font; _fixedFontStyle.fontSize = FontSize; } if (_searchField == null) { _searchField = new SearchField(); } if (_textArea == null) { _textArea = new LongTextArea(); } GUILayout.BeginHorizontal(); // SplitterGUILayout.BeginHorizontalSplit is internal in Unity but we don't have much choice SplitterGUILayout.BeginHorizontalSplit(TreeViewSplitterState); GUILayout.BeginVertical(GUILayout.Width(position.width / 3)); GUILayout.Label("Compile Targets", EditorStyles.boldLabel); var newFilter = _searchField.OnGUI(_treeView.Filter); if (newFilter != _treeView.Filter) { _treeView.Filter = newFilter; _treeView.Reload(); } _treeView.OnGUI(GUILayoutUtility.GetRect(GUIContent.none, GUIStyle.none, GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true))); GUILayout.EndVertical(); GUILayout.BeginVertical(); var selection = _treeView.GetSelection(); if (selection.Count == 1) { var targetIndex = selection[0]; var target = _targets[targetIndex - 1]; var targetOptions = target.Options; // Stash selected item name to handle domain reloads more gracefully _selectedItem = target.GetDisplayName(); // Refresh if any options are changed bool doCopy; int fontSize; // -14 to add a little bit of space for the vertical scrollbar to display correctly RenderButtonBars((position.width * 2) / 3 - 14, target, out doCopy, out fontSize); // We are currently formatting only Asm output var isTextFormatted = _enhancedDisassembly && _disasmKind == DisassemblyKind.Asm; // Depending if we are formatted or not, we don't render the same text var textToRender = isTextFormatted ? target.FormattedDisassembly : target.RawDisassembly; // Only refresh if we are switching to a new selection that hasn't been disassembled yet // Or we are changing disassembly settings (safety checks / enhanced disassembly) var targetRefresh = textToRender == null || target.DisassemblyKind != _disasmKind || targetOptions.EnableBurstSafetyChecks != _safetyChecks || target.TargetCpu != _targetCpu || target.IsDarkMode != EditorGUIUtility.isProSkin; bool targetChanged = _previousTargetIndex != targetIndex; _previousTargetIndex = targetIndex; if (targetRefresh) { // TODO: refactor this code with a proper AppendOption to avoid these "\n" var options = new StringBuilder(); target.TargetCpu = _targetCpu; target.DisassemblyKind = _disasmKind; targetOptions.EnableBurstSafetyChecks = _safetyChecks; target.IsDarkMode = EditorGUIUtility.isProSkin; targetOptions.EnableBurstCompileSynchronously = true; string defaultOptions; if (targetOptions.TryGetOptions(target.IsStaticMethod ? (MemberInfo)target.Method : target.JobType, true, out defaultOptions)) { options.Append(defaultOptions); options.AppendFormat("\n" + BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionTarget, TargetCpuNames[(int)_targetCpu])); options.AppendFormat("\n" + BurstCompilerOptions.GetOption(BurstCompilerOptions.OptionDebug)); var baseOptions = options.ToString().Trim('\n', ' '); target.RawDisassembly = GetDisassembly(target.Method, baseOptions + DisasmOptions[(int)_disasmKind]); if (isTextFormatted) { // Store the formatted version target.FormattedDisassembly = _burstDisassembler.Process(target.RawDisassembly, IsIntel(_targetCpu) ? BurstDisassembler.AsmKind.Intel : BurstDisassembler.AsmKind.ARM, target.IsDarkMode); textToRender = target.FormattedDisassembly; } else { target.FormattedDisassembly = null; textToRender = target.RawDisassembly; } } } if (textToRender != null) { _textArea.Text = textToRender; if (targetChanged) { _scrollPos = Vector2.zero; } _scrollPos = GUILayout.BeginScrollView(_scrollPos, true, true); _textArea.Render(_fixedFontStyle); GUILayout.EndScrollView(); } if (doCopy) { // When copying to the clipboard, we copy the non-formatted version EditorGUIUtility.systemCopyBuffer = target.RawDisassembly ?? string.Empty; } if (fontSize != _fontSizeIndex) { _fontSizeIndex = fontSize; EditorPrefs.SetInt(FontSizeIndexPref, fontSize); _fixedFontStyle = null; } } GUILayout.EndVertical(); SplitterGUILayout.EndHorizontalSplit(); GUILayout.EndHorizontal(); }