From b47cb9ec5e3a419083ddf47499bef58ba450369c Mon Sep 17 00:00:00 2001 From: Miguel Tomas Date: Mon, 3 Aug 2020 11:33:22 +0100 Subject: [PATCH 1/3] Updated package version and naming --- Runtime/GameLovers.UiService.asmdef | 2 +- Runtime/UiService.cs | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Runtime/GameLovers.UiService.asmdef b/Runtime/GameLovers.UiService.asmdef index 3769eb2..f39315c 100644 --- a/Runtime/GameLovers.UiService.asmdef +++ b/Runtime/GameLovers.UiService.asmdef @@ -1,5 +1,5 @@ { - "name": "UiService", + "name": "GameLovers.UiService", "references": [ "GUID:84651a3751eca9349aac36a66bba901b", "GUID:9e24947de15b9834991c9d8411ea37cf", diff --git a/Runtime/UiService.cs b/Runtime/UiService.cs index c24af62..f2a6a2c 100644 --- a/Runtime/UiService.cs +++ b/Runtime/UiService.cs @@ -145,7 +145,7 @@ public async Task LoadUiAsync(Type type, bool openAfter = false) throw new KeyNotFoundException($"The UiConfig of type {type} was not added to the service. Call {nameof(AddUiConfig)} first"); } - var gameObject = await _assetLoader.InstantiatePrefabAsync(config.AddressableAddress); + var gameObject = await _assetLoader.InstantiatePrefabAsync(config.AddressableAddress, null, true); var uiPresenter = gameObject.GetComponent(); gameObject.SetActive(false); diff --git a/package.json b/package.json index 704a8e2..cae59b9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "com.gamelovers.uiservice", "displayName": "UiService", - "version": "0.3.2", + "version": "0.4.0", "unity": "2019.3", "description": "This package provides a service to help manage an Unity's, game UI.\nIt allows to open, close, load, unload and request any Ui Configured in the game.\nThe package provides a Ui Set that allows to group a set of Ui Presenters to help load, open and close multiple Uis at the same time.\n\nTo help configure the game's UI you need to create a UiConfigs Scriptable object by:\n- Right Click on the Project View > Create > ScriptableObjects > Configs > UiConfigs", "dependencies": { From 30dd3c1728f0c56a6a03db42e22dfc8179b8e752 Mon Sep 17 00:00:00 2001 From: Miguel Tomas Date: Sat, 8 Aug 2020 19:09:44 +0100 Subject: [PATCH 2/3] - Added *UiAssetLoader* to load Ui assets to memory **Changed**: - Removed the *UiService* dependency from the *com.gamelovers.assetLoader* --- CHANGELOG.md | 9 ++++- Runtime/GameLovers.UiService.asmdef | 3 +- Runtime/UiAssetLoader.cs | 62 +++++++++++++++++++++++++++++ Runtime/UiAssetLoader.cs.meta | 3 ++ Runtime/UiConfig.cs | 18 --------- Runtime/UiConfig.cs.meta | 3 -- Runtime/UiConfigs.cs | 14 ++++++- Runtime/UiPresenter.cs | 7 ++-- Runtime/UiService.cs | 36 +++++++++++++++-- package.json | 4 +- 10 files changed, 124 insertions(+), 35 deletions(-) create mode 100644 Runtime/UiAssetLoader.cs create mode 100644 Runtime/UiAssetLoader.cs.meta delete mode 100644 Runtime/UiConfig.cs delete mode 100644 Runtime/UiConfig.cs.meta diff --git a/CHANGELOG.md b/CHANGELOG.md index dec7796..051ac3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,17 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html) +## [0.5.0] - 2020-07-13 + +- Added *UiAssetLoader* to load Ui assets to memory + +**Changed**: +- Removed the *UiService* dependency from the *com.gamelovers.assetLoader* + ## [0.4.0] - 2020-07-13 **Changed**: -- Removed the *UiService* dependency from the *Addressables* +- Removed the *UiService* dependency from the *com.unity.addressables* - Modified the *UiService* to be testable and injectable into other systems ## [0.3.2] - 2020-04-18 diff --git a/Runtime/GameLovers.UiService.asmdef b/Runtime/GameLovers.UiService.asmdef index f39315c..c1af9e3 100644 --- a/Runtime/GameLovers.UiService.asmdef +++ b/Runtime/GameLovers.UiService.asmdef @@ -2,8 +2,7 @@ "name": "GameLovers.UiService", "references": [ "GUID:84651a3751eca9349aac36a66bba901b", - "GUID:9e24947de15b9834991c9d8411ea37cf", - "GUID:ebfc05ee5a737f94d8b07099524dab77" + "GUID:9e24947de15b9834991c9d8411ea37cf" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Runtime/UiAssetLoader.cs b/Runtime/UiAssetLoader.cs new file mode 100644 index 0000000..abe265b --- /dev/null +++ b/Runtime/UiAssetLoader.cs @@ -0,0 +1,62 @@ +using System.Threading.Tasks; +using UnityEngine; +using UnityEngine.AddressableAssets; +using UnityEngine.ResourceManagement.AsyncOperations; +using UnityEngine.ResourceManagement.ResourceProviders; + +// ReSharper disable CheckNamespace + +namespace GameLovers.UiService +{ + /// + /// This interface allows to wrap the asset loading scheme into the UI memory + /// + public interface IUiAssetLoader + { + /// + /// Loads and instantiates the prefab in the given with the given + /// and the given to preserve the instance transform relative to world + /// space or relative to the parent. + /// To help the execution of this method is recommended to request the asset path from an . + /// This method can be controlled in an async method and returns the prefab instantiated + /// + Task InstantiatePrefabAsync(string path, Transform parent, bool instantiateInWorldSpace); + + /// + /// Unloads the given from the game memory. + /// If is of type, then will also destroy it + /// + void UnloadAsset(T asset); + } + + /// + public class UiAssetLoader : IUiAssetLoader + { + /// + public async Task InstantiatePrefabAsync(string path, Transform parent, bool instantiateInWorldSpace) + { + var operation = Addressables.InstantiateAsync(path, new InstantiationParameters(parent, instantiateInWorldSpace)); + + await operation.Task; + + if (operation.Status != AsyncOperationStatus.Succeeded) + { + throw operation.OperationException; + } + + return operation.Result; + } + + /// + public void UnloadAsset(T asset) + { + Addressables.Release(asset); + + var gameObject = asset as GameObject; + if (gameObject != null) + { + UnityEngine.Object.Destroy(gameObject); + } + } + } +} \ No newline at end of file diff --git a/Runtime/UiAssetLoader.cs.meta b/Runtime/UiAssetLoader.cs.meta new file mode 100644 index 0000000..98a7e2e --- /dev/null +++ b/Runtime/UiAssetLoader.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 16bb54f918cc43fd976df9650a614516 +timeCreated: 1596908818 \ No newline at end of file diff --git a/Runtime/UiConfig.cs b/Runtime/UiConfig.cs deleted file mode 100644 index b087293..0000000 --- a/Runtime/UiConfig.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - -// ReSharper disable CheckNamespace - -namespace GameLovers.UiService -{ - /// - /// Represents a configuration of an with all it's important data - /// The Id is the int representation of the UI generated by the UiIdsGenerator code generator - /// - [Serializable] - public struct UiConfig - { - public string AddressableAddress; - public int Layer; - public Type UiType; - } -} \ No newline at end of file diff --git a/Runtime/UiConfig.cs.meta b/Runtime/UiConfig.cs.meta deleted file mode 100644 index 373eab0..0000000 --- a/Runtime/UiConfig.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: ba008bfe59a548a4809efbb1bcd4801d -timeCreated: 1574986631 \ No newline at end of file diff --git a/Runtime/UiConfigs.cs b/Runtime/UiConfigs.cs index 10c2dc1..84b3a02 100644 --- a/Runtime/UiConfigs.cs +++ b/Runtime/UiConfigs.cs @@ -7,7 +7,19 @@ namespace GameLovers.UiService { /// - /// Scriptable Object tool to import the & to be used in the + /// Represents a configuration of an with all it's important data + /// The Id is the int representation of the UI generated by the UiIdsGenerator code generator + /// + [Serializable] + public struct UiConfig + { + public string AddressableAddress; + public int Layer; + public Type UiType; + } + + /// + /// ScriptableObject tool to import the & to be used in the /// [CreateAssetMenu(fileName = "UiConfigs", menuName = "ScriptableObjects/Configs/UiConfigs")] public class UiConfigs : ScriptableObject diff --git a/Runtime/UiPresenter.cs b/Runtime/UiPresenter.cs index fd23a49..52faa6e 100644 --- a/Runtime/UiPresenter.cs +++ b/Runtime/UiPresenter.cs @@ -60,8 +60,8 @@ internal void InternalClose() } /// - /// Tags the as a to allow definning a specific state when - /// opening it via the + /// Tags the as a to allow defining a specific state when + /// opening the UI via the /// public interface IUiPresenterData {} @@ -69,8 +69,7 @@ public interface IUiPresenterData {} /// /// Extends the behaviour with defined data of type /// - public abstract class UiPresenterData : UiPresenter, IUiPresenterData - where T : struct + public abstract class UiPresenterData : UiPresenter, IUiPresenterData where T : struct { /// /// The Ui data defined when opened via the diff --git a/Runtime/UiService.cs b/Runtime/UiService.cs index f2a6a2c..3ad7d04 100644 --- a/Runtime/UiService.cs +++ b/Runtime/UiService.cs @@ -1,7 +1,8 @@ using System; using System.Collections.Generic; +using System.Linq; +using System.Threading; using System.Threading.Tasks; -using GameLovers.AssetLoader; using UnityEngine; // ReSharper disable CheckNamespace @@ -11,14 +12,14 @@ namespace GameLovers.UiService /// public class UiService : IUiService { - private readonly IAssetLoader _assetLoader; + private readonly IUiAssetLoader _assetLoader; private readonly IDictionary _uiViews = new Dictionary(); private readonly IDictionary _uiConfigs = new Dictionary(); private readonly IDictionary _uiSets = new Dictionary(); private readonly IList _visibleUiList = new List(); private readonly IList _layers = new List(); - public UiService(IAssetLoader assetLoader) + public UiService(IUiAssetLoader assetLoader) { _assetLoader = assetLoader; } @@ -372,7 +373,7 @@ public Task>[] LoadUiSetAsync(int setId) uiTasks.Add(LoadUiAsync(set.UiConfigsType[i])); } - return AssetLoaderUtils.Interleaved(uiTasks); + return Interleaved(uiTasks); } /// @@ -473,6 +474,33 @@ private UiReference GetReference(Type type) return uiReference; } + private Task>[] Interleaved(IEnumerable> tasks) + { + var inputTasks = tasks.ToList(); + var buckets = new TaskCompletionSource>[inputTasks.Count]; + var results = new Task>[buckets.Length]; + var nextTaskIndex = -1; + + for (var i = 0; i < buckets.Length; i++) + { + buckets[i] = new TaskCompletionSource>(); + results[i] = buckets[i].Task; + } + + foreach (var inputTask in inputTasks) + { + inputTask.ContinueWith(Continuation, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); + } + + return results; + + // Local function + void Continuation(Task completed) + { + buckets[Interlocked.Increment(ref nextTaskIndex)].TrySetResult(completed); + } + } + private struct UiReference { public Type UiType; diff --git a/package.json b/package.json index cae59b9..ef8a23b 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "com.gamelovers.uiservice", "displayName": "UiService", - "version": "0.4.0", + "version": "0.5.0", "unity": "2019.3", "description": "This package provides a service to help manage an Unity's, game UI.\nIt allows to open, close, load, unload and request any Ui Configured in the game.\nThe package provides a Ui Set that allows to group a set of Ui Presenters to help load, open and close multiple Uis at the same time.\n\nTo help configure the game's UI you need to create a UiConfigs Scriptable object by:\n- Right Click on the Project View > Create > ScriptableObjects > Configs > UiConfigs", "dependencies": { - "com.gamelovers.assetloader": "0.3.0" + "com.unity.addressables": "1.8.4" }, "type": "library", "hideInEditor": false From adf674cbdb857240fff0f41bf1a680c10f074506 Mon Sep 17 00:00:00 2001 From: Miguel Tomas Date: Tue, 11 Aug 2020 22:04:52 +0200 Subject: [PATCH 3/3] Fixed UiService documenation text --- Runtime/UiService.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Runtime/UiService.cs b/Runtime/UiService.cs index 3ad7d04..7cf4b5b 100644 --- a/Runtime/UiService.cs +++ b/Runtime/UiService.cs @@ -25,8 +25,12 @@ public UiService(IUiAssetLoader assetLoader) } /// - /// Initialize the service with the proper + /// Initialize the service with that define the game's UI /// + /// + /// To help configure the game's UI you need to create a UiConfigs Scriptable object by: + /// - Right Click on the Project View > Create > ScriptableObjects > Configs > UiConfigs + /// /// /// Thrown if any of the in the given is duplicated ///