Add support for creating Json Assets in editor out of structure type

#2679
This commit is contained in:
Wojtek Figat
2025-01-31 21:58:36 +01:00
parent 24f3dfe264
commit 4e0cd9e8a9
5 changed files with 97 additions and 18 deletions

View File

@@ -1,9 +1,11 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System;
using System.Linq;
using FlaxEditor.Content.Create;
using FlaxEditor.CustomEditors;
using FlaxEditor.CustomEditors.Editors;
using FlaxEditor.Scripting;
using FlaxEditor.Windows;
using FlaxEditor.Windows.Assets;
using FlaxEngine;
@@ -84,18 +86,67 @@ namespace FlaxEditor.Content
if (_element != null)
{
// Define the rule for the types that can be used to create a json data asset
_element.CustomControl.CheckValid += type =>
type.Type != null &&
type.IsClass &&
type.Type.IsVisible &&
!type.IsAbstract &&
!type.IsGenericType &&
type.Type.GetConstructor(Type.EmptyTypes) != null &&
!typeof(FlaxEngine.GUI.Control).IsAssignableFrom(type.Type) &&
!typeof(FlaxEngine.Object).IsAssignableFrom(type.Type);
_element.CustomControl.CheckValid += OnCheckValidJsonAssetType;
}
}
private static Type[] BlacklistedClasses =
[
typeof(System.Attribute),
typeof(FlaxEngine.Object),
typeof(FlaxEngine.GUI.Control),
];
private static Type[] BlacklistedStructs =
[
typeof(Float2),
typeof(Float3),
typeof(Float4),
typeof(Double2),
typeof(Double3),
typeof(Double4),
typeof(Vector2),
typeof(Vector3),
typeof(Vector4),
typeof(Half2),
typeof(Half3),
typeof(Half4),
typeof(Int2),
typeof(Int3),
typeof(Int4),
typeof(Transform),
typeof(Quaternion),
typeof(BoundingBox),
typeof(BoundingSphere),
typeof(BoundingFrustum),
typeof(Ray),
typeof(Plane),
typeof(Matrix),
typeof(Color),
typeof(Color32),
typeof(FloatR11G11B10),
typeof(FloatR10G10B10A2),
typeof(FlaxEngine.Half),
];
private static bool OnCheckValidJsonAssetType(ScriptType type)
{
// Define the rule for the types that can be used to create a json data asset
var mType = type.Type;
if (mType == null ||
type.IsAbstract ||
type.IsStatic ||
type.IsGenericType ||
!mType.IsVisible)
return false;
if (type.IsClass)
return mType.GetConstructor(Type.EmptyTypes) != null && BlacklistedClasses.FirstOrDefault(x => x.IsAssignableFrom(mType)) == null;
if (type.IsStructure)
return !type.IsPrimitive &&
!type.IsVoid &&
!BlacklistedStructs.Contains(mType);
return false;
}
}
}
@@ -175,7 +226,7 @@ namespace FlaxEditor.Content
{
_thumbnail = SpriteHandle.Invalid;
}
/// <summary>
/// Constructor with overriden thumbnail.
/// </summary>
@@ -196,7 +247,7 @@ namespace FlaxEditor.Content
{
Editor.SaveJsonAsset(outputPath, new T());
}
/// <inheritdoc />
public override AssetItem ConstructItem(string path, string typeName, ref Guid id)
{

View File

@@ -1,10 +1,13 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System;
using System.ComponentModel;
using System.Linq;
using FlaxEditor.History;
using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.GUI;
using CategoryAttribute = FlaxEngine.CategoryAttribute;
namespace FlaxEditor.GUI
{
@@ -101,11 +104,26 @@ namespace FlaxEditor.GUI
if (_isValid(type))
{
var attributes = type.GetAttributes(true);
if (attributes.FirstOrDefault(x => x is HideInEditorAttribute || x is System.Runtime.CompilerServices.CompilerGeneratedAttribute) == null)
if (IsHideAttributes(attributes))
{
var mType = type.Type;
if (mType != null && mType.IsValueType && mType.ReflectedType != null && string.Equals(mType.ReflectedType.Name, "<PrivateImplementationDetails>", StringComparison.Ordinal))
continue;
if (mType != null)
{
// Skip if type is compiler-generated
if (mType.IsValueType && mType.ReflectedType != null && string.Equals(mType.ReflectedType.Name, "<PrivateImplementationDetails>", StringComparison.Ordinal))
continue;
// Skip if outer type is hidden
if (mType.DeclaringType != null && IsHideAttributes(mType.DeclaringType.GetCustomAttributes(true)))
continue;
// Blacklist some types
if (typeof(TypeConverter).IsAssignableFrom(mType) ||
typeof(IHistoryAction).IsAssignableFrom(mType) ||
(mType.Namespace != null && mType.Namespace.StartsWith("Newtonsoft.Json")))
continue;
}
AddItem(new TypeItemView(type, attributes));
}
}
@@ -113,6 +131,17 @@ namespace FlaxEditor.GUI
SortItems();
}
private bool IsHideAttributes(object[] attributes)
{
return attributes.FirstOrDefault(IsHideAttribute) == null;
}
private bool IsHideAttribute(object attr)
{
return attr is HideInEditorAttribute ||
attr is System.Runtime.CompilerServices.CompilerGeneratedAttribute;
}
private void OnItemClicked(Item item)
{
_selected(((TypeItemView)item).Type);

View File

@@ -8,7 +8,6 @@ using System.Text;
using FlaxEditor.CustomEditors;
using FlaxEditor.GUI.ContextMenu;
using FlaxEditor.Options;
using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.GUI;
using FlaxEngine.Json;

View File

@@ -42,7 +42,7 @@ namespace FlaxEditor
/// </summary>
/// <typeparam name="TData">The type of the data. Must have <see cref="SerializableAttribute"/>.</typeparam>
/// <seealso cref="FlaxEditor.IUndoAction" />
[Serializable]
[Serializable, HideInEditor]
public abstract class UndoActionBase<TData> : IUndoAction where TData : struct
{
/// <summary>

View File

@@ -5,7 +5,7 @@ namespace FlaxEditor.Utilities;
/// <summary>
/// Units display utilities for Editor.
/// </summary>
public class Units
public static class Units
{
/// <summary>
/// Factor of units per meter.