diff --git a/Source/Editor/CustomEditors/Editors/InputEditor.cs b/Source/Editor/CustomEditors/Editors/InputEditor.cs index 416626e81..7b2682a84 100644 --- a/Source/Editor/CustomEditors/Editors/InputEditor.cs +++ b/Source/Editor/CustomEditors/Editors/InputEditor.cs @@ -1,8 +1,10 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using System.Collections.Generic; +using FlaxEditor.CustomEditors.GUI; +using FlaxEditor.GUI; +using FlaxEditor.GUI.ContextMenu; using FlaxEngine; -using FlaxEngine.GUI; namespace FlaxEditor.CustomEditors.Editors { @@ -12,7 +14,7 @@ namespace FlaxEditor.CustomEditors.Editors [CustomEditor(typeof(InputEvent)), DefaultEditor] public class InputEventEditor : CustomEditor { - private Dropdown _dropdown; + private ComboBox _comboBox; /// public override DisplayStyle Style => DisplayStyle.Inline; @@ -20,23 +22,30 @@ namespace FlaxEditor.CustomEditors.Editors /// public override void Initialize(LayoutElementsContainer layout) { - var dropdownElement = layout.Custom(); - _dropdown = dropdownElement.CustomControl; - var names = new List(); + LinkedLabel.SetupContextMenu += OnSetupContextMenu; + var comboBoxElement = layout.ComboBox(); + _comboBox = comboBoxElement.ComboBox; + var names = new List(); foreach (var mapping in Input.ActionMappings) { if (!names.Contains(mapping.Name)) names.Add(mapping.Name); } - _dropdown.Items = names; + _comboBox.Items = names; if (Values[0] is InputEvent inputEvent && names.Contains(inputEvent.Name)) - _dropdown.SelectedItem = inputEvent.Name; - _dropdown.SelectedIndexChanged += OnSelectedIndexChanged; + _comboBox.SelectedItem = inputEvent.Name; + _comboBox.SelectedIndexChanged += OnSelectedIndexChanged; } - private void OnSelectedIndexChanged(Dropdown dropdown) + private void OnSetupContextMenu(PropertyNameLabel label, ContextMenu menu, CustomEditor linkededitor) { - SetValue(new InputEvent(dropdown.SelectedItem)); + var button = menu.AddButton("Set to null"); + button.Clicked += () => _comboBox.SelectedItem = null; + } + + private void OnSelectedIndexChanged(ComboBox comboBox) + { + SetValue(comboBox.SelectedItem == null ? null : new InputEvent(comboBox.SelectedItem)); } /// @@ -49,17 +58,21 @@ namespace FlaxEditor.CustomEditors.Editors } else { - if (Values[0] is InputEvent inputEvent && _dropdown.Items.Contains(inputEvent.Name)) - _dropdown.SelectedItem = inputEvent.Name; + if (Values[0] is InputEvent inputEvent && _comboBox.Items.Contains(inputEvent.Name)) + _comboBox.SelectedItem = inputEvent.Name; + else + _comboBox.SelectedItem = null; } } /// protected override void Deinitialize() { - if (_dropdown != null) - _dropdown.SelectedIndexChanged -= OnSelectedIndexChanged; - _dropdown = null; + if (LinkedLabel != null) + LinkedLabel.SetupContextMenu -= OnSetupContextMenu; + if (_comboBox != null) + _comboBox.SelectedIndexChanged -= OnSelectedIndexChanged; + _comboBox = null; } } @@ -69,7 +82,7 @@ namespace FlaxEditor.CustomEditors.Editors [CustomEditor(typeof(InputAxis)), DefaultEditor] public class InputAxisEditor : CustomEditor { - private Dropdown _dropdown; + private ComboBox _comboBox; /// public override DisplayStyle Style => DisplayStyle.Inline; @@ -77,23 +90,30 @@ namespace FlaxEditor.CustomEditors.Editors /// public override void Initialize(LayoutElementsContainer layout) { - var dropdownElement = layout.Custom(); - _dropdown = dropdownElement.CustomControl; - var names = new List(); + LinkedLabel.SetupContextMenu += OnSetupContextMenu; + var comboBoxElement = layout.ComboBox(); + _comboBox = comboBoxElement.ComboBox; + var names = new List(); foreach (var mapping in Input.AxisMappings) { if (!names.Contains(mapping.Name)) names.Add(mapping.Name); } - _dropdown.Items = names; + _comboBox.Items = names; if (Values[0] is InputAxis inputAxis && names.Contains(inputAxis.Name)) - _dropdown.SelectedItem = inputAxis.Name; - _dropdown.SelectedIndexChanged += OnSelectedIndexChanged; + _comboBox.SelectedItem = inputAxis.Name; + _comboBox.SelectedIndexChanged += OnSelectedIndexChanged; } - private void OnSelectedIndexChanged(Dropdown dropdown) + private void OnSetupContextMenu(PropertyNameLabel label, ContextMenu menu, CustomEditor linkededitor) { - SetValue(new InputAxis(dropdown.SelectedItem)); + var button = menu.AddButton("Set to null"); + button.Clicked += () => _comboBox.SelectedItem = null; + } + + private void OnSelectedIndexChanged(ComboBox comboBox) + { + SetValue(comboBox.SelectedItem == null ? null : new InputAxis(comboBox.SelectedItem)); } /// @@ -106,17 +126,21 @@ namespace FlaxEditor.CustomEditors.Editors } else { - if (Values[0] is InputAxis inputAxis && _dropdown.Items.Contains(inputAxis.Name)) - _dropdown.SelectedItem = inputAxis.Name; + if (Values[0] is InputAxis inputAxis && _comboBox.Items.Contains(inputAxis.Name)) + _comboBox.SelectedItem = inputAxis.Name; + else + _comboBox.SelectedItem = null; } } /// protected override void Deinitialize() { - if (_dropdown != null) - _dropdown.SelectedIndexChanged -= OnSelectedIndexChanged; - _dropdown = null; + if (LinkedLabel != null) + LinkedLabel.SetupContextMenu -= OnSetupContextMenu; + if (_comboBox != null) + _comboBox.SelectedIndexChanged -= OnSelectedIndexChanged; + _comboBox = null; } } } diff --git a/Source/Engine/Engine/NativeInterop.Unmanaged.cs b/Source/Engine/Engine/NativeInterop.Unmanaged.cs index 423aae6a5..cfa71f97f 100644 --- a/Source/Engine/Engine/NativeInterop.Unmanaged.cs +++ b/Source/Engine/Engine/NativeInterop.Unmanaged.cs @@ -851,39 +851,46 @@ namespace FlaxEngine.Interop *assemblyFullName = NativeAllocStringAnsi(flaxEngineAssembly.FullName); return GetAssemblyHandle(flaxEngineAssembly); } + try + { + string assemblyPath = Marshal.PtrToStringUni(assemblyPathPtr); - string assemblyPath = Marshal.PtrToStringAnsi(assemblyPathPtr); - - Assembly assembly; + Assembly assembly; #if FLAX_EDITOR - // Load assembly from loaded bytes to prevent file locking in Editor - var assemblyBytes = File.ReadAllBytes(assemblyPath); - using MemoryStream stream = new MemoryStream(assemblyBytes); - var pdbPath = Path.ChangeExtension(assemblyPath, "pdb"); - if (File.Exists(pdbPath)) - { - // Load including debug symbols - using FileStream pdbStream = new FileStream(Path.ChangeExtension(assemblyPath, "pdb"), FileMode.Open); - assembly = scriptingAssemblyLoadContext.LoadFromStream(stream, pdbStream); - } - else - { - assembly = scriptingAssemblyLoadContext.LoadFromStream(stream); - } + // Load assembly from loaded bytes to prevent file locking in Editor + var assemblyBytes = File.ReadAllBytes(assemblyPath); + using MemoryStream stream = new MemoryStream(assemblyBytes); + var pdbPath = Path.ChangeExtension(assemblyPath, "pdb"); + if (File.Exists(pdbPath)) + { + // Load including debug symbols + using FileStream pdbStream = new FileStream(Path.ChangeExtension(assemblyPath, "pdb"), FileMode.Open); + assembly = scriptingAssemblyLoadContext.LoadFromStream(stream, pdbStream); + } + else + { + assembly = scriptingAssemblyLoadContext.LoadFromStream(stream); + } #else - // Load assembly from file - assembly = scriptingAssemblyLoadContext.LoadFromAssemblyPath(assemblyPath); + // Load assembly from file + assembly = scriptingAssemblyLoadContext.LoadFromAssemblyPath(assemblyPath); #endif - if (assembly == null) - return new ManagedHandle(); - NativeLibrary.SetDllImportResolver(assembly, NativeLibraryImportResolver); + if (assembly == null) + return new ManagedHandle(); + NativeLibrary.SetDllImportResolver(assembly, NativeLibraryImportResolver); - // Assemblies loaded via streams have no Location: https://github.com/dotnet/runtime/issues/12822 - AssemblyLocations.Add(assembly.FullName, assemblyPath); + // Assemblies loaded via streams have no Location: https://github.com/dotnet/runtime/issues/12822 + AssemblyLocations.Add(assembly.FullName, assemblyPath); - *assemblyName = NativeAllocStringAnsi(assembly.GetName().Name); - *assemblyFullName = NativeAllocStringAnsi(assembly.FullName); - return GetAssemblyHandle(assembly); + *assemblyName = NativeAllocStringAnsi(assembly.GetName().Name); + *assemblyFullName = NativeAllocStringAnsi(assembly.FullName); + return GetAssemblyHandle(assembly); + } + catch (Exception ex) + { + Debug.LogException(ex); + } + return new ManagedHandle(); } [UnmanagedCallersOnly] diff --git a/Source/Engine/Scripting/Runtime/DotNet.cpp b/Source/Engine/Scripting/Runtime/DotNet.cpp index c859fa961..4a84fca0a 100644 --- a/Source/Engine/Scripting/Runtime/DotNet.cpp +++ b/Source/Engine/Scripting/Runtime/DotNet.cpp @@ -703,13 +703,10 @@ bool MAssembly::LoadImage(const String& assemblyPath, const StringView& nativePa { // TODO: Use new hostfxr delegate load_assembly_bytes? (.NET 8+) // Open .Net assembly - const StringAnsi assemblyPathAnsi = assemblyPath.ToStringAnsi(); - const char* name; - const char* fullname; + const char* name = nullptr; + const char* fullname = nullptr; static void* LoadAssemblyImagePtr = GetStaticMethodPointer(TEXT("LoadAssemblyImage")); - _handle = CallStaticMethod(LoadAssemblyImagePtr, assemblyPathAnsi.Get(), &name, &fullname); - _name = name; - _fullname = fullname; + _handle = CallStaticMethod(LoadAssemblyImagePtr, assemblyPath.Get(), &name, &fullname); MCore::GC::FreeMemory((void*)name); MCore::GC::FreeMemory((void*)fullname); if (_handle == nullptr) @@ -717,6 +714,8 @@ bool MAssembly::LoadImage(const String& assemblyPath, const StringView& nativePa Log::CLRInnerException(TEXT(".NET assembly image is invalid at ") + assemblyPath); return true; } + _name = name; + _fullname = fullname; CachedAssemblyHandles.Add(_handle, this); // Provide new path of hot-reloaded native library path for managed DllImport