Skip to content

Commit

Permalink
fix: improve scripted editor type getting
Browse files Browse the repository at this point in the history
  • Loading branch information
sinnwrig committed Oct 3, 2024
1 parent 3de15c2 commit 9ef7061
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 55 deletions.
42 changes: 4 additions & 38 deletions Prowl.Editor/Assets/CustomEditorAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,49 +8,15 @@

namespace Prowl.Editor.Assets;

[AttributeUsage(AttributeTargets.Class)]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class CustomEditorAttribute : Attribute
{
public Type Type { get; private set; }
public bool Inheritable { get; private set; }

public CustomEditorAttribute(Type type)
public CustomEditorAttribute(Type type, bool isInheritable = true)
{
Type = type;
}

public static Dictionary<Type, Type> typeToEditor = new();

[OnAssemblyLoad]
public static void GenerateLookUp()
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
foreach (var type in assembly.GetTypes())
if (type != null)
{
var attribute = type.GetCustomAttribute<CustomEditorAttribute>();
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]
public static void ClearLookUp()
{
typeToEditor.Clear();
}

/// <returns>The editor type for that Extension</returns>
public static Type? GetEditor(Type type)
{
if (typeToEditor.TryGetValue(type, out var editorType))
return editorType;
// If no direct custom editor, look for a base class custom editor
foreach (var pair in typeToEditor)
if (pair.Key.IsAssignableFrom(type))
return pair.Value;
return null;
Inheritable = isInheritable;
}
}
4 changes: 2 additions & 2 deletions Prowl.Editor/Assets/Importers/MaterialImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public override void Import(SerializedAsset ctx, FileInfo assetPath)
[CustomEditor(typeof(MaterialImporter))]
public class MaterialImporterEditor : ScriptedEditor
{
private Material _editingMaterial;
private MaterialEditor _editor;
private Material? _editingMaterial;
private MaterialEditor? _editor;


public override void OnEnable()
Expand Down
22 changes: 14 additions & 8 deletions Prowl.Editor/Assets/Importers/ScriptableObjectImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License. See the LICENSE file in the project root for details.

using Prowl.Editor.Preferences;
using Prowl.Editor.ScriptedEditors;
using Prowl.Runtime;
using Prowl.Runtime.Utils;

Expand All @@ -22,19 +23,24 @@ public override void Import(SerializedAsset ctx, FileInfo assetPath)
[CustomEditor(typeof(ScriptableObjectImporter))]
public class ScriptableObjectImporterEditor : ScriptedEditor
{
ScriptableObject? scriptObject;
private ScriptableObject? _editingObject;
private ScriptedEditor? _objectEditor;

public override void OnInspectorGUI()
public override void OnEnable()
{
var importer = (ScriptableObjectImporter)(target as MetaFile).importer;
SerializedProperty tag = StringTagConverter.ReadFromFile((target as MetaFile).AssetPath);
_editingObject = Serializer.Deserialize<ScriptableObject>(tag);
_objectEditor = null; // Replace this to load a Scripta
}


public override void OnInspectorGUI()
{
try
{
bool changed = false;

scriptObject ??= Serializer.Deserialize<ScriptableObject>(StringTagConverter.ReadFromFile((target as MetaFile).AssetPath));

object t = scriptObject;
object t = _editingObject;
changed |= EditorGUI.PropertyGrid("CompPropertyGrid", ref t,
EditorGUI.TargetFields.Serializable | EditorGUI.TargetFields.Properties,
EditorGUI.PropertyGridConfig.NoHeader | EditorGUI.PropertyGridConfig.NoBorder | EditorGUI.PropertyGridConfig.NoBackground);
Expand All @@ -44,8 +50,8 @@ public override void OnInspectorGUI()

if (changed)
{
scriptObject.OnValidate();
StringTagConverter.WriteToFile(Serializer.Serialize(scriptObject), (target as MetaFile).AssetPath);
_editingObject.OnValidate();
StringTagConverter.WriteToFile(Serializer.Serialize(_editingObject), (target as MetaFile).AssetPath);
AssetDatabase.Reimport((target as MetaFile).AssetPath);
}
}
Expand Down
4 changes: 2 additions & 2 deletions Prowl.Editor/Editor/InspectorWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ protected override void Draw()
var meta = MetaFile.Load(path);
if (meta != null)
{
Type? editorType = CustomEditorAttribute.GetEditor(meta.importer.GetType());
Type? editorType = ScriptedEditor.GetEditorType(meta.importer.GetType());
if (editorType != null)
{
customEditor = (path, (ScriptedEditor)Activator.CreateInstance(editorType));
Expand Down Expand Up @@ -152,7 +152,7 @@ protected override void Draw()
if (customEditor == null)
{
// Just selected a new object create the editor
Type? editorType = CustomEditorAttribute.GetEditor(Selected.GetType());
Type? editorType = ScriptedEditor.GetEditorType(Selected.GetType());
if (editorType != null)
{
customEditor = (Selected, (ScriptedEditor)Activator.CreateInstance(editorType));
Expand Down
9 changes: 7 additions & 2 deletions Prowl.Editor/Editor/SceneViewWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -464,9 +464,11 @@ private void DrawViewportSettings()
double width = (vertical ? buttonSize : buttonSize * buttonCount) + 8;
double height = (vertical ? buttonSize * buttonCount : buttonSize) + 8;

Color bgColor = new Color(0.1f, 0.1f, 0.1f, 0.5f);

using (gui.Node("VpSettings").TopLeft(5).Scale(width, height).Padding(4).Layout(vertical ? LayoutType.Column : LayoutType.Row).Enter())
{
gui.Draw2D.DrawRectFilled(gui.CurrentNode.LayoutData.Rect, new Color(0.1f, 0.1f, 0.1f, 0.5f), (float)EditorStylePrefs.Instance.WindowRoundness);
gui.Draw2D.DrawRectFilled(gui.CurrentNode.LayoutData.Rect, bgColor, (float)EditorStylePrefs.Instance.WindowRoundness);

using (gui.Node("EditorCam").Scale(buttonSize).Enter())
{
Expand All @@ -486,7 +488,10 @@ private void DrawViewportSettings()
style.BGColor = Color.clear;
style.BorderColor = Color.clear;

if (gui.Combo("GridType", "_GridTypePopup", ref gridTypeIndex, Enum.GetNames(typeof(GridType)), 0, 0, buttonSize, buttonSize, style, EditorGUI.GetInputStyle(), FontAwesome6.TableCells))
Gui.WidgetStyle popupStyle = style;
popupStyle.BGColor = bgColor;

if (gui.Combo("GridType", "_GridTypePopup", ref gridTypeIndex, Enum.GetNames(typeof(GridType)), 0, 0, buttonSize, buttonSize, style, popupStyle, FontAwesome6.TableCells))
SceneViewPreferences.Instance.GridType = (GridType)gridTypeIndex;

using (gui.Node("GizmoMode").Scale(buttonSize).Enter())
Expand Down
4 changes: 2 additions & 2 deletions Prowl.Editor/Editor/ScriptedEditors/GameObjectEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ public override void OnInspectorGUI()
gui.SetNodeStorage(gui.CurrentNode.Parent, openedID, compOpened);
}

DragnDrop.Drag((MonoBehaviour)comp, comp!.GetType());
DragnDrop.Drag(comp, comp!.GetType());

var rect = gui.CurrentNode.LayoutData.InnerRect;
string cname = GetComponentDisplayName(cType);
Expand Down Expand Up @@ -255,7 +255,7 @@ public override void OnInspectorGUI()
}
else
{
var editorType = CustomEditorAttribute.GetEditor(cType);
var editorType = GetEditorType(cType);
if (editorType != null)
{
editor = Activator.CreateInstance(editorType) as ScriptedEditor;
Expand Down
78 changes: 77 additions & 1 deletion Prowl.Editor/Editor/ScriptedEditors/ScriptedEditor.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
// 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 System.Reflection;

using Prowl.Runtime;
using Prowl.Editor.Assets;
using Prowl.Runtime.GUI;
using Prowl.Runtime.Utils;

namespace Prowl.Editor;

Expand All @@ -10,7 +15,78 @@ public class ScriptedEditor
public Gui gui => Gui.ActiveGUI;

public object target { get; internal set; }

public virtual void OnEnable() { }
public virtual void OnInspectorGUI() { }

public virtual void OnInspectorGUI()
{
object t = target;

if (EditorGUI.PropertyGrid("Default Drawer", ref t, EditorGUI.TargetFields.Serializable, EditorGUI.PropertyGridConfig.NoHeader))
{
MethodInfo? method = target.GetType().GetMethod("OnValidate", BindingFlags.Public | BindingFlags.Instance);
method?.Invoke(t, null);

target = t;
}
}

public virtual void OnDisable() { }


private static readonly Dictionary<Type, Type> s_editorLookup = [];

[OnAssemblyLoad]
public static void GenerateLookUp()
{
List<Type> typesToSearch = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes()).ToList();
List<CustomEditorAttribute> customEditors = [];

foreach (Type type in typesToSearch)
{
CustomEditorAttribute? attribute = type.GetCustomAttribute<CustomEditorAttribute>();

if (attribute == null)
continue;

if (type != typeof(ScriptedEditor))
{
Debug.LogWarning($"{nameof(CustomEditorAttribute)} is not valid on type '{type}'. Attribute is only valid on types inheriting from {nameof(ScriptedEditor)}. Attribute will be ignored.");
continue;
}

if (s_editorLookup.TryGetValue(attribute.Type, out Type? oldType))
Debug.LogError($"Custom Editor Overwritten. {attribute.Type.Name} already has a custom Editor: {oldType.Name}, being overwritten by: {type.Name}");

s_editorLookup[attribute.Type] = type;
customEditors.Add(attribute);
}

foreach (Type type in typesToSearch)
{
Type? baseType = type;
Type? editor = null;

while (baseType != null && !s_editorLookup.TryGetValue(baseType, out editor))
baseType = baseType.BaseType;

if (editor != null)
s_editorLookup[type] = editor;
}
}

[OnAssemblyUnload]
public static void ClearLookUp()
{
s_editorLookup.Clear();
}

/// <returns>The editor type for that Extension</returns>
public static Type? GetEditorType(Type type)
{
if (s_editorLookup.TryGetValue(type, out Type? editorType))
return editorType;

return null;
}
}

0 comments on commit 9ef7061

Please sign in to comment.