diff --git a/Prowl.Editor/Assets/AssetDatabase.Core.cs b/Prowl.Editor/Assets/AssetDatabase.Core.cs index 1cca34a7..ef83566b 100644 --- a/Prowl.Editor/Assets/AssetDatabase.Core.cs +++ b/Prowl.Editor/Assets/AssetDatabase.Core.cs @@ -80,6 +80,7 @@ public static AssetDirectoryCache GetRootFolderCache(int index) public static void AddRootFolder(string rootFolder) { ArgumentException.ThrowIfNullOrEmpty(rootFolder); + ArgumentNullException.ThrowIfNull(Project.Active); var rootPath = Path.Combine(Project.Active.ProjectPath, rootFolder); var info = new DirectoryInfo(rootPath); @@ -139,7 +140,7 @@ public static void Update(bool doUnload = true, bool forceCacheUpdate = false) if (ProcessFile(file, out _)) toReimport.Add(file); } - else if (!assetPathToMeta.TryGetValue(file, out var meta)) + else if (!assetPathToMeta.TryGetValue(file, out _)) { // File hasent changed but we dont have it in the cache, process it but dont reimport Debug.Log("Asset Found: " + file); @@ -168,7 +169,7 @@ public static void Update(bool doUnload = true, bool forceCacheUpdate = false) cacheModified = true; bool hasMeta = assetPathToMeta.TryGetValue(file, out var meta); - if (hasMeta) + if (hasMeta && meta is not null) { assetPathToMeta.Remove(file); @@ -248,7 +249,7 @@ static bool ProcessFile(string file, out bool metaOutdated) { // No meta file, create and import var newMeta = new MetaFile(fileInfo); - if (newMeta.importer == null) + if (newMeta.Importer == null) { Debug.LogError($"No importer found for file:\n{fileInfo.FullName}"); return false; @@ -351,17 +352,18 @@ public static bool Reimport(FileInfo assetFile, bool disposeExisting = true) Debug.LogError($"No valid meta file found for asset: {ToRelativePath(assetFile)}"); return false; } - if (meta.importer == null) - { - Debug.LogError($"No valid importer found for asset: {ToRelativePath(assetFile)}"); - return false; - } + // TODO: FIXME: its always not null + // if (meta.Importer == null) + // { + // Debug.LogError($"No valid importer found for asset: {ToRelativePath(assetFile)}"); + // return false; + // } // Import the asset SerializedAsset ctx = new(meta.guid); try { - meta.importer.Import(ctx, assetFile); + meta.Importer.Import(ctx, assetFile); } catch (Exception e) { @@ -494,8 +496,11 @@ public static bool Reimport(FileInfo assetFile, bool disposeExisting = true) { var serializedAsset = SerializedAsset.FromSerializedAsset(serializedAssetPath.FullName); serializedAsset.Guid = assetGuid; - serializedAsset.Main.AssetID = assetGuid; - serializedAsset.Main.FileID = 0; + if (serializedAsset.Main is not null) + { + serializedAsset.Main.AssetID = assetGuid; + serializedAsset.Main.FileID = 0; + } for (int i = 0; i < serializedAsset.SubAssets.Count; i++) { serializedAsset.SubAssets[i].AssetID = assetGuid; diff --git a/Prowl.Editor/Assets/AssetDatabase.FileOperations.cs b/Prowl.Editor/Assets/AssetDatabase.FileOperations.cs index 744d77ac..63572a6c 100644 --- a/Prowl.Editor/Assets/AssetDatabase.FileOperations.cs +++ b/Prowl.Editor/Assets/AssetDatabase.FileOperations.cs @@ -100,7 +100,7 @@ public static bool Rename(FileInfo file, string newName) /// /// Renames a folder. /// - /// The folder to rename. + /// The folder to rename. /// The new name of the folder. /// True if the folder was renamed successfully, false otherwise. public static bool Rename(DirectoryInfo source, string newName) @@ -143,7 +143,7 @@ public static bool Delete(FileInfo file) /// /// Deletes a folder. /// - /// The folder to delete. + /// The folder to delete. /// True if the folder was deleted successfully, false otherwise. public static bool Delete(DirectoryInfo source) { diff --git a/Prowl.Editor/Assets/AssetDatabase.Packages.cs b/Prowl.Editor/Assets/AssetDatabase.Packages.cs index 56cdb183..234616a3 100644 --- a/Prowl.Editor/Assets/AssetDatabase.Packages.cs +++ b/Prowl.Editor/Assets/AssetDatabase.Packages.cs @@ -325,7 +325,7 @@ public static async Task InstallPackage(string packageId, string version) Update(); } - public static async Task UninstallPackage(string packageId, string version) + public static void UninstallPackage(string packageId, string version) { ArgumentNullException.ThrowIfNull(packageId, nameof(packageId)); ArgumentNullException.ThrowIfNull(version, nameof(version)); diff --git a/Prowl.Editor/Assets/AssetDatabase.Utilities.cs b/Prowl.Editor/Assets/AssetDatabase.Utilities.cs index e3348343..2850ce23 100644 --- a/Prowl.Editor/Assets/AssetDatabase.Utilities.cs +++ b/Prowl.Editor/Assets/AssetDatabase.Utilities.cs @@ -12,7 +12,7 @@ public static partial class AssetDatabase #region Public Methods - public static bool PathToCachedNode(string path, out AssetDirectoryCache.DirNode node) + public static bool PathToCachedNode(string path, out AssetDirectoryCache.DirNode? node) { node = null; foreach (var tuple in rootFolders) @@ -239,7 +239,7 @@ public static void GenerateUniqueAssetPath(ref FileInfo file) return result; } - public static Type GetTypeOfAsset(Guid guid, ushort fileID) + public static Type? GetTypeOfAsset(Guid guid, ushort fileID) { if (assetGuidToMeta.TryGetValue(guid, out var meta)) if (meta.assetTypes.Length > fileID) diff --git a/Prowl.Editor/Assets/AssetDirectoryCache.cs b/Prowl.Editor/Assets/AssetDirectoryCache.cs index f34ce24e..84838d91 100644 --- a/Prowl.Editor/Assets/AssetDirectoryCache.cs +++ b/Prowl.Editor/Assets/AssetDirectoryCache.cs @@ -5,10 +5,10 @@ namespace Prowl.Editor.Assets; public class AssetDirectoryCache(DirectoryInfo root) { - public class DirNode(DirectoryInfo directory, DirNode parent) + public class DirNode(DirectoryInfo directory, DirNode? parent) { public DirectoryInfo Directory = directory; - public DirNode Parent = parent; + public DirNode? Parent = parent; public List SubDirectories = []; public List Files = []; } @@ -90,7 +90,7 @@ public void Refresh() _rootNode = BuildDirectoryTree(_rootDir, null); } - private DirNode BuildDirectoryTree(DirectoryInfo directory, DirNode parent) + private DirNode BuildDirectoryTree(DirectoryInfo directory, DirNode? parent) { DirNode node = new(directory, parent); try diff --git a/Prowl.Editor/Assets/ImporterAttribute.cs b/Prowl.Editor/Assets/ImporterAttribute.cs index 9139f204..c88fda27 100644 --- a/Prowl.Editor/Assets/ImporterAttribute.cs +++ b/Prowl.Editor/Assets/ImporterAttribute.cs @@ -31,26 +31,25 @@ public static void GenerateLookUp() extToIcon.Clear(); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) foreach (var type in assembly.GetTypes()) - if (type != null) + { + var attribute = type.GetCustomAttribute(); + if (attribute == null) continue; + + foreach (var extRW in attribute.Extensions) { - var attribute = type.GetCustomAttribute(); - if (attribute == null) continue; - - foreach (var extRW in attribute.Extensions) - { - var ext = extRW.ToLower(); - // Make sure the Extension is formatted correctly '.png' 1 dot at start - if (ext[0] != '.') ext = '.' + ext; - // Check if has more then 1 '.' - if (ext.Count(x => x == '.') > 1) throw new Exception($"Extension {ext} is formatted incorrectly on importer: {type.Name}"); - - if (extToImporter.TryGetValue(ext, out var oldType)) - Debug.LogError($"Asset Importer Overwritten. {ext} extension already in use by: {oldType.Name}, being overwritten by: {type.Name}"); - extToImporter[ext] = type; - extToIcon[ext] = attribute.FileIcon; - extToGeneralType[ext] = attribute.GeneralType; - } + var ext = extRW.ToLower(); + // Make sure the Extension is formatted correctly '.png' 1 dot at start + if (ext[0] != '.') ext = '.' + ext; + // Check if has more then 1 '.' + if (ext.Count(x => x == '.') > 1) throw new Exception($"Extension {ext} is formatted incorrectly on importer: {type.Name}"); + + if (extToImporter.TryGetValue(ext, out var oldType)) + Debug.LogError($"Asset Importer Overwritten. {ext} extension already in use by: {oldType.Name}, being overwritten by: {type.Name}"); + extToImporter[ext] = type; + extToIcon[ext] = attribute.FileIcon; + extToGeneralType[ext] = attribute.GeneralType; } + } } [OnAssemblyUnload] @@ -104,15 +103,14 @@ public static void GenerateLookUp() { foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) foreach (var type in assembly.GetTypes()) - if (type != null) - { - var attribute = type.GetCustomAttribute(); - if (attribute == null) continue; - - if (typeToEditor.TryGetValue(attribute.Type, out var oldType)) - Debug.LogError($"Custom Editor Overwritten. {attribute.Type.Name} already has a custom Editor: {oldType.Name}, being overwritten by: {type.Name}"); - typeToEditor[attribute.Type] = type; - } + { + var attribute = type.GetCustomAttribute(); + if (attribute == null) continue; + + if (typeToEditor.TryGetValue(attribute.Type, out var oldType)) + Debug.LogError($"Custom Editor Overwritten. {attribute.Type.Name} already has a custom Editor: {oldType.Name}, being overwritten by: {type.Name}"); + typeToEditor[attribute.Type] = type; + } } [OnAssemblyUnload] diff --git a/Prowl.Editor/Assets/Importers/AudioClipImporter.cs b/Prowl.Editor/Assets/Importers/AudioClipImporter.cs index e078b223..dd6f38fc 100644 --- a/Prowl.Editor/Assets/Importers/AudioClipImporter.cs +++ b/Prowl.Editor/Assets/Importers/AudioClipImporter.cs @@ -124,7 +124,8 @@ public class AudioClipEditor : ScriptedEditor public override void OnEnable() { - serialized = AssetDatabase.LoadAsset((target as MetaFile).AssetPath); + var metaFile = target as MetaFile ?? throw new Exception(); + serialized = AssetDatabase.LoadAsset(metaFile.AssetPath) ?? throw new Exception(); } public override void OnDisable() @@ -140,7 +141,7 @@ public override void OnInspectorGUI() { double ItemSize = EditorStylePrefs.Instance.ItemSize; - var importer = (AudioClipImporter)(target as MetaFile).importer; + var importer = (AudioClipImporter)(target as MetaFile).Importer; try { diff --git a/Prowl.Editor/Assets/Importers/FontImporter.cs b/Prowl.Editor/Assets/Importers/FontImporter.cs index f3072d17..6306e3d2 100644 --- a/Prowl.Editor/Assets/Importers/FontImporter.cs +++ b/Prowl.Editor/Assets/Importers/FontImporter.cs @@ -27,7 +27,7 @@ public override void Import(SerializedAsset ctx, FileInfo assetPath) [CustomEditor(typeof(FontImporter))] public class FontEditor : ScriptedEditor { - static int start, end; + // static int start, end; private readonly int numberOfProperties = 0; public void InputFloat(string name, ref float val) { @@ -101,7 +101,7 @@ public override void OnInspectorGUI() { double ItemSize = EditorStylePrefs.Instance.ItemSize; - var importer = (FontImporter)(target as MetaFile).importer; + var importer = (FontImporter)(target as MetaFile).Importer; gui.CurrentNode.Layout(LayoutType.Column); diff --git a/Prowl.Editor/Assets/Importers/MaterialImporter.cs b/Prowl.Editor/Assets/Importers/MaterialImporter.cs index 420219bd..28115f55 100644 --- a/Prowl.Editor/Assets/Importers/MaterialImporter.cs +++ b/Prowl.Editor/Assets/Importers/MaterialImporter.cs @@ -38,7 +38,7 @@ public class MaterialImporterEditor : ScriptedEditor { public override void OnInspectorGUI() { - var importer = (MaterialImporter)(target as MetaFile).importer; + var importer = (MaterialImporter)(target as MetaFile).Importer; try { diff --git a/Prowl.Editor/Assets/Importers/ModelImporter.cs b/Prowl.Editor/Assets/Importers/ModelImporter.cs index 86947ed4..22978f18 100644 --- a/Prowl.Editor/Assets/Importers/ModelImporter.cs +++ b/Prowl.Editor/Assets/Importers/ModelImporter.cs @@ -667,7 +667,7 @@ public override void OnInspectorGUI() { double ItemSize = EditorStylePrefs.Instance.ItemSize; - var importer = (ModelImporter)(target as MetaFile).importer; + var importer = (ModelImporter)(target as MetaFile).Importer; var serialized = AssetDatabase.LoadAsset((target as MetaFile).AssetPath); gui.CurrentNode.Layout(LayoutType.Column); diff --git a/Prowl.Editor/Assets/Importers/TextureImporter.cs b/Prowl.Editor/Assets/Importers/TextureImporter.cs index 7d0bf576..8a60277c 100644 --- a/Prowl.Editor/Assets/Importers/TextureImporter.cs +++ b/Prowl.Editor/Assets/Importers/TextureImporter.cs @@ -53,7 +53,7 @@ public class TextureEditor : ScriptedEditor { public override void OnInspectorGUI() { - var importer = (TextureImporter)(target as MetaFile).importer; + var importer = (TextureImporter)(target as MetaFile).Importer; gui.CurrentNode.Layout(LayoutType.Column); diff --git a/Prowl.Editor/Assets/MetaFile.cs b/Prowl.Editor/Assets/MetaFile.cs index 3415d51d..886549ec 100644 --- a/Prowl.Editor/Assets/MetaFile.cs +++ b/Prowl.Editor/Assets/MetaFile.cs @@ -18,7 +18,7 @@ public class MetaFile public string[] assetTypes = []; public DateTime lastModified; - public ScriptedImporter importer; + public readonly ScriptedImporter Importer; public List dependencies; /// Default constructor for MetaFile. @@ -35,7 +35,8 @@ public MetaFile(FileInfo assetFile) AssetPath = assetFile; guid = Guid.NewGuid(); lastModified = assetFile.LastWriteTimeUtc; - importer = Activator.CreateInstance(importerType) as ScriptedImporter; + var importer = Activator.CreateInstance(importerType) as ScriptedImporter; + Importer = importer ?? throw new Exception(); } /// Save the MetaFile to a specified file or default to the associated asset file with a ".meta" extension. diff --git a/Prowl.Editor/Editor/AssetsBrowserWindow.cs b/Prowl.Editor/Editor/AssetsBrowserWindow.cs index f2889852..406d4bc3 100644 --- a/Prowl.Editor/Editor/AssetsBrowserWindow.cs +++ b/Prowl.Editor/Editor/AssetsBrowserWindow.cs @@ -334,20 +334,20 @@ public void RenderEntry(ref int index, AssetDirectoryCache.FileNode entry) var interact = gui.GetInteractable(); AssetsTreeWindow.HandleFileClick(-1, interact, entry, i, true); - DrawFileEntry(index++, entry.File, interact, true, subAssets[i]); + DrawFileEntry(index++, entry.File, interact, subAssets[i]); } } } } - private void DrawFileEntry(int index, FileSystemInfo entry, Interactable interact, bool hasSubAsset = false, AssetDatabase.SubAssetCache? subAsset = null) + private void DrawFileEntry(int index, FileSystemInfo entry, Interactable interact, AssetDatabase.SubAssetCache? subAsset = null) { var rect = gui.CurrentNode.LayoutData.Rect; //if (hasSubAsset) // rect.Expand(-10); var entrySize = rect.width; - gui.Tooltip(hasSubAsset ? subAsset.Value.name : entry.FullName); + gui.Tooltip(subAsset is not null ? subAsset.Value.name : entry.FullName); var color = EditorStylePrefs.Instance.Borders; if (entry is FileInfo f) diff --git a/Prowl.Editor/Editor/AssetsTreeWindow.cs b/Prowl.Editor/Editor/AssetsTreeWindow.cs index 407171ff..5513a0b8 100644 --- a/Prowl.Editor/Editor/AssetsTreeWindow.cs +++ b/Prowl.Editor/Editor/AssetsTreeWindow.cs @@ -129,7 +129,7 @@ protected override void Draw() } } - public static void DrawContextMenu(FileSystemInfo? fileInfo, DirectoryInfo? directory = null, bool fromAssetBrowser = false, LayoutNode popupHolder = null) + public static void DrawContextMenu(FileSystemInfo? fileInfo, DirectoryInfo? directory = null, bool fromAssetBrowser = false, LayoutNode? popupHolder = null) { bool closePopup = false; diff --git a/Prowl.Editor/Editor/Docking/DockContainer.cs b/Prowl.Editor/Editor/Docking/DockContainer.cs index 696f384e..bd2c18ac 100644 --- a/Prowl.Editor/Editor/Docking/DockContainer.cs +++ b/Prowl.Editor/Editor/Docking/DockContainer.cs @@ -9,15 +9,15 @@ namespace Prowl.Editor.Docking; public class DockContainer { - public DockNode Root = new DockNode(); - private Vector2 PaddedMins => new Vector2(0, 0); + public DockNode Root = new(); + private Vector2 PaddedMins => new(0, 0); public void Update(Rect root) { Root.UpdateRecursive(root.Min, root.Max); } - public DockNode TraceLeaf(double x, double y) + public DockNode? TraceLeaf(double x, double y) { x -= PaddedMins.x; y -= PaddedMins.y; @@ -25,7 +25,7 @@ public DockNode TraceLeaf(double x, double y) return Root.TraceLeaf(x, y); } - public DockPlacement GetPlacement(double x, double y, out List possibleAreas, out Rect hovered) + public DockPlacement GetPlacement(double x, double y, out List? possibleAreas, out Rect hovered) { possibleAreas = null; hovered = Rect.Zero; @@ -38,21 +38,23 @@ public DockPlacement GetPlacement(double x, double y, out List possibleAre return default; Vector2 cen = (leaf.Mins + leaf.Maxs) * 0.5f; - Vector2 size = new Vector2(100, 100); + Vector2 size = new(100, 100); // TODO: Why do we need to remove half of the size? Shouldn't ((min + max) / 2) be the center already? cen.x -= size.x / 2; cen.y -= size.y / 2; - Rect main = new Rect(cen, size); + Rect main = new(cen, size); - Rect left = new Rect(cen - new Vector2(size.x + 5, 0), size); - Rect right = new Rect(cen + new Vector2(size.x + 5, 0), size); - Rect top = new Rect(cen - new Vector2(0, size.y + 5), size); - Rect bottom = new Rect(cen + new Vector2(0, size.y + 5), size); + Rect left = new(cen - new Vector2(size.x + 5, 0), size); + Rect right = new(cen + new Vector2(size.x + 5, 0), size); + Rect top = new(cen - new Vector2(0, size.y + 5), size); + Rect bottom = new(cen + new Vector2(0, size.y + 5), size); possibleAreas = [main, left, right, top, bottom]; - DockPlacement placement = new DockPlacement(); - placement.Leaf = leaf; - placement.PolygonVerts = new Vector2[4]; + DockPlacement placement = new() + { + Leaf = leaf, + PolygonVerts = new Vector2[4] + }; while (true) { @@ -318,7 +320,7 @@ public bool DetachWindow(EditorWindow window) if (leaf.LeafWindows.Count == 0) { - DockNode parent = FindParent(leaf); + DockNode? parent = FindParent(leaf); if (parent != null) { DockNode neighborNode; diff --git a/Prowl.Editor/Editor/Docking/DockNode.cs b/Prowl.Editor/Editor/Docking/DockNode.cs index 4b69997c..5c110837 100644 --- a/Prowl.Editor/Editor/Docking/DockNode.cs +++ b/Prowl.Editor/Editor/Docking/DockNode.cs @@ -52,7 +52,7 @@ public enum NodeType for (int i = 0; i < 2; ++i) { - DockNode leaf = Child[i].TraceLeaf(x, y); + DockNode? leaf = Child[i].TraceLeaf(x, y); if (leaf != null) return leaf; } @@ -82,7 +82,7 @@ public enum NodeType return this; } - DockNode node = Child[0].TraceSeparator(x, y); + DockNode? node = Child[0].TraceSeparator(x, y); if (node != null) return node; @@ -138,7 +138,7 @@ public void UpdateRecursive(double x, double y, double w, double h) } } - public DockNode FindParent(DockNode node) + public DockNode? FindParent(DockNode node) { if (Type == NodeType.Leaf) return null; @@ -147,7 +147,7 @@ public DockNode FindParent(DockNode node) if (Child[i] == node) return this; - DockNode n = Child[0].FindParent(node); + DockNode? n = Child[0].FindParent(node); if (n != null) return n; diff --git a/Prowl.Editor/Editor/DragnDrop.cs b/Prowl.Editor/Editor/DragnDrop.cs index 6b64a3e9..3bce1dc6 100644 --- a/Prowl.Editor/Editor/DragnDrop.cs +++ b/Prowl.Editor/Editor/DragnDrop.cs @@ -11,7 +11,7 @@ namespace Prowl.Editor; public static class DragnDrop { - private static object[] draggedObject; + private static object[]? draggedObject; private static string payloadTag = ""; diff --git a/Prowl.Editor/Editor/EditorGUI.cs b/Prowl.Editor/Editor/EditorGUI.cs index 94a8b2cc..ffadbbf3 100644 --- a/Prowl.Editor/Editor/EditorGUI.cs +++ b/Prowl.Editor/Editor/EditorGUI.cs @@ -357,7 +357,7 @@ static bool HandleBeginGUIAttributes(string id, object target, IEnumerable m_Leaf != null; - private DockNode m_Leaf; - private Vector2 m_DockPosition; + private DockNode? m_Leaf; + // private Vector2 m_DockPosition; - public DockNode Leaf + public DockNode? Leaf { get => m_Leaf; internal set => m_Leaf = value; @@ -128,7 +128,7 @@ public void ProcessFrame() { HandleTitleBarInteraction(); - if (IsDocked && Leaf.LeafWindows.Count > 0) + if (IsDocked && Leaf?.LeafWindows.Count > 0) { double[] tabWidths = new double[Leaf.LeafWindows.Count]; double total = 0; @@ -310,7 +310,7 @@ private void HandleTitleBarInteraction() if (gui.IsPointerMoving && IsDocked) { - EditorGuiManager.Container.DetachWindow(this); + EditorGuiManager.Container?.DetachWindow(this); // Position the window so the mouse is over the title bar _x = gui.PointerPos.x - (_width / 2); _y = gui.PointerPos.y - 10; @@ -359,4 +359,4 @@ protected virtual void Draw() { } protected virtual void Update() { } protected virtual void Close() { } -} \ No newline at end of file +} diff --git a/Prowl.Editor/Editor/GameWindow.cs b/Prowl.Editor/Editor/GameWindow.cs index a845a7f7..8b630aa1 100644 --- a/Prowl.Editor/Editor/GameWindow.cs +++ b/Prowl.Editor/Editor/GameWindow.cs @@ -34,7 +34,7 @@ public enum Resolutions const int HeaderHeight = 27; RenderTexture RenderTarget; - bool previouslyPlaying = false; + // bool previouslyPlaying = false; bool hasFrame; public static WeakReference LastFocused; diff --git a/Prowl.Editor/Editor/HierarchyWindow.cs b/Prowl.Editor/Editor/HierarchyWindow.cs index e7037759..ff96d767 100644 --- a/Prowl.Editor/Editor/HierarchyWindow.cs +++ b/Prowl.Editor/Editor/HierarchyWindow.cs @@ -21,7 +21,7 @@ public class HierarchyWindow : EditorWindow private const float PingDuration = 3f; private static float pingTimer; - private static WeakReference pingedGO; + private static WeakReference? pingedGO; private bool justStartedRename; public HierarchyWindow() : base() diff --git a/Prowl.Editor/Editor/InspectorWindow.cs b/Prowl.Editor/Editor/InspectorWindow.cs index 43688723..f58038a9 100644 --- a/Prowl.Editor/Editor/InspectorWindow.cs +++ b/Prowl.Editor/Editor/InspectorWindow.cs @@ -8,6 +8,7 @@ using Prowl.Icons; using Prowl.Runtime; using Prowl.Runtime.GUI; +using EditorCustom = (object parent, Prowl.Editor.Assets.ScriptedEditor? editor); namespace Prowl.Editor; @@ -20,7 +21,7 @@ public class InspectorWindow : EditorWindow private object? Selected; private bool lockSelection; - (object, ScriptedEditor)? customEditor; + (object parent, ScriptedEditor scriptedEditor)? customEditor; public InspectorWindow() : base() { @@ -111,12 +112,10 @@ protected override void Draw() var meta = MetaFile.Load(path); if (meta != null) { - Type? editorType = CustomEditorAttribute.GetEditor(meta.importer.GetType()); + Type? editorType = CustomEditorAttribute.GetEditor(meta.Importer.GetType()); if (editorType != null) { - customEditor = (path, (ScriptedEditor)Activator.CreateInstance(editorType)); - customEditor.Value.Item2.target = meta; - customEditor.Value.Item2.OnEnable(); + CreateInstanceCustomEditor(path, editorType, meta); destroyCustomEditor = false; } else @@ -143,7 +142,7 @@ protected override void Draw() else if (customEditor.Value.Item1.Equals(path)) { // We are still editing the same asset path - customEditor.Value.Item2.OnInspectorGUI(); + customEditor.Value.scriptedEditor?.OnInspectorGUI(); destroyCustomEditor = false; } } @@ -155,9 +154,7 @@ protected override void Draw() Type? editorType = CustomEditorAttribute.GetEditor(Selected.GetType()); if (editorType != null) { - customEditor = (Selected, (ScriptedEditor)Activator.CreateInstance(editorType)); - customEditor.Value.Item2.target = Selected; - customEditor.Value.Item2.OnEnable(); + customEditor = CreateInstanceCustomEditor(Selected, editorType, Selected); destroyCustomEditor = false; } else @@ -177,19 +174,31 @@ protected override void Draw() else if (customEditor.Value.Item1 == Selected) { // We are still editing the same object - customEditor.Value.Item2.OnInspectorGUI(); + customEditor.Value.scriptedEditor?.OnInspectorGUI(); destroyCustomEditor = false; } } if (destroyCustomEditor) { - customEditor?.Item2.OnDisable(); + customEditor?.scriptedEditor?.OnDisable(); customEditor = null; } } } + private (object parent, ScriptedEditor scriptedEditor)? CreateInstanceCustomEditor(object path, Type editorType, object meta) + { + var scriptedEditor = Activator.CreateInstance(editorType) as ScriptedEditor; + customEditor = (path, scriptedEditor); + if (customEditor.Value.scriptedEditor is not null) + { + customEditor.Value.scriptedEditor.target = meta; + customEditor.Value.scriptedEditor.OnEnable(); + } + return customEditor; + } + private void DrawInspectorLabel(string message) { double ItemSize = EditorStylePrefs.Instance.ItemSize; diff --git a/Prowl.Editor/Editor/NodeEditor/NodeEditor.cs b/Prowl.Editor/Editor/NodeEditor/NodeEditor.cs index 969abe55..c84c0064 100644 --- a/Prowl.Editor/Editor/NodeEditor/NodeEditor.cs +++ b/Prowl.Editor/Editor/NodeEditor/NodeEditor.cs @@ -444,9 +444,13 @@ protected bool DrawBackingField(Gui g, Node node, int fieldIndex, NodePort port) bool changed = false; var fieldInfo = GetFieldInfo(port.node.GetType(), port.fieldName); - InputAttribute field = fieldInfo.GetCustomAttributes(true).FirstOrDefault(); + if (fieldInfo is null) + { + return changed; + } + InputAttribute? field = fieldInfo.GetCustomAttributes(true).FirstOrDefault(); bool showBacking = false; - if (field.backingValue != ShowBackingValue.Never) + if (field is not null && field.backingValue != ShowBackingValue.Never) showBacking = field.backingValue == ShowBackingValue.Always || (field.backingValue == ShowBackingValue.Unconnected && !port.IsConnected); if (showBacking) @@ -462,12 +466,12 @@ protected bool DrawBackingField(Gui g, Node node, int fieldIndex, NodePort port) return changed; } - protected static FieldInfo GetFieldInfo(Type type, string fieldName) + protected static FieldInfo? GetFieldInfo(Type type, string fieldName) { // If we can't find field in the first run, it's probably a private field in a base class. - FieldInfo field = type.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + FieldInfo? field = type.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); // Search base classes for private fields only. Public fields are found above - while (field == null && (type = type.BaseType) != typeof(Node)) field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + while (field is not null && type.BaseType is not null && (type = type.BaseType) != typeof(Node)) field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); return field; } @@ -578,7 +582,7 @@ public class NodeEditor internal Rect dragSelection; private string _searchText = string.Empty; - private static NodeMenuItemInfo rootMenuItem; + private static NodeMenuItemInfo? rootMenuItem; private readonly SelectHandler SelectHandler = new((item) => !item.IsAlive, (a, b) => ReferenceEquals(a.Target, b.Target)); @@ -1034,7 +1038,7 @@ public bool DrawBlackBoard(Gui gui) { object? obj = graph; // Get graph.parameters field - FieldInfo props = graph.GetType().GetField("parameters", BindingFlags.Instance | BindingFlags.Public); + FieldInfo props = graph.GetType().GetField("parameters", BindingFlags.Instance | BindingFlags.Public) ?? throw new Exception(); return EditorGUI.PropertyGrid("BlackBoard", ref obj, [props], EditorGUI.PropertyGridConfig.NoHeader); } } @@ -1086,15 +1090,16 @@ public void Release() private void DrawMenuItems(NodeMenuItemInfo menuItem, Gui g) { - bool foundName = false; + // bool foundName = false; bool hasSearch = string.IsNullOrEmpty(_searchText) == false; foreach (var item in menuItem.Children) { if (hasSearch && (item.Name.Contains(_searchText, StringComparison.CurrentCultureIgnoreCase) == false || item.Type == null)) { DrawMenuItems(item, g); - if (hasSearch && item.Name.Equals(_searchText, StringComparison.CurrentCultureIgnoreCase)) - foundName = true; + // TODO: `foundName` is not used anywhere + // if (hasSearch && item.Name.Equals(_searchText, StringComparison.CurrentCultureIgnoreCase)) + // foundName = true; continue; } @@ -1229,12 +1234,12 @@ private class NodeMenuItemInfo { public string Name; public Type Type; - public readonly MethodInfo Method; + public readonly MethodInfo? Method; public readonly List Children = []; public NodeMenuItemInfo() { } - public NodeMenuItemInfo(Type type, MethodInfo method = null) + public NodeMenuItemInfo(Type type, MethodInfo? method = null) { Type = type; Method = method; @@ -1244,7 +1249,7 @@ public NodeMenuItemInfo(Type type, MethodInfo method = null) Name = addToMenuAttribute.catagory; } - public void AddChild(string path, Type type, MethodInfo method = null) + public void AddChild(string path, Type type, MethodInfo? method = null) { string[] parts = path.Split('/'); NodeMenuItemInfo currentNode = this; diff --git a/Prowl.Editor/Editor/PackageManager.cs b/Prowl.Editor/Editor/PackageManager.cs index 25d2cf08..12d97d5a 100644 --- a/Prowl.Editor/Editor/PackageManager.cs +++ b/Prowl.Editor/Editor/PackageManager.cs @@ -170,7 +170,7 @@ private void DrawPackageList() } } - private void DrawPackageDetails() + private async void DrawPackageDetails() { if (loadingDetails) { @@ -211,7 +211,7 @@ private void DrawPackageDetails() if (canUpdate && EditorGUI.StyledButton("Update", installWidth / 2, itemSize)) { AssetDatabase.UninstallPackage(_metadata.Identity.Id, installedPackage.Identity.Version.ToString()); - AssetDatabase.InstallPackage(_metadata.Identity.Id, _projectVersions[_selectedVersionIndex]); + await AssetDatabase.InstallPackage(_metadata.Identity.Id, _projectVersions[_selectedVersionIndex]); } if (EditorGUI.StyledButton("Uninstall", canUpdate ? installWidth / 2 : installWidth, itemSize)) @@ -226,7 +226,7 @@ private void DrawPackageDetails() if (gui.Combo("Version", "VersionPopup", ref _selectedVersionIndex, _projectVersions, 0, 0, 75, itemSize)) PopulateDetails(_projectVersions[_selectedVersionIndex]); if (EditorGUI.StyledButton("Install", installWidth, itemSize)) - AssetDatabase.InstallPackage(_metadata.Identity.Id, _projectVersions[_selectedVersionIndex]); + await AssetDatabase.InstallPackage(_metadata.Identity.Id, _projectVersions[_selectedVersionIndex]); } } diff --git a/Prowl.Editor/Editor/ProjectSettingsWindow.cs b/Prowl.Editor/Editor/ProjectSettingsWindow.cs index 9e4ab3e3..c27093f2 100644 --- a/Prowl.Editor/Editor/ProjectSettingsWindow.cs +++ b/Prowl.Editor/Editor/ProjectSettingsWindow.cs @@ -107,8 +107,8 @@ private void RenderBody() if (currentType == null) return; // Draw Settings - object setting = currentSingleton; - + object? setting = currentSingleton ?? throw new Exception(); + string name = currentType.Name.Replace("Preferences", ""); if (PropertyGrid(name, ref setting, TargetFields.Serializable | TargetFields.Properties, PropertyGridConfig.NoBorder | PropertyGridConfig.NoBackground)) { diff --git a/Prowl.Editor/Editor/PropertyDrawer/Drawers/Bool_PropertyDrawer.cs b/Prowl.Editor/Editor/PropertyDrawer/Drawers/Bool_PropertyDrawer.cs index a613d951..d8484c7c 100644 --- a/Prowl.Editor/Editor/PropertyDrawer/Drawers/Bool_PropertyDrawer.cs +++ b/Prowl.Editor/Editor/PropertyDrawer/Drawers/Bool_PropertyDrawer.cs @@ -13,7 +13,7 @@ public class Bool_PropertyDrawer : PropertyDrawer public override bool OnValueGUI(Gui gui, string ID, Type targetType, ref object? value) { - bool val = (bool)value; + bool val = value is bool v ? v : Convert.ToBoolean(value); bool changed = Gui.ActiveGUI.Checkbox(ID + "Val", ref val, 0, 0, out _, EditorGUI.GetInputStyle()); value = val; return changed; diff --git a/Prowl.Editor/Editor/PropertyDrawer/Drawers/Color_PropertyDrawer.cs b/Prowl.Editor/Editor/PropertyDrawer/Drawers/Color_PropertyDrawer.cs index 40bf52b6..2e799443 100644 --- a/Prowl.Editor/Editor/PropertyDrawer/Drawers/Color_PropertyDrawer.cs +++ b/Prowl.Editor/Editor/PropertyDrawer/Drawers/Color_PropertyDrawer.cs @@ -13,7 +13,7 @@ public override bool OnValueGUI(Gui gui, string ID, Type targetType, ref object? { gui.CurrentNode.Layout(LayoutType.Row).ScaleChildren(); - Color val = (Color)value; + Color val = value is Color v ? v : throw new Exception(); var style = EditorGUI.InputFieldStyle; style.TextColor = val with { a = 1 }; diff --git a/Prowl.Editor/Editor/PropertyDrawer/Drawers/Double_PropertyDrawer.cs b/Prowl.Editor/Editor/PropertyDrawer/Drawers/Double_PropertyDrawer.cs index 3809b71d..a32bf473 100644 --- a/Prowl.Editor/Editor/PropertyDrawer/Drawers/Double_PropertyDrawer.cs +++ b/Prowl.Editor/Editor/PropertyDrawer/Drawers/Double_PropertyDrawer.cs @@ -12,9 +12,9 @@ public class Double_PropertyDrawer : PropertyDrawer public override double MinWidth => EditorStylePrefs.Instance.ItemSize * 2; public override bool OnValueGUI(Gui gui, string ID, Type targetType, ref object? value) { - double val = (double)value; + double val = value is double v ? v : double.NaN; bool changed = EditorGUI.InputDouble(ID + "Val", ref val, 0, 0, Size.Percentage(1f), EditorGUI.InputFieldStyle); value = val; return changed; } -} \ No newline at end of file +} diff --git a/Prowl.Editor/Editor/PropertyDrawer/Drawers/Float_PropertyDrawer.cs b/Prowl.Editor/Editor/PropertyDrawer/Drawers/Float_PropertyDrawer.cs index 367cc4e3..d1ef8579 100644 --- a/Prowl.Editor/Editor/PropertyDrawer/Drawers/Float_PropertyDrawer.cs +++ b/Prowl.Editor/Editor/PropertyDrawer/Drawers/Float_PropertyDrawer.cs @@ -13,7 +13,7 @@ public class Float_PropertyDrawer : PropertyDrawer public override bool OnValueGUI(Gui gui, string ID, Type targetType, ref object? value) { - float val = (float)value; + float val = value is float v ? v : Convert.ToSingle(value); bool changed = EditorGUI.InputFloat(ID + "Val", ref val, 0, 0, Size.Percentage(1f), EditorGUI.InputFieldStyle); value = val; return changed; diff --git a/Prowl.Editor/Editor/PropertyDrawer/Drawers/PropertyDrawerEnumerable.cs b/Prowl.Editor/Editor/PropertyDrawer/Drawers/PropertyDrawerEnumerable.cs index 0091cf7c..a20e5109 100644 --- a/Prowl.Editor/Editor/PropertyDrawer/Drawers/PropertyDrawerEnumerable.cs +++ b/Prowl.Editor/Editor/PropertyDrawer/Drawers/PropertyDrawerEnumerable.cs @@ -1,6 +1,8 @@ // This file is part of the Prowl Game Engine // Licensed under the MIT License. See the LICENSE file in the project root for details. +using DotRecast.Core; + using Prowl.Editor.Preferences; using Prowl.Icons; using Prowl.Runtime; @@ -104,12 +106,12 @@ public override bool PropertyLayout(Gui gui, string label, int index, Type prope // See if Element has a field called "Name" or "name" and use that as the label var nameField = ElementType(list).GetField("Name") ?? ElementType(list).GetField("name"); - string elementName = ((string)nameField?.GetValue(element)) ?? "Element " + i; + string elementName = nameField?.GetValue(element) as string ?? "Element " + i; config |= EditorGUI.PropertyGridConfig.NoBackground; changed |= DrawerAttribute.DrawProperty(gui, elementName, i, ElementType(list), ref element, config); if (changed) - SetElement(list, i, element); + SetElement(list, i, element!); if (drawerID == selectedDrawer && i == selectedElement) @@ -222,14 +224,14 @@ public override bool PropertyLayout(Gui gui, string label, int index, Type prope [Drawer(typeof(Array))] public class PropertyDrawerArray : PropertyDrawerEnumerable { - protected override Type ElementType(Array value) => value.GetType().GetElementType(); + protected override Type ElementType(Array value) => value.GetType().GetElementType()!; protected override int GetCount(Array value) => value.Length; - protected override object GetElement(Array value, int index) => value.GetValue(index); + protected override object GetElement(Array value, int index) => value.GetValue(index)!; protected override void SetElement(Array value, int index, object element) => value.SetValue(element, index); protected override void RemoveElement(ref Array value, int index) { var elementType = value.GetType().GetElementType(); - var newArray = Array.CreateInstance(elementType, value.Length - 1); + var newArray = Array.CreateInstance(elementType!, value.Length - 1); Array.Copy(value, 0, newArray, 0, index); Array.Copy(value, index + 1, newArray, index, value.Length - index - 1); value = newArray; @@ -237,7 +239,7 @@ protected override void RemoveElement(ref Array value, int index) protected override void AddElement(ref Array value) { var elementType = value.GetType().GetElementType(); - var newArray = Array.CreateInstance(elementType, value.Length + 1); + var newArray = Array.CreateInstance(elementType!, value.Length + 1); Array.Copy(value, newArray, value.Length); value = newArray; } @@ -248,7 +250,7 @@ public class PropertyDrawerList : PropertyDrawerEnumerable value.GetType().GetGenericArguments()[0]; protected override int GetCount(System.Collections.IList value) => value.Count; - protected override object GetElement(System.Collections.IList value, int index) => value[index]; + protected override object GetElement(System.Collections.IList value, int index) => value[index] ?? throw new Exception(); protected override void SetElement(System.Collections.IList value, int index, object element) => value[index] = element; protected override void RemoveElement(ref System.Collections.IList value, int index) => value.RemoveAt(index); protected override void AddElement(ref System.Collections.IList value) diff --git a/Prowl.Editor/Editor/PropertyDrawer/Drawers/Vector2_PropertyDrawer.cs b/Prowl.Editor/Editor/PropertyDrawer/Drawers/Vector2_PropertyDrawer.cs index 5c9fb0f9..ac520f07 100644 --- a/Prowl.Editor/Editor/PropertyDrawer/Drawers/Vector2_PropertyDrawer.cs +++ b/Prowl.Editor/Editor/PropertyDrawer/Drawers/Vector2_PropertyDrawer.cs @@ -15,7 +15,7 @@ public override bool OnValueGUI(Gui gui, string ID, Type targetType, ref object? { gui.CurrentNode.Layout(LayoutType.Row).ScaleChildren(); - Vector2 val = (Vector2)value; + Vector2 val = value is Vector2 v ? v : throw new Exception(); bool changed = EditorGUI.InputDouble(ID + "X", ref val.x, 0, 0, 0, EditorGUI.VectorXStyle); changed |= EditorGUI.InputDouble(ID + "Y", ref val.y, 0, 0, 0, EditorGUI.VectorYStyle); value = val; diff --git a/Prowl.Editor/Editor/PropertyDrawer/Drawers/Vector3_PropertyDrawer.cs b/Prowl.Editor/Editor/PropertyDrawer/Drawers/Vector3_PropertyDrawer.cs index 678e24b5..81cb7d67 100644 --- a/Prowl.Editor/Editor/PropertyDrawer/Drawers/Vector3_PropertyDrawer.cs +++ b/Prowl.Editor/Editor/PropertyDrawer/Drawers/Vector3_PropertyDrawer.cs @@ -15,7 +15,7 @@ public override bool OnValueGUI(Gui gui, string ID, Type targetType, ref object? { gui.CurrentNode.Layout(LayoutType.Row).ScaleChildren(); - Vector3 val = (Vector3)value; + Vector3 val = value is Vector3 v ? v : throw new Exception(); bool changed = EditorGUI.InputDouble(ID + "X", ref val.x, 0, 0, 0, EditorGUI.VectorXStyle); changed |= EditorGUI.InputDouble(ID + "Y", ref val.y, 0, 0, 0, EditorGUI.VectorYStyle); changed |= EditorGUI.InputDouble(ID + "Z", ref val.z, 0, 0, 0, EditorGUI.VectorZStyle); diff --git a/Prowl.Editor/Editor/PropertyDrawer/Drawers/Vector4_PropertyDrawer.cs b/Prowl.Editor/Editor/PropertyDrawer/Drawers/Vector4_PropertyDrawer.cs index 72091e90..cf4cf33f 100644 --- a/Prowl.Editor/Editor/PropertyDrawer/Drawers/Vector4_PropertyDrawer.cs +++ b/Prowl.Editor/Editor/PropertyDrawer/Drawers/Vector4_PropertyDrawer.cs @@ -14,7 +14,7 @@ public override bool OnValueGUI(Gui gui, string ID, Type targetType, ref object? { gui.CurrentNode.Layout(LayoutType.Row).ScaleChildren(); - Vector4 val = (Vector4)value; + Vector4 val = value is Vector4 v ? v : throw new Exception(); bool changed = EditorGUI.InputDouble(ID + "X", ref val.x, 0, 0, 0, EditorGUI.VectorXStyle); changed |= EditorGUI.InputDouble(ID + "Y", ref val.y, 0, 0, 0, EditorGUI.VectorYStyle); changed |= EditorGUI.InputDouble(ID + "Z", ref val.z, 0, 0, 0, EditorGUI.VectorZStyle); diff --git a/Prowl.Editor/Editor/SceneViewWindow.cs b/Prowl.Editor/Editor/SceneViewWindow.cs index 6155ed5c..0b3211ea 100644 --- a/Prowl.Editor/Editor/SceneViewWindow.cs +++ b/Prowl.Editor/Editor/SceneViewWindow.cs @@ -17,8 +17,8 @@ public class SceneViewWindow : EditorWindow private static bool LastFocusedCameraChanged; readonly Camera Cam; - Material gridMat; - Mesh gridMesh; + // Material gridMat; + // Mesh gridMesh; RenderTexture RenderTarget; Vector2 WindowCenter; Vector2 mouseUV; @@ -26,7 +26,7 @@ public class SceneViewWindow : EditorWindow double fpsTimer; double fps; double moveSpeed = 1; - bool hasStarted = false; + // bool hasStarted = false; double camX, camY; readonly TransformGizmo gizmo; @@ -123,6 +123,7 @@ protected override void Draw() Matrix4x4.CreateTranslation(new Vector3(gX, gY, 0)), GridType.YZ => Matrix4x4.CreateLookToLeftHanded(Vector3.zero, Vector3.up, Vector3.right) * Matrix4x4.CreateTranslation(new Vector3(0, gY, gZ)), + _ => throw new NotImplementedException(), }; } diff --git a/Prowl.Editor/Editor/ScriptedEditors/GameObjectEditor.cs b/Prowl.Editor/Editor/ScriptedEditors/GameObjectEditor.cs index 63284feb..1feb782b 100644 --- a/Prowl.Editor/Editor/ScriptedEditors/GameObjectEditor.cs +++ b/Prowl.Editor/Editor/ScriptedEditors/GameObjectEditor.cs @@ -24,7 +24,7 @@ namespace Prowl.Editor.EditorWindows.CustomEditors; public class GameObjectEditor : ScriptedEditor { private string _searchText = string.Empty; - private static MenuItemInfo rootMenuItem; + private static MenuItemInfo? rootMenuItem; private readonly Dictionary compEditors = new(); [OnAssemblyUnload] diff --git a/Prowl.Editor/Editor/ScriptedEditors/ScriptableObjectEditor.cs b/Prowl.Editor/Editor/ScriptedEditors/ScriptableObjectEditor.cs index 8f3da8b7..ea48c407 100644 --- a/Prowl.Editor/Editor/ScriptedEditors/ScriptableObjectEditor.cs +++ b/Prowl.Editor/Editor/ScriptedEditors/ScriptableObjectEditor.cs @@ -12,19 +12,20 @@ namespace Prowl.Editor.ScriptedEditors; [CustomEditor(typeof(ScriptableObjectImporter))] public class ScriptableObjectEditor : ScriptedEditor { - ScriptableObject? scriptObject; + ScriptableObject? _scriptObject; public override void OnInspectorGUI() { - var importer = (ScriptableObjectImporter)(target as MetaFile).importer; + var metaFile = target as MetaFile ?? throw new Exception(); + // var importer = (ScriptableObjectImporter)metaFile.importer; try { bool changed = false; - scriptObject ??= Serializer.Deserialize(StringTagConverter.ReadFromFile((target as MetaFile).AssetPath)); + _scriptObject ??= Serializer.Deserialize(StringTagConverter.ReadFromFile(metaFile.AssetPath)); - object t = scriptObject; + object t = _scriptObject ?? throw new Exception(); changed |= PropertyGrid("CompPropertyGrid", ref t, TargetFields.Serializable | TargetFields.Properties, PropertyGridConfig.NoHeader | PropertyGridConfig.NoBorder | PropertyGridConfig.NoBackground); // Draw any Buttons @@ -32,15 +33,15 @@ public override void OnInspectorGUI() if (changed) { - scriptObject.OnValidate(); - StringTagConverter.WriteToFile(Serializer.Serialize(scriptObject), (target as MetaFile).AssetPath); - AssetDatabase.Reimport((target as MetaFile).AssetPath); + _scriptObject.OnValidate(); + StringTagConverter.WriteToFile(Serializer.Serialize(_scriptObject), metaFile.AssetPath); + AssetDatabase.Reimport(metaFile.AssetPath); } } catch (Exception e) { - double ItemSize = EditorStylePrefs.Instance.ItemSize; - gui.Node("DummyForText").ExpandWidth().Height(ItemSize * 10); + double itemSize = EditorStylePrefs.Instance.ItemSize; + gui.Node("DummyForText").ExpandWidth().Height(itemSize * 10); gui.Draw2D.DrawText("Failed to Deserialize ScriptableObject, The ScriptableObject file is invalid. Error: " + e.ToString(), gui.CurrentNode.LayoutData.Rect); } } diff --git a/Prowl.Editor/EditorGuiManager.cs b/Prowl.Editor/EditorGuiManager.cs index 846df24a..e86048c0 100644 --- a/Prowl.Editor/EditorGuiManager.cs +++ b/Prowl.Editor/EditorGuiManager.cs @@ -19,9 +19,9 @@ public static class EditorGuiManager public static System.Numerics.Vector4 SelectedColor => new System.Numerics.Vector4(0.06f, 0.53f, 0.98f, 1.00f); public static Gui Gui; - public static DockContainer? Container; - public static EditorWindow DraggingWindow; - public static DockNode DragSplitter; + public static DockContainer Container; + public static EditorWindow? DraggingWindow; + public static DockNode? DragSplitter; private static Vector2 m_DragPos; private static double m_StartSplitPos; @@ -49,7 +49,7 @@ public static void FocusWindow(EditorWindow editorWindow) Windows.Add(editorWindow); FocusedWindow = new WeakReference(editorWindow); - if (editorWindow.IsDocked) + if (editorWindow.IsDocked && editorWindow.Leaf is not null) editorWindow.Leaf.WindowNum = editorWindow.Leaf.LeafWindows.IndexOf(editorWindow); } @@ -69,8 +69,8 @@ internal static void Remove(EditorWindow editorWindow) public static void Update() { - if (FocusedWindow != null && FocusedWindow.Target != null) - FocusWindow(FocusedWindow.Target as EditorWindow); // Ensure focused window is always on top (But below floating windows if docked) + if (FocusedWindow != null && FocusedWindow.Target != null && FocusedWindow.Target is EditorWindow editorWindow) + FocusWindow(editorWindow); // Ensure focused window is always on top (But below floating windows if docked) // Sort by docking as well, Docked windows are guranteed to come first Windows.Sort((a, b) => b.IsDocked.CompareTo(a.IsDocked)); @@ -84,7 +84,6 @@ public static void Update() Veldrid.CommandList commandList = Graphics.GetCommandList(); commandList.Name = "GUI Command Buffer"; - commandList.SetFramebuffer(Graphics.ScreenTarget); commandList.ClearColorTarget(0, Veldrid.RgbaFloat.Black); commandList.ClearDepthStencil(1.0f, 0); @@ -208,7 +207,7 @@ private static void DrawContent(Gui g) { if (!Gui.IsBlockedByInteractable(cursorPos)) { - DockNode node = Container.Root.TraceSeparator(cursorPos.x, cursorPos.y); + DockNode? node = Container.Root.TraceSeparator(cursorPos.x, cursorPos.y); if (node != null) { node.GetSplitterBounds(out var bmins, out var bmaxs, 4); @@ -273,7 +272,7 @@ private static void DrawContent(Gui g) for (int i = 0; i < windowList.Count; i++) { EditorWindow window = windowList[i]; - if (!window.IsDocked || window.Leaf.LeafWindows[window.Leaf.WindowNum] == window) + if (!window.IsDocked || window.Leaf?.LeafWindows[window.Leaf.WindowNum] == window) { g.SetZIndex(i * 100); g.PushID((ulong)window._id); @@ -308,7 +307,7 @@ public static void SaveScene() return; } - if (AssetDatabase.TryGetFile(scene.AssetID, out var file)) + if (AssetDatabase.TryGetFile(scene.AssetID, out var file) && file is not null) { AssetDatabase.Delete(file); @@ -464,7 +463,7 @@ public static void CreateScript() FileInfo file = new FileInfo(Path.Combine(Directory.FullName, $"New Script.cs")); AssetDatabase.GenerateUniqueAssetPath(ref file); - using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream($"Prowl.Editor.EmbeddedResources.NewScript.txt"); + using Stream? stream = Assembly.GetExecutingAssembly().GetManifestResourceStream($"Prowl.Editor.EmbeddedResources.NewScript.txt") ?? throw new Exception(); using StreamReader reader = new StreamReader(stream); string script = reader.ReadToEnd(); script = script.Replace("%SCRIPTNAME%", EditorUtils.FilterAlpha(Path.GetFileNameWithoutExtension(file.Name))); diff --git a/Prowl.Editor/SelectHandler.cs b/Prowl.Editor/SelectHandler.cs index 1cbcb763..b45158d4 100644 --- a/Prowl.Editor/SelectHandler.cs +++ b/Prowl.Editor/SelectHandler.cs @@ -23,7 +23,7 @@ public class SelectHandler where T : class { bool selectedThisFrame; readonly List selected = new(); - SortedList previousFrameSelectables; + SortedList previousFrameSelectables = []; SortedList selectables = new(); int lastSelectedIndex = -1; @@ -35,12 +35,12 @@ public class SelectHandler where T : class public event Action? OnDeselectObject; private readonly Func CheckIsDestroyed; - private readonly Func Equals; + private readonly Func EqualsFunc; public SelectHandler(Func checkIsDestroyed, Func equals) { CheckIsDestroyed = checkIsDestroyed; - Equals = equals; + EqualsFunc = equals; } public void StartFrame() @@ -61,7 +61,7 @@ public void StartFrame() if (lastSelectedIndex == -1 && selected.Count > 0) { - SetSelectedIndex((T)selected[0]); + SetSelectedIndex(Selected[0]); } } @@ -94,7 +94,7 @@ public bool IsSelected(T obj) { for (int i = 0; i < selected.Count; i++) { - if (Equals.Invoke(selected[i], obj)) + if (EqualsFunc.Invoke(selected[i], obj)) return true; } return false; @@ -105,7 +105,7 @@ public void Foreach(Action value) var copy = new List(selected); copy.ForEach((weak) => { - value?.Invoke((T)weak); + value.Invoke((T)weak); }); } @@ -155,7 +155,7 @@ public void Select(T obj, bool additively = false) { for (int i = 0; i < selected.Count; i++) { - if (Equals.Invoke(selected[i], obj)) + if (EqualsFunc.Invoke(selected[i], obj)) { selected.RemoveAt(i); break; @@ -178,11 +178,10 @@ public void Select(T obj, bool additively = false) private void SetSelectedIndex(T entity) { - if (previousFrameSelectables == null) return; // if sorted has this value using reference equals, set lastSelectedIndex to the index of it for (int i = 0; i < previousFrameSelectables.Count; i++) { - if (Equals.Invoke(previousFrameSelectables.Values[i], entity)) + if (EqualsFunc.Invoke(previousFrameSelectables.Values[i], entity)) { lastSelectedIndex = previousFrameSelectables.Keys[i]; break; diff --git a/Prowl.Editor/Utilities/CreateAssetMenu.cs b/Prowl.Editor/Utilities/CreateAssetMenu.cs index 16d13f0e..04c40ab6 100644 --- a/Prowl.Editor/Utilities/CreateAssetMenu.cs +++ b/Prowl.Editor/Utilities/CreateAssetMenu.cs @@ -20,19 +20,21 @@ public static void FindAllMenus() List<(string, Type)> values = new(); foreach (var assembly in assemblies) { - Type[] types = null; try { - types = assembly.GetTypes(); + Type[] types = assembly.GetTypes(); foreach (var type in types) - if (type != null && type.IsAssignableTo(typeof(ScriptableObject))) + if (type.IsAssignableTo(typeof(ScriptableObject))) { var attribute = type.GetCustomAttribute(); if (attribute != null) values.Add(("Assets/" + attribute.Name, type)); } } - catch { } + catch + { + // ignored + } } foreach (var value in values) diff --git a/Prowl.Editor/Utilities/EditorUtils.cs b/Prowl.Editor/Utilities/EditorUtils.cs index 482ca994..77653af0 100644 --- a/Prowl.Editor/Utilities/EditorUtils.cs +++ b/Prowl.Editor/Utilities/EditorUtils.cs @@ -29,7 +29,7 @@ public static List GetDerivedTypes(Type baseType, Assembly assembly) return derivedTypes; } - public static bool IsSubclassOf(Type type, Type baseType) + public static bool IsSubclassOf(Type? type, Type? baseType) { if (type == null || baseType == null || type == baseType) return false; diff --git a/Prowl.Editor/Utilities/MenuItem.cs b/Prowl.Editor/Utilities/MenuItem.cs index 174d3b53..71279452 100644 --- a/Prowl.Editor/Utilities/MenuItem.cs +++ b/Prowl.Editor/Utilities/MenuItem.cs @@ -57,20 +57,21 @@ public static void FindAllMenus() var assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) { - Type[] types = null; try { - types = assembly.GetTypes(); + Type[] types = assembly.GetTypes(); foreach (var type in types) - if (type != null) - foreach (MethodInfo method in type.GetMethods()) - { - var attribute = method.GetCustomAttribute(); - if (attribute != null) - values.Add(new MenuPath(attribute.Path, () => method.Invoke(null, null))); - } + foreach (MethodInfo method in type.GetMethods()) + { + var attribute = method.GetCustomAttribute(); + if (attribute != null) + values.Add(new MenuPath(attribute.Path, () => method.Invoke(null, null))); + } + } + catch + { + // ignored } - catch { } } // values is now a list of all methods with the Menu Paths @@ -105,16 +106,12 @@ public static void FindAllMenus() public static MenuPath? GetMenuPath(string root) { - if (Menus == null) return null; - if (root == null) return null; if (!Menus.ContainsKey(root)) return null; return Menus[root]; } public static bool DrawMenuRoot(string root, bool simpleRoot = false, Size? rootSize = null) { - if (Menus == null) return false; - if (root == null) return false; if (!Menus.ContainsKey(root)) return false; var node = Menus[root]; if (node.Children.Count == 0) return false; @@ -128,7 +125,6 @@ public static bool DrawMenuRoot(string root, bool simpleRoot = false, Size? root public static bool DrawMenu(MenuPath menu, bool simpleRoot, int depth, Size? rootSize = null) { - if (menu == null) return false; if (menu.Children.Count == 0) { if (EditorGUI.StyledButton(menu.Path)) @@ -165,6 +161,8 @@ public static bool DrawMenu(MenuPath menu, bool simpleRoot, int depth, Size? roo if (Gui.ActiveGUI.BeginPopup(menu.Path + "Popup", out var node)) { + ArgumentNullException.ThrowIfNull(node); + using (node.Width(150).Layout(LayoutType.Column).Padding(5).Spacing(5).FitContentHeight().Enter()) { bool changed = false; diff --git a/Prowl.Editor/Utilities/ProjectCache.cs b/Prowl.Editor/Utilities/ProjectCache.cs index 4a1283b3..360d36e4 100644 --- a/Prowl.Editor/Utilities/ProjectCache.cs +++ b/Prowl.Editor/Utilities/ProjectCache.cs @@ -92,7 +92,7 @@ public int Compare(Project? a, Project? b) */ - public Project? GetProject(int index) + public Project GetProject(int index) { Project project = _projectCache[index]; project.Refresh(); @@ -115,7 +115,6 @@ public void OnBeforeSerialize() public void OnAfterDeserialize() { - _serializedProjects ??= []; _projectCache = []; foreach (string path in _serializedProjects) diff --git a/Prowl.Editor/Utilities/ShaderCompiler/ShaderCompiler.cs b/Prowl.Editor/Utilities/ShaderCompiler/ShaderCompiler.cs index bbd4c22c..fdbd5ea0 100644 --- a/Prowl.Editor/Utilities/ShaderCompiler/ShaderCompiler.cs +++ b/Prowl.Editor/Utilities/ShaderCompiler/ShaderCompiler.cs @@ -149,7 +149,7 @@ public static ShaderVariant GenerateVariant(Context ctx, ShaderCreationArgs args ShaderDescription[] compiledSPIRV = Compile(args, state, includer, messages); foreach (ShaderDescription desc in compiledSPIRV) - if (desc.ShaderBytes == null || desc.ShaderBytes.Length == 0) + if (desc.ShaderBytes.Length == 0) return null; ReflectedResourceInfo info = Reflect(ctx, compiledSPIRV); diff --git a/Prowl.Editor/Utilities/ShaderCompiler/ShaderParser.cs b/Prowl.Editor/Utilities/ShaderCompiler/ShaderParser.cs index 45f7b7df..dc83ae15 100644 --- a/Prowl.Editor/Utilities/ShaderCompiler/ShaderParser.cs +++ b/Prowl.Editor/Utilities/ShaderCompiler/ShaderParser.cs @@ -2,7 +2,6 @@ // Licensed under the MIT License. See the LICENSE file in the project root for details. using System.Text; -using System.Text.RegularExpressions; using Prowl.Runtime; using Prowl.Runtime.Utils; @@ -30,7 +29,7 @@ public enum ShaderToken Quote } - static Dictionary> symbolHandlers = new() + private static readonly Dictionary> s_symbolHandlers = new() { {'{', (ctx) => HandleSingleCharToken(ctx, ShaderToken.OpenCurlBrace)}, {'}', (ctx) => HandleSingleCharToken(ctx, ShaderToken.CloseCurlBrace)}, @@ -46,7 +45,7 @@ private static Tokenizer CreateTokenizer(string input) { return new( input.AsMemory(), - symbolHandlers, + s_symbolHandlers, "{}()=,".Contains, ShaderToken.Identifier, ShaderToken.None, @@ -61,13 +60,13 @@ public static bool ParseShader(string input, FileIncluder includer, out Runtime. Tokenizer tokenizer = CreateTokenizer(input); - string name = ""; + string name; List properties = []; ParsedPass? globalDefaults = null; List parsedPasses = []; - string? fallback = null; + // string? fallback = null; try { @@ -100,7 +99,7 @@ public static bool ParseShader(string input, FileIncluder includer, out Runtime. case "Fallback": tokenizer.MoveNext(); // Move to string - fallback = tokenizer.ParseQuotedStringValue(); + // fallback = tokenizer.ParseQuotedStringValue(); break; default: @@ -133,9 +132,10 @@ public static bool ParseShader(string input, FileIncluder includer, out Runtime. string sourceCode = sourceBuilder.ToString(); - if (!ParseProgramInfo(sourceCode, out EntryPoint[]? entrypoints, out (int, int)? shaderModel, out CompilationMessage? message)) + if (!ParseProgramInfo(sourceCode, out EntryPoint[] entrypoints, out (int, int)? shaderModel, out CompilationMessage? message)) { - LogCompilationError(message.Value.message, includer, message.Value.line, message.Value.column); + if (message is not null) + LogCompilationError(message.Value.message, includer, message.Value.line, message.Value.column); return false; } @@ -198,7 +198,7 @@ private static bool LogCompilationMessages(string shaderName, List> ParseKeywords(Tokenizer entrypointsList = []; - entrypoints = null; + entrypoints = []; shaderModel = null; message = null; @@ -755,7 +755,7 @@ void AddEntrypoint(ShaderStages stage, string name, string idType) { severity = LogSeverity.Error, line = lineNumber, - column = line.IndexOf("#pragma") + 7, + column = line.IndexOf("#pragma", StringComparison.InvariantCulture) + 7, message = ex.Message }; diff --git a/Prowl.Editor/Utilities/ShaderCompiler/UniformReflector.cs b/Prowl.Editor/Utilities/ShaderCompiler/UniformReflector.cs index 25c7f01c..cff92005 100644 --- a/Prowl.Editor/Utilities/ShaderCompiler/UniformReflector.cs +++ b/Prowl.Editor/Utilities/ShaderCompiler/UniformReflector.cs @@ -46,7 +46,7 @@ static ShaderUniform CreateStorageBuffer(Reflector reflector, ReflectedResource { uint binding = GetBinding(reflector, bufferResource.id); - var decoratedType = reflector.GetTypeHandle(bufferResource.type_id); + // var decoratedType = reflector.GetTypeHandle(bufferResource.type_id); if (reflector.HasDecoration(bufferResource.id, Decoration.NonWritable)) return new ShaderUniform(bufferResource.name, binding, ResourceKind.StructuredBufferReadOnly); diff --git a/Prowl.Editor/Utilities/ShaderCompiler/VertexInputReflector.cs b/Prowl.Editor/Utilities/ShaderCompiler/VertexInputReflector.cs index f4372c12..f7294f09 100644 --- a/Prowl.Editor/Utilities/ShaderCompiler/VertexInputReflector.cs +++ b/Prowl.Editor/Utilities/ShaderCompiler/VertexInputReflector.cs @@ -26,7 +26,7 @@ public static VertexInput[] GetStageInputs(Reflector reflector, Resources resour { ReflectedResource resource = resources.StageInputs[i]; - var typeInfo = reflector.GetTypeHandle(resource.type_id); + // var typeInfo = reflector.GetTypeHandle(resource.type_id); if (!ParseSemantic(resource.name, formatter, out VertexInput input)) throw new Exception($"Unknown semantic: {input.semantic}"); diff --git a/Prowl.Editor/Utilities/Texture2DLoader.cs b/Prowl.Editor/Utilities/Texture2DLoader.cs index 2e4737b6..e4e7c6d9 100644 --- a/Prowl.Editor/Utilities/Texture2DLoader.cs +++ b/Prowl.Editor/Utilities/Texture2DLoader.cs @@ -115,7 +115,7 @@ public static Texture2D FromFile(string file, bool generateMipmaps = fal { if (Path.GetExtension(file).Equals(".dds", StringComparison.OrdinalIgnoreCase)) { - var texture = SixLabors.ImageSharp.Textures.Texture.Load(file, out var format); + var texture = SixLabors.ImageSharp.Textures.Texture.Load(file, out _); if (texture is SixLabors.ImageSharp.Textures.TextureFormats.FlatTexture flat) { var i = flat.MipMaps[0].GetImage(); diff --git a/Prowl.Editor/Utilities/TreePath.cs b/Prowl.Editor/Utilities/TreePath.cs index 412885b8..fa189277 100644 --- a/Prowl.Editor/Utilities/TreePath.cs +++ b/Prowl.Editor/Utilities/TreePath.cs @@ -3,22 +3,22 @@ namespace Prowl.Editor; -public class TreePath +public class TreePath where T : notnull { - public TreePath Parent { get; set; } + public TreePath? Parent { get; set; } public string Name { get; set; } public T Data { get; set; } - public List> Children { get; } = new List>(); + public List> Children { get; } = []; public TreePath() { } - public TreePath(string name, T data = default) + public TreePath(string name, T data) { Name = name; Data = data; } - public void AddChild(string path, T data = default) + public void AddChild(string path, T data) { string[] parts = path.Split('/'); TreePath currentNode = this; @@ -26,7 +26,7 @@ public void AddChild(string path, T data = default) for (int i = 0; i < parts.Length - 1; i++) { string part = parts[i]; - TreePath childNode = currentNode.Children.Find(c => c.Name == part); + TreePath? childNode = currentNode.Children.Find(c => c.Name == part); if (childNode == null) { childNode = new TreePath { Name = part }; @@ -41,10 +41,10 @@ public void AddChild(string path, T data = default) currentNode.Children.Add(leafNode); } - public TreePath FindNode(string path) + public TreePath? FindNode(string path) { string[] parts = path.Split('/'); - TreePath currentNode = this; + TreePath? currentNode = this; foreach (string part in parts) { @@ -71,4 +71,4 @@ private void SearchRecursive(TreePath node, string query, List> r foreach (TreePath child in node.Children) SearchRecursive(child, query, results, ignoreCase); } -} \ No newline at end of file +} diff --git a/Prowl.Players/Prowl.Desktop/StandaloneAssetProvider.cs b/Prowl.Players/Prowl.Desktop/StandaloneAssetProvider.cs index 17c27e73..9352879e 100644 --- a/Prowl.Players/Prowl.Desktop/StandaloneAssetProvider.cs +++ b/Prowl.Players/Prowl.Desktop/StandaloneAssetProvider.cs @@ -27,45 +27,45 @@ public StandaloneAssetProvider() public AssetRef LoadAsset(string relativeAssetPath, ushort fileID = 0) where T : EngineObject { Guid guid = GetGuidFromPath(relativeAssetPath); - if (_loaded.ContainsKey(guid)) - return (T)(fileID == 0 ? _loaded[guid].Main : _loaded[guid].SubAssets[fileID - 1]); + if (_loaded.TryGetValue(guid, out SerializedAsset? value)) + return (T)(fileID == 0 ? value.Main : value.SubAssets[fileID - 1])!; foreach (AssetBundle package in packages) - if (package.TryGetAsset(relativeAssetPath, out var asset)) + if (package.TryGetAsset(relativeAssetPath, out var asset) && asset is not null) { _loaded[guid] = asset; - return (T)(fileID == 0 ? asset.Main : asset.SubAssets[fileID - 1]); + return (T)(fileID == 0 ? asset.Main : asset.SubAssets[fileID - 1])!; } throw new FileNotFoundException($"Asset with path {relativeAssetPath} not found."); } public AssetRef LoadAsset(Guid guid, ushort fileID = 0) where T : EngineObject { - if (_loaded.ContainsKey(guid)) - return (T)(fileID == 0 ? _loaded[guid].Main : _loaded[guid].SubAssets[fileID - 1]); + if (_loaded.TryGetValue(guid, out SerializedAsset? value)) + return (T)(fileID == 0 ? value.Main : value.SubAssets[fileID - 1])!; foreach (AssetBundle package in packages) - if (package.TryGetAsset(guid, out var asset)) + if (package.TryGetAsset(guid, out var asset) && asset is not null) { _loaded[guid] = asset; - return (T)(fileID == 0 ? asset.Main : asset.SubAssets[fileID - 1]); + return (T)(fileID == 0 ? asset.Main : asset.SubAssets[fileID - 1])!; } throw new FileNotFoundException($"Asset with GUID {guid} not found."); } - public AssetRef LoadAsset(IAssetRef assetID) where T : EngineObject + public AssetRef LoadAsset(IAssetRef? assetID) where T : EngineObject { - if (assetID == null) return null; + ArgumentNullException.ThrowIfNull(assetID); return LoadAsset(assetID.AssetID, assetID.FileID); } - public SerializedAsset? LoadAsset(Guid guid) + public SerializedAsset LoadAsset(Guid guid) { - if (_loaded.ContainsKey(guid)) - return _loaded[guid]; + if (_loaded.TryGetValue(guid, out SerializedAsset? loadAsset)) + return loadAsset; foreach (AssetBundle package in packages) - if (package.TryGetAsset(guid, out var asset)) + if (package.TryGetAsset(guid, out var asset) && asset is not null) { _loaded[guid] = asset; return asset; @@ -73,7 +73,7 @@ public AssetRef LoadAsset(IAssetRef assetID) where T : EngineObject throw new FileNotFoundException($"Asset with GUID {guid} not found."); } - public string GetPathFromGUID(Guid guid) + public string? GetPathFromGUID(Guid guid) { foreach (AssetBundle package in packages) if (package.TryGetPath(guid, out var path)) diff --git a/Prowl.Runtime/AnimationCurve.cs b/Prowl.Runtime/AnimationCurve.cs index adb60b66..f7168d83 100644 --- a/Prowl.Runtime/AnimationCurve.cs +++ b/Prowl.Runtime/AnimationCurve.cs @@ -4,6 +4,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace Prowl.Runtime; @@ -411,18 +412,18 @@ public KeyFrame(double position, double value, double tangentIn = 0, double tang if (Equals(value2, null)) return Equals(value1, null); - return (MathD.ApproximatelyEquals(value1.Position, value2.Position)) - && (MathD.ApproximatelyEquals(value1.Value, value2.Value)) - && (MathD.ApproximatelyEquals(value1.TangentIn, value2.TangentIn)) - && (MathD.ApproximatelyEquals(value1.TangentOut, value2.TangentOut)) + return (value1.Position == value2.Position) + && (value1.Value == value2.Value) + && (value1.TangentIn == value2.TangentIn) + && (value1.TangentOut == value2.TangentOut) && (value1.Continuity == value2.Continuity); } #region Inherited Methods - public int CompareTo(KeyFrame other) => Position.CompareTo(other.Position); - public bool Equals(KeyFrame other) => (this == other); - public override bool Equals(object obj) => (obj as KeyFrame) != null && Equals((KeyFrame)obj); + public int CompareTo([AllowNull] KeyFrame other) => Position.CompareTo(other.Position); + public bool Equals([AllowNull] KeyFrame other) => this == other; + public override bool Equals([AllowNull] object obj) => obj is KeyFrame keyFrame && Equals(keyFrame); public override int GetHashCode() => Position.GetHashCode() ^ Value.GetHashCode() ^ TangentIn.GetHashCode() ^ TangentOut.GetHashCode() ^ Continuity.GetHashCode(); diff --git a/Prowl.Runtime/Application.cs b/Prowl.Runtime/Application.cs index 56d7b82a..0f805c5b 100644 --- a/Prowl.Runtime/Application.cs +++ b/Prowl.Runtime/Application.cs @@ -42,7 +42,7 @@ public static class Application GraphicsBackend.OpenGLES, ]; - private static readonly GraphicsBackend[] s_preferredMacBackends = // Covers MacOS/Apple + private static readonly GraphicsBackend[] s_preferredMacBackends = // Covers macOS/Apple [ GraphicsBackend.Metal, GraphicsBackend.OpenGL, @@ -77,9 +77,9 @@ public static void Run(string title, int width, int height, IAssetProvider asset Screen.Closing += AppClose; IsRunning = true; - IsPlaying = true; // Base application is not the editor, isplaying is always true + IsPlaying = true; // Base application is not the editor, IsPlaying is always true - Screen.Start($"{title} - {GetBackend()}", new Vector2Int(width, height), new Vector2Int(100, 100), WindowState.Normal); + Screen.Start($"{title} - {GetBackend()}", new Vector2Int(width, height), new Vector2Int(100, 100)); } static void AppInitialize() @@ -88,7 +88,7 @@ static void AppInitialize() SceneManager.Initialize(); AudioSystem.Initialize(); - AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; AssemblyManager.Initialize(); @@ -121,7 +121,7 @@ static void AppUpdate() static void AppClose() { IsRunning = false; - Quitting?.Invoke(); + Quitting.Invoke(); Graphics.Dispose(); Physics.Dispose(); AudioSystem.Dispose(); diff --git a/Prowl.Runtime/AssetRef.cs b/Prowl.Runtime/AssetRef.cs index 5c6a3094..d29090bb 100644 --- a/Prowl.Runtime/AssetRef.cs +++ b/Prowl.Runtime/AssetRef.cs @@ -28,8 +28,8 @@ public T? Res } set { - assetID = value == null ? Guid.Empty : value.AssetID; - fileID = value == null ? (ushort)0 : value.FileID; + assetID = value?.AssetID ?? Guid.Empty; + fileID = value?.FileID ?? 0; instance = value; } } @@ -85,7 +85,7 @@ public bool IsAvailable { get { - if (instance != null && !instance.IsDestroyed) return true; + if (instance is { IsDestroyed: false }) return true; RetrieveInstance(); return instance != null; } @@ -139,6 +139,7 @@ public AssetRef(Guid id) /// the specified alias. /// /// + /// public AssetRef(Guid id, ushort fileId) { instance = null; @@ -152,8 +153,8 @@ public AssetRef(Guid id, ushort fileId) public AssetRef(T? res) { instance = res; - assetID = res != null ? res.AssetID : Guid.Empty; - fileID = res != null ? res.FileID : (ushort)0; + assetID = res?.AssetID ?? Guid.Empty; + fileID = res?.FileID ?? 0; } public object? GetInstance() @@ -212,7 +213,7 @@ public override string ToString() else stateChar = '_'; - return string.Format("[{2}] {0}", resType.Name, stateChar); + return string.Format("[{1}] {0}", resType.Name, stateChar); } public override bool Equals(object? obj) diff --git a/Prowl.Runtime/Audio/AudioSystem.cs b/Prowl.Runtime/Audio/AudioSystem.cs index 24c1d867..e3748205 100644 --- a/Prowl.Runtime/Audio/AudioSystem.cs +++ b/Prowl.Runtime/Audio/AudioSystem.cs @@ -18,9 +18,9 @@ public static class AudioSystem private static readonly List _active = []; private static readonly List _pool = []; - private static AudioListener _listener; + private static AudioListener? s_listener; - public static AudioListener Listener => _listener; + public static AudioListener Listener => s_listener; public static AudioEngine Engine => _engine; @@ -75,17 +75,17 @@ public static void UpdatePool() public static void RegisterListener(AudioListener audioListener) { - if (_listener != null) + if (s_listener != null) { Debug.LogWarning("Audio listener already registered, only the first in the scene will work as intended! Please destroy that one first before instantiating a new Listener."); return; } - _listener = audioListener; + s_listener = audioListener; } public static void UnregisterListener(AudioListener audioListener) { - _listener = null; + s_listener = null; } public static AudioBuffer GetAudioBuffer(AudioClip clip) diff --git a/Prowl.Runtime/Audio/OpenAL/OpenALActiveAudio.cs b/Prowl.Runtime/Audio/OpenAL/OpenALActiveAudio.cs index 2665c1ff..1635e4e7 100644 --- a/Prowl.Runtime/Audio/OpenAL/OpenALActiveAudio.cs +++ b/Prowl.Runtime/Audio/OpenAL/OpenALActiveAudio.cs @@ -83,7 +83,7 @@ public override Vector3 Position set { System.Numerics.Vector3 vec3 = value; - OpenALEngine.al.SetSourceProperty(ID, SourceVector3.Position, ref vec3); + OpenALEngine.al.SetSourceProperty(ID, SourceVector3.Position, in vec3); } } @@ -97,7 +97,7 @@ public override Vector3 Direction set { System.Numerics.Vector3 vec3 = value; - OpenALEngine.al.SetSourceProperty(ID, SourceVector3.Direction, ref vec3); + OpenALEngine.al.SetSourceProperty(ID, SourceVector3.Direction, in vec3); } } diff --git a/Prowl.Runtime/Components/Audio/AudioSource.cs b/Prowl.Runtime/Components/Audio/AudioSource.cs index 4a0149fd..f1b4fe0e 100644 --- a/Prowl.Runtime/Components/Audio/AudioSource.cs +++ b/Prowl.Runtime/Components/Audio/AudioSource.cs @@ -19,7 +19,7 @@ public sealed class AudioSource : MonoBehaviour private ActiveAudio _source; private AudioBuffer _buffer; - private uint _lastVersion; + // private uint _lastVersion; private bool _looping = false; private float _gain = 1f; private float _maxDistance = 32f; diff --git a/Prowl.Runtime/Components/MeshRenderer.cs b/Prowl.Runtime/Components/MeshRenderer.cs index ac140106..9c2320d7 100644 --- a/Prowl.Runtime/Components/MeshRenderer.cs +++ b/Prowl.Runtime/Components/MeshRenderer.cs @@ -74,7 +74,7 @@ public Material GetMaterial() public void GetRenderingData(out PropertyBlock properties, out IGeometryDrawData drawData, out Matrix4x4 model) { - drawData = Mesh.Res; + drawData = Mesh.Res ?? throw new System.ArgumentNullException(nameof(Mesh)); properties = Properties; model = Transform.localToWorldMatrix; } diff --git a/Prowl.Runtime/Components/Navmesh/NavMeshSurface.cs b/Prowl.Runtime/Components/Navmesh/NavMeshSurface.cs index a28e3966..ee243e10 100644 --- a/Prowl.Runtime/Components/Navmesh/NavMeshSurface.cs +++ b/Prowl.Runtime/Components/Navmesh/NavMeshSurface.cs @@ -63,7 +63,7 @@ public DtNavMeshQuery? Query private Bounds debug_bounds; private Vector3[][][] debug_polygons; - private float timer = 0; + // private float timer = 0; #endregion @@ -410,11 +410,11 @@ public RcVec3f CalcVel(RcVec3f pos, RcVec3f tgt, float speed) class SceneMeshData { - public class MeshData - { - public List vertices; - public List indices; - } + // public class MeshData + // { + // public List vertices; + // public List indices; + // } public readonly List shapeData = new(); public readonly List transformsOut = new(); diff --git a/Prowl.Runtime/Components/Physics/CharacterController.cs b/Prowl.Runtime/Components/Physics/CharacterController.cs index 2b102d3d..9262a22c 100644 --- a/Prowl.Runtime/Components/Physics/CharacterController.cs +++ b/Prowl.Runtime/Components/Physics/CharacterController.cs @@ -33,7 +33,7 @@ public override bool Kinematic protected override void RigidbodyAttached() { - ref var character = ref Physics.Characters.AllocateCharacter(BodyReference.Value.Handle); + ref var character = ref Physics.Characters.AllocateCharacter(BodyReference!.Value.Handle); character.LocalUp = new Vector3(0, 1, 0); character.JumpVelocity = jumpVelocity; character.MaximumVerticalForce = maxVerticalForce; @@ -49,12 +49,12 @@ protected override void RigidbodyAttached() protected override void RigidbodyDetached() { - Physics.Characters.RemoveCharacterByBodyHandle(BodyReference.Value.Handle); + Physics.Characters.RemoveCharacterByBodyHandle(BodyReference!.Value.Handle); } public override void Update() { - ref var character = ref Physics.Characters.GetCharacterByBodyHandle(BodyReference.Value.Handle); + ref var character = ref Physics.Characters.GetCharacterByBodyHandle(BodyReference!.Value.Handle); character.CosMaximumSlope = MathF.Cos(maxSlope.ToRad()); character.JumpVelocity = jumpVelocity; @@ -75,5 +75,5 @@ public override void Update() BodyReference.Value.LocalInertia = new BodyInertia { InverseMass = 1f / Mass }; } - public void TryJump() => Physics.Characters.GetCharacterByBodyHandle(BodyReference.Value.Handle).TryJump = true; + public void TryJump() => Physics.Characters.GetCharacterByBodyHandle(BodyReference!.Value.Handle).TryJump = true; } diff --git a/Prowl.Runtime/Components/Physics/Constraints/_ConstraintComponentBase.cs b/Prowl.Runtime/Components/Physics/Constraints/_ConstraintComponentBase.cs index 3da64fe0..9a2e5309 100644 --- a/Prowl.Runtime/Components/Physics/Constraints/_ConstraintComponentBase.cs +++ b/Prowl.Runtime/Components/Physics/Constraints/_ConstraintComponentBase.cs @@ -95,7 +95,7 @@ internal override void RebuildConstraint() int count = 0; foreach (var component in _constraintComponent.Bodies) - bodies[count++] = component.BodyReference.Value.Handle; + bodies[count++] = component.BodyReference!.Value.Handle; Span validBodies = bodies[..count]; diff --git a/Prowl.Runtime/Components/Physics/Rigidbody.cs b/Prowl.Runtime/Components/Physics/Rigidbody.cs index e262b0ed..8b16c662 100644 --- a/Prowl.Runtime/Components/Physics/Rigidbody.cs +++ b/Prowl.Runtime/Components/Physics/Rigidbody.cs @@ -104,7 +104,7 @@ public ContinuousDetectionMode ContinuousDetectionMode } } - public bool Awake + public new bool Awake { get => BodyReference?.Awake ?? false; set diff --git a/Prowl.Runtime/Components/SkinnedMeshRenderer.cs b/Prowl.Runtime/Components/SkinnedMeshRenderer.cs index 4727ffec..fdfb6e23 100644 --- a/Prowl.Runtime/Components/SkinnedMeshRenderer.cs +++ b/Prowl.Runtime/Components/SkinnedMeshRenderer.cs @@ -78,6 +78,6 @@ public void Deserialize(SerializedProperty value, Serializer.SerializationContex { Mesh = Serializer.Deserialize>(value["Mesh"], ctx); Material = Serializer.Deserialize>(value["Material"], ctx); - Bones = Serializer.Deserialize(value["Bones"], ctx); + Bones = Serializer.Deserialize(value["Bones"], ctx) ?? []; } } diff --git a/Prowl.Runtime/Components/UI/GUICanvas.cs b/Prowl.Runtime/Components/UI/GUICanvas.cs index 871ee70e..d998a310 100644 --- a/Prowl.Runtime/Components/UI/GUICanvas.cs +++ b/Prowl.Runtime/Components/UI/GUICanvas.cs @@ -22,13 +22,15 @@ public enum Space { Screen } public override void Awake() { - TargetCamera = GetComponent(); - if (TargetCamera == null) + var targetCamera = GetComponent(); + if (targetCamera == null) { Debug.LogError("Target Camera is not set on GUICanvas."); return; } + TargetCamera = targetCamera; + gui = new Gui(DoAntiAliasing); //if (space == Space.Screen) diff --git a/Prowl.Runtime/EngineObject.cs b/Prowl.Runtime/EngineObject.cs index 451bccd5..adca636d 100644 --- a/Prowl.Runtime/EngineObject.cs +++ b/Prowl.Runtime/EngineObject.cs @@ -57,7 +57,7 @@ public virtual void OnValidate() { } return null; } - public static T?[] FindObjectsOfType() where T : EngineObject + public static T[] FindObjectsOfType() where T : EngineObject { List objects = new(); foreach (var obj in allObjects) @@ -130,6 +130,7 @@ public static EngineObject Instantiate(EngineObject obj, bool keepAssetID = fals /// Force the object to dispose immediately /// You are advised to not use this! Use Destroy() Instead. /// + /// TODO: FIXME: replacing GameObject and EngineObject calls crashes the app [Obsolete("You are advised to not use this! Use Destroy() Instead.")] public void Dispose() { diff --git a/Prowl.Runtime/GUI/Graphics/UIDrawListRenderer.cs b/Prowl.Runtime/GUI/Graphics/UIDrawListRenderer.cs index 21571dfa..ed5ff7d7 100644 --- a/Prowl.Runtime/GUI/Graphics/UIDrawListRenderer.cs +++ b/Prowl.Runtime/GUI/Graphics/UIDrawListRenderer.cs @@ -19,7 +19,7 @@ public enum ColorSpaceHandling public static class UIDrawListRenderer { - private static readonly Assembly s_assembly = Assembly.GetAssembly(typeof(UIDrawListRenderer)); + private static readonly Assembly s_assembly = Assembly.GetAssembly(typeof(UIDrawListRenderer)) ?? throw new NullReferenceException(); private static ColorSpaceHandling s_handling; // Device objects diff --git a/Prowl.Runtime/GUI/Gui.State.cs b/Prowl.Runtime/GUI/Gui.State.cs index 309f3b9b..d7996737 100644 --- a/Prowl.Runtime/GUI/Gui.State.cs +++ b/Prowl.Runtime/GUI/Gui.State.cs @@ -12,7 +12,7 @@ public partial class Gui { public int CurrentZIndex => CurrentNode.ZIndex; - private static readonly Dictionary _storage = []; + private static readonly Dictionary s_storage = []; /// /// Set the ZIndex for the current node @@ -37,11 +37,11 @@ public void SetZIndex(int index, bool keepClipSpace = false) /// Get a value from the current node's storage public T GetNodeStorage(LayoutNode node, string key, T defaultValue = default) where T : unmanaged { - if (!_storage.TryGetValue(node.ID, out var storage)) + if (!s_storage.TryGetValue(node.ID, out var storage)) return defaultValue; - if (storage.ContainsKey(key)) - return (T)storage[key]; + if (storage.ContainsKey(key) && storage[key] is T value) + return value; return defaultValue; } @@ -51,8 +51,8 @@ public T GetNodeStorage(LayoutNode node, string key, T defaultValue = default /// Set a value in the current node's storage public void SetNodeStorage(LayoutNode node, string key, T value) where T : unmanaged { - if (!_storage.TryGetValue(node.ID, out var storage)) - _storage[node.ID] = storage = []; + if (!s_storage.TryGetValue(node.ID, out var storage)) + s_storage[node.ID] = storage = []; storage[key] = value; } @@ -60,7 +60,7 @@ public void SetNodeStorage(LayoutNode node, string key, T value) where T : un /// /// Push an ID onto the ID stack. /// Useful for when you want to use the same string ID for multiple nodes that would otherwise conflict. - /// Or maybe you dont have control like a List of User-Created Nodes, you PushID(Index) and PopID() when done + /// Or maybe you don't have control like a List of User-Created Nodes, you PushID(Index) and PopID() when done /// /// public void PushID(ulong id) => IDStack.Push(id); diff --git a/Prowl.Runtime/GUI/Layout/Spacing.cs b/Prowl.Runtime/GUI/Layout/Spacing.cs index f6d9ab80..7cac1963 100644 --- a/Prowl.Runtime/GUI/Layout/Spacing.cs +++ b/Prowl.Runtime/GUI/Layout/Spacing.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. See the LICENSE file in the project root for details. using System; +using System.Diagnostics.CodeAnalysis; namespace Prowl.Runtime.GUI; @@ -31,22 +32,29 @@ public Spacing(double left, double right, double top, double bottom) public static bool operator ==(Spacing s1, Spacing s2) { - return MathD.ApproximatelyEquals(s1.Left, s2.Left) && - MathD.ApproximatelyEquals(s1.Right, s2.Right) && - MathD.ApproximatelyEquals(s1.Top, s2.Top) && - MathD.ApproximatelyEquals(s1.Bottom, s2.Bottom); + return s1.Equals(s2); } public static bool operator !=(Spacing s1, Spacing s2) { - return MathD.ApproximatelyEquals(s1.Left , s2.Left) || - MathD.ApproximatelyEquals(s1.Right , s2.Right) || - MathD.ApproximatelyEquals(s1.Top , s2.Top) || - MathD.ApproximatelyEquals(s1.Bottom , s2.Bottom); + return !s1.Equals(s2); } - public override bool Equals(object obj) + public override bool Equals([AllowNull] object obj) { - throw new System.NotImplementedException(); + return obj is Spacing spacing && Equals(spacing); + } + + public readonly bool Equals(Spacing other) + { + return Left == other.Left && + Right == other.Right && + Top == other.Top && + Bottom == other.Bottom; + } + + public override int GetHashCode() + { + return HashCode.Combine(Left, Right, Top, Bottom); } } diff --git a/Prowl.Runtime/GUI/TextEdit/StbTextEdit.cs b/Prowl.Runtime/GUI/TextEdit/StbTextEdit.cs index 35897c4e..50496102 100644 --- a/Prowl.Runtime/GUI/TextEdit/StbTextEdit.cs +++ b/Prowl.Runtime/GUI/TextEdit/StbTextEdit.cs @@ -22,7 +22,8 @@ public TextEditRow LayoutRow(int startIndex) r.baseline_y_delta = (float)size.y; r.ymin = 0.0f; r.ymax = (float)size.y; - r.num_chars = text_remaining.Value - startIndex; + if (text_remaining is not null) + r.num_chars = text_remaining.Value - startIndex; return r; } diff --git a/Prowl.Runtime/GUI/Widgets/Gizmo/TransformGizmo.cs b/Prowl.Runtime/GUI/Widgets/Gizmo/TransformGizmo.cs index d31bd937..0a0aa5dd 100644 --- a/Prowl.Runtime/GUI/Widgets/Gizmo/TransformGizmo.cs +++ b/Prowl.Runtime/GUI/Widgets/Gizmo/TransformGizmo.cs @@ -107,7 +107,7 @@ public enum GizmoOrientation { Global, Local } internal Matrix4x4 ViewProjection; internal Matrix4x4 Model; internal Matrix4x4 ModelViewProjection; - internal Matrix4x4 InverseModelViewProjection; + // internal Matrix4x4 InverseModelViewProjection; private readonly List _subGizmos = []; internal Gui _gui; diff --git a/Prowl.Runtime/GUI/Widgets/Gizmo/ViewManipulatorGizmo.cs b/Prowl.Runtime/GUI/Widgets/Gizmo/ViewManipulatorGizmo.cs index db1de196..17d3e935 100644 --- a/Prowl.Runtime/GUI/Widgets/Gizmo/ViewManipulatorGizmo.cs +++ b/Prowl.Runtime/GUI/Widgets/Gizmo/ViewManipulatorGizmo.cs @@ -11,7 +11,7 @@ public class ViewManipulatorGizmo private readonly Gui _gui; private Rect _gizmoRect; - private Matrix4x4 _view; + // private Matrix4x4 _view; private Vector3 camForward; private Vector3 camUp; private bool _orthographic; diff --git a/Prowl.Runtime/GUI/Widgets/Gui.InputField.cs b/Prowl.Runtime/GUI/Widgets/Gui.InputField.cs index 6baa9607..82df3ecd 100644 --- a/Prowl.Runtime/GUI/Widgets/Gui.InputField.cs +++ b/Prowl.Runtime/GUI/Widgets/Gui.InputField.cs @@ -130,50 +130,52 @@ static int ImStrbolW(string data, int bufMidLine, int bufBegin) private static StbTextEditState stb; - internal static bool OnProcess(WidgetStyle style, Interactable interact, ref string Text, uint MaxLength, InputFieldFlags Flags) + internal static bool OnProcess(WidgetStyle style, Interactable interact, ref string text, uint maxLength, InputFieldFlags Flags) { var g = ActiveGUI; - var font = style.Font.IsAvailable ? style.Font.Res : Font.DefaultFont; + var font = style.Font is { IsAvailable: true, Res: not null } ? style.Font.Res : Font.DefaultFont; var fontsize = style.FontSize; - var render_pos = new Vector2(g.CurrentNode.LayoutData.InnerRect.x, g.CurrentNode.LayoutData.InnerRect.y); + var renderPos = new Vector2(g.CurrentNode.LayoutData.InnerRect.x, g.CurrentNode.LayoutData.InnerRect.y); // Center text vertically //render_pos.y += (g.CurrentNode.LayoutData.InnerRect.height - fontsize) / 2; - render_pos.y += 3; - render_pos.x += 5; + renderPos.y += 3; + renderPos.x += 5; bool justSelected = false; - if (stb == null || stb.ID != interact.ID) + if (stb.ID != interact.ID) { justSelected = true; - stb = new(); - stb.ID = interact.ID; - stb.SingleLine = !((Flags & InputFieldFlags.Multiline) == InputFieldFlags.Multiline); - stb.font = font; - stb.Text = Text; + stb = new StbTextEditState + { + ID = interact.ID, + SingleLine = (Flags & InputFieldFlags.Multiline) != InputFieldFlags.Multiline, + font = font, + Text = text + }; } - HandleKeyEvent(stb, MaxLength, Flags); + HandleKeyEvent(stb, maxLength, Flags); HandleMouseEvent(stb); if (justSelected && (Flags & InputFieldFlags.AutoSelectAll) == InputFieldFlags.AutoSelectAll) { stb.SelectStart = 0; - stb.SelectEnd = Text.Length; + stb.SelectEnd = text.Length; } if (g.IsNodeHovered() && g.IsPointerDoubleClick(MouseButton.Left)) { stb.SelectStart = 0; - stb.SelectEnd = Text.Length; + stb.SelectEnd = text.Length; } //g.DrawText(font, Text, fontsize, render_pos, Color.black); // Render - Rect clip_rect = g.CurrentNode.LayoutData.InnerRect; - Vector2 text_size = new Vector2(0f, 0f); + Rect clipRect = g.CurrentNode.LayoutData.InnerRect; + // Vector2 textSize = new Vector2(0f, 0f); stb.cursorAnim += Time.deltaTimeF; - bool is_multiline = !stb.SingleLine; + bool isMultiline = !stb.SingleLine; Vector2 size = new Vector2(g.CurrentNode.LayoutData.InnerRect.width, g.CurrentNode.LayoutData.InnerRect.height); // We need to: @@ -181,33 +183,33 @@ internal static bool OnProcess(WidgetStyle style, Interactable interact, ref str // - Handle scrolling, highlight selection, display cursor (those all requires some form of 1d.2d cursor position calculation) // - Measure text height (for scrollbar) // We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort) - int text_begin = 0; - Vector2 cursor_offset = Vector2.zero, select_start_offset = Vector2.zero; + int textBegin = 0; + Vector2 cursorOffset = Vector2.zero, select_start_offset = Vector2.zero; { // Count lines + find lines numbers straddling 'cursor' and 'select_start' position. - int[] searches_input_ptr = new int[2]; - searches_input_ptr[0] = text_begin + stb.CursorIndex; - searches_input_ptr[1] = -1; + int[] searchesInputPtr = new int[2]; + searchesInputPtr[0] = textBegin + stb.CursorIndex; + searchesInputPtr[1] = -1; int searches_remaining = 1; int[] searches_result_line_number = [-1, -999]; if (stb.SelectStart != stb.SelectEnd) { - searches_input_ptr[1] = text_begin + MathD.Min(stb.SelectStart, stb.SelectEnd); + searchesInputPtr[1] = textBegin + MathD.Min(stb.SelectStart, stb.SelectEnd); searches_result_line_number[1] = -1; searches_remaining++; } // Iterate all lines to find our line numbers // In multi-line mode, we never exit the loop until all lines are counted, so add one extra to the searches_remaining counter. - searches_remaining += is_multiline ? 1 : 0; + searches_remaining += isMultiline ? 1 : 0; int line_count = 0; - for (int s = text_begin; s < stb.Text.Length && stb.Text[s] != 0; s++) + for (int s = textBegin; s < stb.Text.Length && stb.Text[s] != 0; s++) if (stb.Text[s] == '\n') { line_count++; - if (searches_result_line_number[0] == -1 && s >= searches_input_ptr[0]) { searches_result_line_number[0] = line_count; if (--searches_remaining <= 0) break; } - if (searches_result_line_number[1] == -1 && s >= searches_input_ptr[1]) { searches_result_line_number[1] = line_count; if (--searches_remaining <= 0) break; } + if (searches_result_line_number[0] == -1 && s >= searchesInputPtr[0]) { searches_result_line_number[0] = line_count; if (--searches_remaining <= 0) break; } + if (searches_result_line_number[1] == -1 && s >= searchesInputPtr[1]) { searches_result_line_number[1] = line_count; if (--searches_remaining <= 0) break; } } line_count++; if (searches_result_line_number[0] == -1) searches_result_line_number[0] = line_count; @@ -216,17 +218,18 @@ internal static bool OnProcess(WidgetStyle style, Interactable interact, ref str int? remaining = null; Vector2? out_offset = null; // Calculate 2d position by finding the beginning of the line and measuring distance - cursor_offset.x = font.InputTextCalcTextSizeW(stb.Text, ImStrbolW(stb.Text, searches_input_ptr[0], text_begin), searches_input_ptr[0], ref remaining, ref out_offset).x; - cursor_offset.y = searches_result_line_number[0] * fontsize; + cursorOffset.x = font.InputTextCalcTextSizeW(stb.Text, ImStrbolW(stb.Text, searchesInputPtr[0], textBegin), searchesInputPtr[0], ref remaining, ref out_offset).x; + cursorOffset.y = searches_result_line_number[0] * fontsize; if (searches_result_line_number[1] >= 0) { - select_start_offset.x = font.InputTextCalcTextSizeW(stb.Text, ImStrbolW(stb.Text, searches_input_ptr[1], text_begin), searches_input_ptr[1], ref remaining, ref out_offset).x; + select_start_offset.x = font.InputTextCalcTextSizeW(stb.Text, ImStrbolW(stb.Text, searchesInputPtr[1], textBegin), searchesInputPtr[1], ref remaining, ref out_offset).x; select_start_offset.y = searches_result_line_number[1] * fontsize; } + // TODO: commented textSize because its' never used // Calculate text height - if (is_multiline) - text_size = new Vector2(size.x, line_count * fontsize); + // if (isMultiline) + // textSize = new Vector2(size.x, line_count * fontsize); } // Scroll @@ -236,10 +239,10 @@ internal static bool OnProcess(WidgetStyle style, Interactable interact, ref str if ((Flags & InputFieldFlags.NoHorizontalScroll) == 0) { double scroll_increment_x = size.x * 0.25f; - if (cursor_offset.x < stb.ScrollX) - stb.ScrollX = (int)MathD.Max(0.0f, cursor_offset.x - scroll_increment_x); - else if (cursor_offset.x - size.x >= stb.ScrollX) - stb.ScrollX = (int)(cursor_offset.x - size.x + scroll_increment_x); + if (cursorOffset.x < stb.ScrollX) + stb.ScrollX = (int)MathD.Max(0.0f, cursorOffset.x - scroll_increment_x); + else if (cursorOffset.x - size.x >= stb.ScrollX) + stb.ScrollX = (int)(cursorOffset.x - size.x + scroll_increment_x); } else { @@ -247,71 +250,71 @@ internal static bool OnProcess(WidgetStyle style, Interactable interact, ref str } // Vertical scroll - if (is_multiline) + if (isMultiline) { double scroll_y = g.CurrentNode.VScroll; - if (cursor_offset.y - fontsize < scroll_y) - scroll_y = MathD.Max(0.0f, cursor_offset.y - fontsize); - else if (cursor_offset.y - size.y >= scroll_y) - scroll_y = cursor_offset.y - size.y; + if (cursorOffset.y - fontsize < scroll_y) + scroll_y = MathD.Max(0.0f, cursorOffset.y - fontsize); + else if (cursorOffset.y - size.y >= scroll_y) + scroll_y = cursorOffset.y - size.y; g.SetNodeStorage("VScroll", scroll_y); } } stb.CursorFollow = false; - if (is_multiline) - render_pos.y -= g.CurrentNode.VScroll; + if (isMultiline) + renderPos.y -= g.CurrentNode.VScroll; Vector2 render_scroll = new Vector2(stb.ScrollX, 0.0f); if ((Flags & InputFieldFlags.OnlyDisplay) == InputFieldFlags.OnlyDisplay) { Color32 colb = style.TextColor; - g.Draw2D.DrawList.AddText(font, fontsize, render_pos - render_scroll, colb, stb.Text, 0, stb.Text.Length, 0.0f, (is_multiline ? null : (Vector4?)clip_rect)); + g.Draw2D.DrawList.AddText(font, fontsize, renderPos - render_scroll, colb, stb.Text, 0, stb.Text.Length, 0.0f, (isMultiline ? null : (Vector4?)clipRect)); return false; } // Draw selection if (stb.SelectStart != stb.SelectEnd) { - int text_selected_begin = text_begin + MathD.Min(stb.SelectStart, stb.SelectEnd); - int text_selected_end = text_begin + MathD.Max(stb.SelectStart, stb.SelectEnd); + int text_selected_begin = textBegin + MathD.Min(stb.SelectStart, stb.SelectEnd); + int text_selected_end = textBegin + MathD.Max(stb.SelectStart, stb.SelectEnd); - float bg_offy_up = is_multiline ? 0.0f : -1.0f; // FIXME: those offsets should be part of the style? they don't play so well with multi-line selection. - float bg_offy_dn = is_multiline ? 0.0f : 2.0f; + float bg_offy_up = isMultiline ? 0.0f : -1.0f; // FIXME: those offsets should be part of the style? they don't play so well with multi-line selection. + float bg_offy_dn = isMultiline ? 0.0f : 2.0f; Color32 bg_color = style.ActiveColor; - Vector2 rect_pos = render_pos + select_start_offset - render_scroll; + Vector2 rect_pos = renderPos + select_start_offset - render_scroll; for (int p = text_selected_begin; p < text_selected_end;) { - if (rect_pos.y > clip_rect.y + clip_rect.height + fontsize) + if (rect_pos.y > clipRect.y + clipRect.height + fontsize) break; - if (rect_pos.y < clip_rect.y) + if (rect_pos.y < clipRect.y) { while (p < text_selected_end) - if (Text[p++] == '\n') //TODO: what should we access here? + if (text[p++] == '\n') //TODO: what should we access here? break; } else { var temp = (int?)p; Vector2? out_offset = null; - Vector2 rect_size = font.InputTextCalcTextSizeW(Text, p, text_selected_end, ref temp, ref out_offset, true); p = temp.Value; + Vector2 rect_size = font.InputTextCalcTextSizeW(text, p, text_selected_end, ref temp, ref out_offset, true); p = temp!.Value; if (rect_size.x <= 0.0f) rect_size.x = (int)(font.GetCharAdvance(' ') * 0.50f); // So we can see selected empty lines Rect rect = new Rect(rect_pos + new Vector2(0.0f, bg_offy_up - fontsize), new Vector2(rect_size.x, bg_offy_dn + fontsize)); - rect.Clip(clip_rect); - if (rect.Overlaps(clip_rect)) + rect.Clip(clipRect); + if (rect.Overlaps(clipRect)) g.Draw2D.DrawList.AddRectFilled(rect.Min, rect.Max, bg_color); } - rect_pos.x = render_pos.x - render_scroll.x; + rect_pos.x = renderPos.x - render_scroll.x; rect_pos.y += fontsize; } } Color32 col = style.TextColor; - g.Draw2D.DrawList.AddText(font, fontsize, render_pos - render_scroll, col, stb.Text, 0, stb.Text.Length, 0.0f, (is_multiline ? null : (Vector4?)clip_rect)); + g.Draw2D.DrawList.AddText(font, fontsize, renderPos - render_scroll, col, stb.Text, 0, stb.Text.Length, 0.0f, (isMultiline ? null : (Vector4?)clipRect)); //g.DrawText(font, fontsize, Text, render_pos - render_scroll, Color.black, 0, stb.CurLenA, 0.0f, (is_multiline ? null : (ImVec4?)clip_rect)); // Draw blinking cursor - Vector2 cursor_screen_pos = render_pos + cursor_offset - render_scroll; + Vector2 cursor_screen_pos = renderPos + cursorOffset - render_scroll; bool cursor_is_visible = (stb.cursorAnim <= 0.0f) || (stb.cursorAnim % 1.20f) <= 0.80f; if (cursor_is_visible) g.Draw2D.DrawList.AddLine(cursor_screen_pos + new Vector2(0.0f, -fontsize - 4f), cursor_screen_pos + new Vector2(0.0f, -5f), col); @@ -319,7 +322,7 @@ internal static bool OnProcess(WidgetStyle style, Interactable interact, ref str if ((Flags & InputFieldFlags.EnterReturnsTrue) == InputFieldFlags.EnterReturnsTrue) { - Text = stb.Text; + text = stb.Text; if (g.IsKeyPressed(Key.Return)) { g.FocusID = 0; @@ -329,12 +332,12 @@ internal static bool OnProcess(WidgetStyle style, Interactable interact, ref str } else { - if (!is_multiline && g.IsKeyPressed(Key.Return)) + if (!isMultiline && g.IsKeyPressed(Key.Return)) g.FocusID = 0; - var oldText = Text; - Text = stb.Text; - return oldText != Text; + var oldText = text; + text = stb.Text; + return oldText != text; } } diff --git a/Prowl.Runtime/GameObject/GameObject.cs b/Prowl.Runtime/GameObject/GameObject.cs index 67c348c0..0b6fa90e 100644 --- a/Prowl.Runtime/GameObject/GameObject.cs +++ b/Prowl.Runtime/GameObject/GameObject.cs @@ -662,7 +662,7 @@ public void Deserialize(SerializedProperty value, Serializer.SerializationContex layerIndex = value["LayerIndex"].ByteValue; hideFlags = (HideFlags)value["HideFlags"].IntValue; - _transform = Serializer.Deserialize(value["Transform"], ctx); + _transform = Serializer.Deserialize(value["Transform"], ctx) ?? new Transform(); _transform.gameObject = this; if (value.TryGet("AssetID", out var guid)) @@ -670,9 +670,9 @@ public void Deserialize(SerializedProperty value, Serializer.SerializationContex if (value.TryGet("FileID", out var fileID)) FileID = fileID.UShortValue; - var children = value["Children"]; + var children2 = value["Children"]; this.children = new(); - foreach (var childTag in children.List) + foreach (var childTag in children2.List) { GameObject? child = Serializer.Deserialize(childTag, ctx); if (child == null) continue; diff --git a/Prowl.Runtime/GameObject/MonoBehaviour.cs b/Prowl.Runtime/GameObject/MonoBehaviour.cs index bef2d9ab..13623ddb 100644 --- a/Prowl.Runtime/GameObject/MonoBehaviour.cs +++ b/Prowl.Runtime/GameObject/MonoBehaviour.cs @@ -65,7 +65,7 @@ public MonoBehaviour() : base() { } public void RemoveSelf() => GameObject.RemoveComponent(this); public T? GetComponent() where T : MonoBehaviour => GameObject.GetComponent(); public MonoBehaviour? GetComponent(Type type) => GameObject.GetComponent(type); - public bool TryGetComponent(out T component) where T : MonoBehaviour => (component = GetComponent()) != null; + public bool TryGetComponent(out T? component) where T : MonoBehaviour => (component = GetComponent()) != null; public IEnumerable GetComponents() where T : MonoBehaviour => GameObject.GetComponents(); public IEnumerable GetComponents(Type type) => GameObject.GetComponents(type); public T? GetComponentInParent(bool includeSelf = true) where T : MonoBehaviour => GameObject.GetComponentInParent(includeSelf); diff --git a/Prowl.Runtime/Physics.cs b/Prowl.Runtime/Physics.cs index 4b9cd843..ec625aa5 100644 --- a/Prowl.Runtime/Physics.cs +++ b/Prowl.Runtime/Physics.cs @@ -61,11 +61,7 @@ public static PhysicsBody GetContainer(CollidableReference collidable) { return GetContainer(collidable.StaticHandle); } - else - { - return GetContainer(collidable.BodyHandle); - } - return null; + return GetContainer(collidable.BodyHandle); } public static Rigidbody GetContainer(BodyHandle handle) diff --git a/Prowl.Runtime/Rendering/RenderPipeline/DefaultRenderPipeline.cs b/Prowl.Runtime/Rendering/RenderPipeline/DefaultRenderPipeline.cs index 0ed6e16a..cf2858c6 100644 --- a/Prowl.Runtime/Rendering/RenderPipeline/DefaultRenderPipeline.cs +++ b/Prowl.Runtime/Rendering/RenderPipeline/DefaultRenderPipeline.cs @@ -25,6 +25,7 @@ public class DefaultRenderPipeline : RenderPipeline private static void ValidateDefaults() { + // TODO: FIXME: these values are never null s_quadMesh ??= Mesh.CreateQuad(Vector2.one); s_gridMaterial ??= new Material(Application.AssetProvider.LoadAsset("Defaults/Grid.shader")); s_defaultMaterial ??= new Material(Application.AssetProvider.LoadAsset("Defaults/DefaultUnlit.shader")); @@ -33,16 +34,19 @@ private static void ValidateDefaults() s_whiteTexture ??= Texture2D.EmptyWhite; - if (s_skyDome == null) - { - GameObject skyDomeModel = Application.AssetProvider.LoadAsset("Defaults/SkyDome.obj").Res; - MeshRenderer renderer = skyDomeModel.GetComponentInChildren(true, true); + // TODO: FIXME: s_skyDome is never null + // if (s_skyDome == null) + // { + GameObject skyDomeModel = Application.AssetProvider.LoadAsset("Defaults/SkyDome.obj").Res; + MeshRenderer renderer = skyDomeModel.GetComponentInChildren(true, true); + if (renderer.Mesh.Res is not null) + { s_skyDome = renderer.Mesh.Res; } + // } } - public override void Render(Framebuffer target, Camera camera, in RenderingData data) { ValidateDefaults(); diff --git a/Prowl.Runtime/Rendering/Texture/RenderTexture.cs b/Prowl.Runtime/Rendering/Texture/RenderTexture.cs index 5920ca5d..be0b7d4b 100644 --- a/Prowl.Runtime/Rendering/Texture/RenderTexture.cs +++ b/Prowl.Runtime/Rendering/Texture/RenderTexture.cs @@ -220,7 +220,7 @@ public override void OnDispose() DepthBuffer?.Dispose(); if (ColorBuffers != null) - foreach (Texture2D tex in ColorBuffers) + foreach (var tex in ColorBuffers) tex?.Dispose(); Framebuffer?.Dispose(); diff --git a/Prowl.Runtime/Rendering/Texture/TextureSampler.cs b/Prowl.Runtime/Rendering/Texture/TextureSampler.cs index baa9cb32..3734dbc5 100644 --- a/Prowl.Runtime/Rendering/Texture/TextureSampler.cs +++ b/Prowl.Runtime/Rendering/Texture/TextureSampler.cs @@ -96,7 +96,7 @@ private void RecreateInternalSampler() { OnDispose(); _internalDescription = description; - _internalSampler = Graphics.Factory.CreateSampler(ref _internalDescription); + _internalSampler = Graphics.Factory.CreateSampler(in _internalDescription); } } diff --git a/Prowl.Runtime/Resources/AnimationClip.cs b/Prowl.Runtime/Resources/AnimationClip.cs index a1186f4a..5b89881d 100644 --- a/Prowl.Runtime/Resources/AnimationClip.cs +++ b/Prowl.Runtime/Resources/AnimationClip.cs @@ -94,21 +94,23 @@ public void Deserialize(SerializedProperty value, Serializer.SerializationContex var boneList = value.Get("Bones"); foreach (var boneProp in boneList.List) { - var bone = new AnimBone(); - bone.BoneName = boneProp.Get("BoneName").StringValue; - - bone.PosX = Serializer.Deserialize(boneProp.Get("PosX"), ctx); - bone.PosY = Serializer.Deserialize(boneProp.Get("PosY"), ctx); - bone.PosZ = Serializer.Deserialize(boneProp.Get("PosZ"), ctx); - - bone.RotX = Serializer.Deserialize(boneProp.Get("RotX"), ctx); - bone.RotY = Serializer.Deserialize(boneProp.Get("RotY"), ctx); - bone.RotZ = Serializer.Deserialize(boneProp.Get("RotZ"), ctx); - bone.RotW = Serializer.Deserialize(boneProp.Get("RotW"), ctx); - - bone.ScaleX = Serializer.Deserialize(boneProp.Get("ScaleX"), ctx); - bone.ScaleY = Serializer.Deserialize(boneProp.Get("ScaleY"), ctx); - bone.ScaleZ = Serializer.Deserialize(boneProp.Get("ScaleZ"), ctx); + var bone = new AnimBone + { + BoneName = boneProp.Get("BoneName").StringValue, + + PosX = Serializer.Deserialize(boneProp.Get("PosX"), ctx) ?? new AnimationCurve(), + PosY = Serializer.Deserialize(boneProp.Get("PosY"), ctx) ?? new AnimationCurve(), + PosZ = Serializer.Deserialize(boneProp.Get("PosZ"), ctx) ?? new AnimationCurve(), + + RotX = Serializer.Deserialize(boneProp.Get("RotX"), ctx) ?? new AnimationCurve(), + RotY = Serializer.Deserialize(boneProp.Get("RotY"), ctx) ?? new AnimationCurve(), + RotZ = Serializer.Deserialize(boneProp.Get("RotZ"), ctx) ?? new AnimationCurve(), + RotW = Serializer.Deserialize(boneProp.Get("RotW"), ctx) ?? new AnimationCurve(), + + ScaleX = Serializer.Deserialize(boneProp.Get("ScaleX"), ctx) ?? new AnimationCurve(), + ScaleY = Serializer.Deserialize(boneProp.Get("ScaleY"), ctx) ?? new AnimationCurve(), + ScaleZ = Serializer.Deserialize(boneProp.Get("ScaleZ"), ctx) ?? new AnimationCurve() + }; Bones.Add(bone); } diff --git a/Prowl.Runtime/Resources/ScriptableObject.cs b/Prowl.Runtime/Resources/ScriptableObject.cs index 29ff2f97..4b638da1 100644 --- a/Prowl.Runtime/Resources/ScriptableObject.cs +++ b/Prowl.Runtime/Resources/ScriptableObject.cs @@ -9,8 +9,8 @@ public ScriptableObject() : base() { } private ScriptableObject(string name) : base(name) { } // ScriptableObjects can only be created via the AssetDatabase loading them, so their guranteed to always Deserialize - public void OnAfterDeserialize() => OnEnable(); - public void OnBeforeSerialize() { } + public virtual void OnAfterDeserialize() => OnEnable(); + public virtual void OnBeforeSerialize() { } public virtual void OnEnable() { } diff --git a/Prowl.Runtime/Serializer/SerializedProperty.Compound.cs b/Prowl.Runtime/Serializer/SerializedProperty.Compound.cs index 6c8f511e..d25054f8 100644 --- a/Prowl.Runtime/Serializer/SerializedProperty.Compound.cs +++ b/Prowl.Runtime/Serializer/SerializedProperty.Compound.cs @@ -137,10 +137,8 @@ public static SerializedProperty Merge(List allTags) switch (nameVal.Value.TagType) { case PropertyType.Compound: - mergedTag = Merge(allTags.Select(t => t.Get(nameVal.Key)).ToList()); - return mergedTag != null; case PropertyType.List: - mergedTag = Merge(allTags.Select(t => t.Get(nameVal.Key)).ToList()); + mergedTag = Merge(allTags.Where(t => t != null).Select(t => t?.Get(nameVal.Key)!).ToList()); return mergedTag != null; default: if (nameVal.Value.Value?.Equals(nTag.Value) != false) diff --git a/Prowl.Runtime/Serializer/SerializedProperty.cs b/Prowl.Runtime/Serializer/SerializedProperty.cs index 3d6c978b..c420d5f1 100644 --- a/Prowl.Runtime/Serializer/SerializedProperty.cs +++ b/Prowl.Runtime/Serializer/SerializedProperty.cs @@ -199,7 +199,7 @@ public void Set(object value) /// Returns the value of this tag, cast as a bool. /// When used on a tag other than BoolTag. - public bool BoolValue { get => (bool)Value; set => Set(value); } + public bool BoolValue { get => (Value is not null && (bool)Value); set => Set(value); } /// Returns the value of this tag, cast as a byte. /// When used on a tag other than ByteTag. diff --git a/Prowl.Runtime/Utils/MultiValueDictionary.cs b/Prowl.Runtime/Utils/MultiValueDictionary.cs index 0fffc464..94eeb1df 100644 --- a/Prowl.Runtime/Utils/MultiValueDictionary.cs +++ b/Prowl.Runtime/Utils/MultiValueDictionary.cs @@ -148,7 +148,7 @@ public MultiValueDictionary(IEnumerable - /// Creates a new new instance of the + /// Creates a new instance of the /// class that is empty, has the default initial capacity, and uses the default /// for . The /// internal dictionary will use instances of the @@ -180,7 +180,7 @@ public static MultiValueDictionary Create() } /// - /// Creates a new new instance of the + /// Creates a new instance of the /// class that is empty, has the specified initial capacity, and uses the default /// for . The /// internal dictionary will use instances of the @@ -216,7 +216,7 @@ public static MultiValueDictionary Create(int ca } /// - /// Creates a new new instance of the + /// Creates a new instance of the /// class that is empty, has the default initial capacity, and uses the specified /// for . The /// internal dictionary will use instances of the @@ -250,7 +250,7 @@ public static MultiValueDictionary Create(IEqual } /// - /// Creates a new new instance of the + /// Creates a new instance of the /// class that is empty, has the specified initial capacity, and uses the specified /// for . The /// internal dictionary will use instances of the @@ -375,7 +375,7 @@ public static MultiValueDictionary Create(IEnume ======================================================================*/ /// - /// Creates a new new instance of the + /// Creates a new instance of the /// class that is empty, has the default initial capacity, and uses the default /// for . The /// internal dictionary will use instances of the @@ -409,7 +409,7 @@ public static MultiValueDictionary Create(Func - /// Creates a new new instance of the + /// Creates a new instance of the /// class that is empty, has the specified initial capacity, and uses the default /// for . The /// internal dictionary will use instances of the @@ -447,7 +447,7 @@ public static MultiValueDictionary Create(int ca } /// - /// Creates a new new instance of the + /// Creates a new instance of the /// class that is empty, has the default initial capacity, and uses the specified /// for . The /// internal dictionary will use instances of the @@ -483,7 +483,7 @@ public static MultiValueDictionary Create(IEqual } /// - /// Creates a new new instance of the + /// Creates a new instance of the /// class that is empty, has the specified initial capacity, and uses the specified /// for . The /// internal dictionary will use instances of the @@ -816,7 +816,7 @@ public bool TryGetValue(TKey key, out IReadOnlyCollection value) throw new ArgumentNullException(nameof(key)); var success = _dictionary.TryGetValue(key, out InnerCollectionView collection); - value = collection; + value = collection is null ? new List() : collection; return success; } diff --git a/Prowl.Runtime/Utils/NodeSystem/Node.cs b/Prowl.Runtime/Utils/NodeSystem/Node.cs index ed8766a9..0e88f765 100644 --- a/Prowl.Runtime/Utils/NodeSystem/Node.cs +++ b/Prowl.Runtime/Utils/NodeSystem/Node.cs @@ -408,7 +408,7 @@ public bool ContainsKey(string key) public bool TryGetValue(string key, out NodePort value) { var result = dictionary.TryGetValue(key, out NodePort dictionaryValue); - value = dictionaryValue; + value = dictionaryValue ?? throw new KeyNotFoundException(); return result; } diff --git a/Prowl.Runtime/Utils/NodeSystem/NodeGraph.cs b/Prowl.Runtime/Utils/NodeSystem/NodeGraph.cs index 55cda142..ee97e3ea 100644 --- a/Prowl.Runtime/Utils/NodeSystem/NodeGraph.cs +++ b/Prowl.Runtime/Utils/NodeSystem/NodeGraph.cs @@ -145,7 +145,7 @@ public virtual void Clear() public virtual NodeGraph Copy() { SerializedProperty graphTag = Serializer.Serialize(this); - NodeGraph graph = Serializer.Deserialize(graphTag); + NodeGraph graph = Serializer.Deserialize(graphTag) ?? throw new NullReferenceException(); // Instantiate all nodes inside the graph for (int i = 0; i < nodes.Count; i++) { @@ -175,9 +175,9 @@ protected virtual void OnDestroy() Clear(); } - public void OnBeforeSerialize() { } + public override void OnBeforeSerialize() { } - public void OnAfterDeserialize() + public override void OnAfterDeserialize() { // Clear null nodes nodes.RemoveAll(n => n == null); diff --git a/Prowl.Runtime/Utils/NodeSystem/Nodes/ReflectedNode.cs b/Prowl.Runtime/Utils/NodeSystem/Nodes/ReflectedNode.cs index a91820ea..7b7e9055 100644 --- a/Prowl.Runtime/Utils/NodeSystem/Nodes/ReflectedNode.cs +++ b/Prowl.Runtime/Utils/NodeSystem/Nodes/ReflectedNode.cs @@ -47,7 +47,7 @@ public void SetMethod(MethodInfo method_info) cached_method = method_info; node_title = GetNodeName(method_info); - type_Name = method_info.ReflectedType.FullName; + type_Name = method_info.ReflectedType.FullName ?? throw new InvalidOperationException(); method_Name = method_info.Name; AddDynamicInput(typeof(FlowNode), ConnectionType.Override, TypeConstraint.Strict, "From", true); diff --git a/Prowl.Runtime/Utils/ProwlHash.cs b/Prowl.Runtime/Utils/ProwlHash.cs index 78bd8830..712a2e86 100644 --- a/Prowl.Runtime/Utils/ProwlHash.cs +++ b/Prowl.Runtime/Utils/ProwlHash.cs @@ -204,7 +204,7 @@ public static ulong Combine(T1 value1, T2 value2 } // From https://stackoverflow.com/questions/670063/getting-hash-of-a-list-of-strings-regardless-of-order - public static int OrderlessHash(IEnumerable source, IEqualityComparer? comparer = null) + public static int OrderlessHash(IEnumerable source, IEqualityComparer? comparer = null) where T : notnull { comparer ??= EqualityComparer.Default;