From fe7cc62728f52ba323be0355b505c32ec679ca03 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 15 Feb 2024 11:22:01 +0100 Subject: [PATCH] Add `JsonAssetReference` type for scripting --- .../CustomEditors/Editors/AssetRefEditor.cs | 24 ++++-- Source/Engine/Content/JsonAssetReference.cs | 83 +++++++++++++++++++ Source/Engine/Content/JsonAssetReference.h | 25 ++++++ 3 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 Source/Engine/Content/JsonAssetReference.cs create mode 100644 Source/Engine/Content/JsonAssetReference.h diff --git a/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs b/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs index 1f3359fd5..db8ec1152 100644 --- a/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs +++ b/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs @@ -51,10 +51,13 @@ namespace FlaxEditor.CustomEditors.Editors return; Picker = layout.Custom().CustomControl; - _valueType = Values.Type.Type != typeof(object) || Values[0] == null ? Values.Type : TypeUtils.GetObjectType(Values[0]); + var value = Values[0]; + _valueType = Values.Type.Type != typeof(object) || value == null ? Values.Type : TypeUtils.GetObjectType(value); var assetType = _valueType; if (assetType == typeof(string)) assetType = new ScriptType(typeof(Asset)); + else if (_valueType.Type != null && _valueType.Type.Name == typeof(JsonAssetReference<>).Name) + assetType = new ScriptType(_valueType.Type.GenericTypeArguments[0]); float height = 48; var attributes = Values.GetAttributes(); @@ -102,6 +105,12 @@ namespace FlaxEditor.CustomEditors.Editors SetValue(new SceneReference(Picker.Validator.SelectedID)); else if (_valueType.Type == typeof(string)) SetValue(Picker.Validator.SelectedPath); + else if (_valueType.Type.Name == typeof(JsonAssetReference<>).Name) + { + var value = Values[0]; + value.GetType().GetField("Asset").SetValue(value, Picker.Validator.SelectedAsset as JsonAsset); + SetValue(value); + } else SetValue(Picker.Validator.SelectedAsset); } @@ -114,16 +123,19 @@ namespace FlaxEditor.CustomEditors.Editors if (!HasDifferentValues) { _isRefreshing = true; - if (Values[0] is AssetItem assetItem) + var value = Values[0]; + if (value is AssetItem assetItem) Picker.Validator.SelectedItem = assetItem; - else if (Values[0] is Guid guid) + else if (value is Guid guid) Picker.Validator.SelectedID = guid; - else if (Values[0] is SceneReference sceneAsset) + else if (value is SceneReference sceneAsset) Picker.Validator.SelectedItem = Editor.Instance.ContentDatabase.FindAsset(sceneAsset.ID); - else if (Values[0] is string path) + else if (value is string path) Picker.Validator.SelectedPath = path; + else if (value != null && value.GetType().Name == typeof(JsonAssetReference<>).Name) + Picker.Validator.SelectedAsset = value.GetType().GetField("Asset").GetValue(value) as JsonAsset; else - Picker.Validator.SelectedAsset = Values[0] as Asset; + Picker.Validator.SelectedAsset = value as Asset; _isRefreshing = false; } } diff --git a/Source/Engine/Content/JsonAssetReference.cs b/Source/Engine/Content/JsonAssetReference.cs new file mode 100644 index 000000000..adfaa5179 --- /dev/null +++ b/Source/Engine/Content/JsonAssetReference.cs @@ -0,0 +1,83 @@ +// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. + +using System; + +namespace FlaxEngine +{ + /// + /// Json asset reference utility. References resource with a typed data type. + /// + /// Type of the asset instance type. +#if FLAX_EDITOR + [CustomEditor(typeof(FlaxEditor.CustomEditors.Editors.AssetRefEditor))] +#endif + public struct JsonAssetReference + { + /// + /// Gets or sets the referenced asset. + /// + public JsonAsset Asset; + + /// + /// Gets the instance of the Json Asset. Null if unset. + /// + /// instance of the Json Asset or null if unset. + public T Get() + { + return (T)Asset?.Instance; + } + + /// + /// Initializes a new instance of the structure. + /// + /// The Json Asset. + public JsonAssetReference(JsonAsset asset) + { + Asset = asset; + } + + /// + /// Implicit cast operator. + /// + public static implicit operator JsonAsset(JsonAssetReference value) + { + return value.Asset; + } + + /// + /// Implicit cast operator. + /// + public static implicit operator IntPtr(JsonAssetReference value) + { + return Object.GetUnmanagedPtr(value.Asset); + } + + /// + /// Implicit cast operator. + /// + public static implicit operator JsonAssetReference(JsonAsset value) + { + return new JsonAssetReference(value); + } + + /// + /// Implicit cast operator. + /// + public static implicit operator JsonAssetReference(IntPtr valuePtr) + { + return new JsonAssetReference(Object.FromUnmanagedPtr(valuePtr) as JsonAsset); + } + + /// + public override string ToString() + { + return Asset?.ToString(); + } + + /// + public override int GetHashCode() + { + return Asset?.GetHashCode() ?? 0; + } + } +} diff --git a/Source/Engine/Content/JsonAssetReference.h b/Source/Engine/Content/JsonAssetReference.h new file mode 100644 index 000000000..82fbe47f1 --- /dev/null +++ b/Source/Engine/Content/JsonAssetReference.h @@ -0,0 +1,25 @@ +// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. + +#pragma once + +#include "Engine/Content/JsonAsset.h" +#include "Engine/Content/AssetReference.h" + +/// +/// Json asset reference utility. References resource with a typed data type. +/// +/// Type of the asset instance type. +template +API_STRUCT(NoDefault, Template, MarshalAs=JsonAsset*) struct JsonAssetReference : AssetReference +{ + JsonAssetReference& operator=(JsonAsset* asset) noexcept + { + OnSet(asset); + return *this; + } + + operator JsonAsset*() const + { + return Get(); + } +};