From 6894c4ef1eb0db9974adf0e9fb07bde9a622b2d5 Mon Sep 17 00:00:00 2001 From: godzzz Date: Sun, 21 Jan 2024 16:29:40 +0400 Subject: [PATCH] [v0.2.5] Fix for ResourceAsset [!] Improvements for Database assets --- .../Files/EditorDatabaseAsset.cs | 84 +++++++------------ .../Files/EditorDatabaseAsset.cs.meta | 0 Runtime/Extensions/DirectoryInfoExtensions.cs | 18 +--- Runtime/Files.Bundles/Files/AssetBundleUri.cs | 2 +- Runtime/Files.Database/DatabaseAssetUri.cs | 2 + .../Files.Database/RuntimeDatabaseAsset.cs | 54 ++++++++++++ .../RuntimeDatabaseAsset.cs.meta | 3 + Runtime/Files.Resource/ResourcesAsset.cs | 20 ++++- package.json | 2 +- 9 files changed, 107 insertions(+), 78 deletions(-) rename Runtime/Files.Database/DatabaseAsset.cs => Editor/Files/EditorDatabaseAsset.cs (51%) rename Runtime/Files.Database/DatabaseAsset.cs.meta => Editor/Files/EditorDatabaseAsset.cs.meta (100%) create mode 100644 Runtime/Files.Database/RuntimeDatabaseAsset.cs create mode 100644 Runtime/Files.Database/RuntimeDatabaseAsset.cs.meta diff --git a/Runtime/Files.Database/DatabaseAsset.cs b/Editor/Files/EditorDatabaseAsset.cs similarity index 51% rename from Runtime/Files.Database/DatabaseAsset.cs rename to Editor/Files/EditorDatabaseAsset.cs index 3c9fab0..a00b238 100644 --- a/Runtime/Files.Database/DatabaseAsset.cs +++ b/Editor/Files/EditorDatabaseAsset.cs @@ -3,29 +3,35 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Depra.Assets.Delegates; using Depra.Assets.Exceptions; using Depra.Assets.Extensions; +using Depra.Assets.Files; +using Depra.Assets.Files.Database; using Depra.Assets.ValueObjects; using UnityEditor; using UnityEngine; using Object = UnityEngine.Object; -namespace Depra.Assets.Files.Database +namespace Depra.Assets.Editor.Files { - public sealed class DatabaseAsset : IAssetFile, IDisposable where TAsset : ScriptableObject + public sealed class EditorDatabaseAsset : IAssetFile, IDisposable where TAsset : ScriptableObject { private readonly Type _assetType; private readonly DatabaseAssetUri _uri; + private readonly RuntimeDatabaseAsset _runtimeAsset; private TAsset _loadedAsset; - public DatabaseAsset(DatabaseAssetUri uri) + public EditorDatabaseAsset(DatabaseAssetUri uri) { + _uri = uri; _assetType = typeof(TAsset); - Metadata = new AssetMetadata(_uri = uri, FileSize.Unknown); + Metadata = new AssetMetadata(_uri, FileSize.Unknown); + _runtimeAsset = new RuntimeDatabaseAsset(_uri); } public AssetMetadata Metadata { get; } @@ -38,17 +44,9 @@ public TAsset Load() return _loadedAsset; } - TAsset loadedAsset = null; -#if UNITY_EDITOR - if (_uri.Exists()) - { - loadedAsset = AssetDatabase.LoadAssetAtPath(_uri.Relative); - } -#endif - if (loadedAsset == null) - { - loadedAsset = CreateAsset(); - } + var loadedAsset = (TAsset) ActivateAsset(_uri.Exists() + ? AssetDatabase.LoadAssetAtPath(_uri.Relative) + : _runtimeAsset.Load()); Guard.AgainstNull(loadedAsset, () => new AssetCatNotBeCreated(_assetType, _assetType.Name)); @@ -65,39 +63,14 @@ public void Unload() return; } -#if UNITY_EDITOR - AssetDatabase.DeleteAsset(_uri.Relative); -#endif _loadedAsset = null; + _runtimeAsset.Unload(); + AssetDatabase.DeleteAsset(_uri.Relative); } - [Obsolete("Not yet supported in Unity. Use DatabaseAsset.Load() instead")] - public Task LoadAsync(DownloadProgressDelegate onProgress = null, - CancellationToken cancellationToken = default) - { - if (IsLoaded) - { - onProgress?.Invoke(DownloadProgress.Full); - return Task.FromResult(_loadedAsset); - } - - throw new AssetCanNotBeLoaded("Asynchronous loading is not supported by Unity"); - } - - private TAsset CreateAsset() - { - var asset = ScriptableObject.CreateInstance(); -#if UNITY_EDITOR - asset = (TAsset) ActivateAsset(asset); -#endif - - return asset; - } - -#if UNITY_EDITOR private Object ActivateAsset(Object asset) { - _uri.Directory.CreateIfNotExists(); + _uri.Directory.Require(); asset.name = _uri.Name; AssetDatabase.CreateAsset(asset, _uri.Relative); @@ -106,20 +79,19 @@ private Object ActivateAsset(Object asset) return asset; } -#endif - IEnumerable IAssetFile.Dependencies() - { -#if UNITY_EDITOR - var paths = AssetDatabase.GetDependencies(_uri.Relative); - foreach (var path in paths) - { - yield return new DatabaseAssetUri(path); - } -#else - return Array.Empty(); -#endif - } + + public IEnumerable Dependencies() => AssetDatabase + .GetDependencies(_uri.Relative, recursive: false) + .Select(path => new DatabaseAssetUri(path)).Cast(); void IDisposable.Dispose() => Unload(); + + [Obsolete("Not yet supported in Unity. Use DatabaseAsset.Load() instead")] + Task IAssetFile.LoadAsync(DownloadProgressDelegate onProgress, + CancellationToken cancellationToken) + { + onProgress?.Invoke(DownloadProgress.Full); + return Task.FromResult(IsLoaded ? _loadedAsset : Load()); + } } } \ No newline at end of file diff --git a/Runtime/Files.Database/DatabaseAsset.cs.meta b/Editor/Files/EditorDatabaseAsset.cs.meta similarity index 100% rename from Runtime/Files.Database/DatabaseAsset.cs.meta rename to Editor/Files/EditorDatabaseAsset.cs.meta diff --git a/Runtime/Extensions/DirectoryInfoExtensions.cs b/Runtime/Extensions/DirectoryInfoExtensions.cs index 1e62ab0..bf92e67 100644 --- a/Runtime/Extensions/DirectoryInfoExtensions.cs +++ b/Runtime/Extensions/DirectoryInfoExtensions.cs @@ -4,30 +4,16 @@ using System.IO; using System.Linq; using System.Runtime.CompilerServices; -using Depra.Assets.Common; namespace Depra.Assets.Extensions { public static class DirectoryInfoExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool IsEmpty(this DirectoryInfo self) => - self.EnumerateFileSystemInfos().Any() == false; + public static bool IsEmpty(this DirectoryInfo self) => self.EnumerateFileSystemInfos().Any() == false; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void DeleteIfEmpty(this DirectoryInfo self) - { - if (self.Exists == false || self.IsEmpty() == false) - { - return; - } - - self.Delete(true); - File.Delete(self.FullName + AssetTypes.META); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static DirectoryInfo CreateIfNotExists(this DirectoryInfo self) + public static DirectoryInfo Require(this DirectoryInfo self) { if (self.Exists == false) { diff --git a/Runtime/Files.Bundles/Files/AssetBundleUri.cs b/Runtime/Files.Bundles/Files/AssetBundleUri.cs index b2f16e1..d909958 100644 --- a/Runtime/Files.Bundles/Files/AssetBundleUri.cs +++ b/Runtime/Files.Bundles/Files/AssetBundleUri.cs @@ -20,7 +20,7 @@ public sealed record AssetBundleUri : IAssetUri public AssetBundleUri(string path) { _fileInfo = new FileInfo(path); - _fileInfo.Directory.CreateIfNotExists(); + _fileInfo.Directory.Require(); Name = string.IsNullOrEmpty(Extension) ? _fileInfo.Name diff --git a/Runtime/Files.Database/DatabaseAssetUri.cs b/Runtime/Files.Database/DatabaseAssetUri.cs index 51291db..e723d5c 100644 --- a/Runtime/Files.Database/DatabaseAssetUri.cs +++ b/Runtime/Files.Database/DatabaseAssetUri.cs @@ -37,5 +37,7 @@ public DatabaseAssetUri(string relativeDirectory, string name, string extension) internal DirectoryInfo Directory { get; } public bool Exists() => File.Exists(Absolute); + + public override string ToString() => Absolute; } } \ No newline at end of file diff --git a/Runtime/Files.Database/RuntimeDatabaseAsset.cs b/Runtime/Files.Database/RuntimeDatabaseAsset.cs new file mode 100644 index 0000000..a523b33 --- /dev/null +++ b/Runtime/Files.Database/RuntimeDatabaseAsset.cs @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: Apache-2.0 +// © 2023 Nikolay Melnikov + +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Depra.Assets.Delegates; +using Depra.Assets.Exceptions; +using Depra.Assets.ValueObjects; +using UnityEngine; + +namespace Depra.Assets.Files.Database +{ + public sealed class RuntimeDatabaseAsset : IAssetFile, IDisposable where TAsset : ScriptableObject + { + private TAsset _loadedAsset; + + public RuntimeDatabaseAsset(string name) : this((IAssetUri) new AssetName(name)) { } + + public RuntimeDatabaseAsset(IAssetUri uri) => Metadata = new AssetMetadata(uri, FileSize.Unknown); + + public AssetMetadata Metadata { get; } + public bool IsLoaded => _loadedAsset != null; + + public TAsset Load() + { + var loadedAsset = ScriptableObject.CreateInstance(); + Guard.AgainstNull(loadedAsset, () => new AssetCatNotBeCreated(typeof(TAsset), nameof(TAsset))); + + return _loadedAsset = loadedAsset; + } + + public void Unload() + { + if (_loadedAsset) + { + _loadedAsset = null; + } + } + + void IDisposable.Dispose() => Unload(); + + IEnumerable IAssetFile.Dependencies() => Array.Empty(); + + [Obsolete("Not yet supported in Unity. Use RuntimeDatabaseAsset.Load() instead")] + Task IAssetFile.LoadAsync(DownloadProgressDelegate onProgress, + CancellationToken cancellationToken) + { + onProgress?.Invoke(DownloadProgress.Full); + return Task.FromResult(IsLoaded ? _loadedAsset : Load()); + } + } +} \ No newline at end of file diff --git a/Runtime/Files.Database/RuntimeDatabaseAsset.cs.meta b/Runtime/Files.Database/RuntimeDatabaseAsset.cs.meta new file mode 100644 index 0000000..4dc00f1 --- /dev/null +++ b/Runtime/Files.Database/RuntimeDatabaseAsset.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1cb5cae42ecc47e9a1961e108a6e0efe +timeCreated: 1703629253 \ No newline at end of file diff --git a/Runtime/Files.Resource/ResourcesAsset.cs b/Runtime/Files.Resource/ResourcesAsset.cs index e0a317a..bfabbaf 100644 --- a/Runtime/Files.Resource/ResourcesAsset.cs +++ b/Runtime/Files.Resource/ResourcesAsset.cs @@ -1,8 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 -// © 2023 Nikolay Melnikov +// © 2023-2024 Nikolay Melnikov using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Depra.Assets.Delegates; @@ -11,17 +12,21 @@ using Depra.Assets.ValueObjects; using UnityEngine; using Object = UnityEngine.Object; +#if UNITY_EDITOR +using UnityEditor; +#endif namespace Depra.Assets.Files.Resource { public sealed class ResourcesAsset : IAssetFile, IDisposable where TAsset : Object { + private readonly ResourcesPath _path; private TAsset _loadedAsset; public ResourcesAsset(ResourcesPath path) { Guard.AgainstNull(path, nameof(path)); - Metadata = new AssetMetadata(path, FileSize.Unknown); + Metadata = new AssetMetadata(_path = path, FileSize.Unknown); } public AssetMetadata Metadata { get; } @@ -64,7 +69,7 @@ public async Task LoadAsync(DownloadProgressDelegate onProgress = null, } var loadedAsset = await Resources - .LoadAsync(Metadata.Uri.Relative) + .LoadAsync(Metadata.Uri.Relative) .ToTask(OnProgress, cancellationToken); Guard.AgainstNull(loadedAsset, () => new ResourceNotLoaded(Metadata.Uri.Relative)); @@ -78,7 +83,14 @@ public async Task LoadAsync(DownloadProgressDelegate onProgress = null, void OnProgress(float progress) => onProgress?.Invoke(new DownloadProgress(progress)); } - IEnumerable IAssetFile.Dependencies() => Array.Empty(); + public IEnumerable Dependencies() => +#if UNITY_EDITOR + AssetDatabase + .GetDependencies(_path.Project, recursive: false) + .Select(path => new AssetName(path)); +#else + return Array.Empty(); +#endif void IDisposable.Dispose() => Unload(); } diff --git a/package.json b/package.json index a4e6bb6..357d6dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.depra.assets.unity", - "version": "0.2.4", + "version": "0.2.5", "displayName": "Depra.Assets", "description": "Provides an API for loading Unity asset files in multiple ways through a single interface.", "unity": "2021.3",