diff --git a/CHANGELOG.md b/CHANGELOG.md index e104e46..6e9d512 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ 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.10.0] - 2024-11-13 + +**New**: +- Added *UniTask* dependency to enable WebGL platform support + +**Changed**: +- Updated *IUiService* async methods to use *UniTask* instead of *Task* for better performance and WebGL compatibility + ## [0.9.1] - 2024-11-04 **Fixed**: @@ -11,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.9.0] - 2024-11-01 +***New**: - Added *GetUi* method to the *IUiService*. It requests the *UiPresenter* by directly using generic T - Added *IsVisible* method to the *IUiService*. It requests the visibility state of *UiPresenter* - Added IReadOnlyList property *VisiblePresenters* to the *IUiService* to allow external entities to access the list of visible *UiPresenter* @@ -20,6 +29,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.8.0] - 2024-10-29 +***New**: - Added new *PresenterDelayerBase*, *AnimationDelayer* and *TimeDelayer* to support presenters that open/close with a delay - Added new *DelayUiPresenter* to interact with *PresenterDelayerBase* implementations and allow presenters to open/close with a delay - Improved performance of *UiService* @@ -41,6 +51,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.7.1] - 2021-05-03 +***New**: - Added the possibility for *SafeAreaHelpersView* to maintain the View in the same position if not placed outside of the safe area **Fixed**: @@ -48,6 +59,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.7.0] - 2021-03-12 +***New**: - Added *NonDrawingView* to have an Image without a renderer to not add additional draw calls. - Added *SafeAreaHelperView* to add the possibility for the *RectTransform* to adjust himself to the screen notches - Added *AnimatedUiPresenter* to play animation on enter or closing @@ -61,10 +73,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.6.1] - 2020-09-24 +**Fixed**: - Updated dependency packages ## [0.6.0] - 2020-09-24 +***New**: - Added the possibility for the *IUiService* to allow to open/close already opened/closed *UiPresenters*, and throw an exception if not. - Added the visible property to UiPresenter of its current visual status Added *IUiServiceInit* to give a new contract interface for the *UiService" initialisation @@ -75,6 +89,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.5.0] - 2020-07-13 +***New**: - Added *UiAssetLoader* to load Ui assets to memory **Changed**: @@ -88,19 +103,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.3.2] - 2020-04-18 +**Changed**: - Moved interface *IUiService* to a separate file to improve the code readability ## [0.3.1] - 2020-02-15 +**Changed**: - Updated dependency packages ## [0.3.0] - 2020-02-11 +***New**: - Added new *UiPresenterData* class for the case where the *UiPresenter* needs to be initialized with a default data value - Added new *OnInitialize* method that is invoked after the *UiPresenter* is initialized ## [0.2.1] - 2020-02-09 +***New**: - Added the possibility to open the ui after adding or loading it to the *UiService* - Added the possibility to get the canvas reference object based on the given layer - Added the possibility to remove and unload the *UiPresenter* by only passing it's reference @@ -110,6 +129,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.2.0] - 2020-01-19 +***New**: - Added easy selection of the *UiConfigs.asset* file. Just go to *Tools > Select UiConfigs.asset*. If the *UiConfigs.asset* does not exist, it will create a new one in the Assets folder - Added the protected *Close()* method to directly allow to close the *UiPresenter* from the *UiPresenter* object file without needing to call the *UiService*. Also now is possible to close an Ui in the service by referencing the object directly without needing to reference the object type by calling *CloseUi(T presenter)* - Now the *UnloadUi* & *UnloadUiSet* properly unloads the ui from memory and removes it from the service diff --git a/Runtime/GameLovers.UiService.asmdef b/Runtime/GameLovers.UiService.asmdef index 3107fb7..4a5f966 100644 --- a/Runtime/GameLovers.UiService.asmdef +++ b/Runtime/GameLovers.UiService.asmdef @@ -3,7 +3,8 @@ "rootNamespace": "", "references": [ "GUID:84651a3751eca9349aac36a66bba901b", - "GUID:9e24947de15b9834991c9d8411ea37cf" + "GUID:9e24947de15b9834991c9d8411ea37cf", + "GUID:f51ebe6a0ceec4240a699833d6309b23" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Runtime/IUiService.cs b/Runtime/IUiService.cs index 75d5e83..58d610a 100644 --- a/Runtime/IUiService.cs +++ b/Runtime/IUiService.cs @@ -1,3 +1,4 @@ +using Cysharp.Threading.Tasks; using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -111,7 +112,7 @@ public interface IUiService /// Whether to open the UI after loading. /// A task that completes with the loaded UI. /// Thrown if the service does not contain a UI configuration for the specified type. - async Task LoadUiAsync(bool openAfter = false) where T : UiPresenter => (await LoadUiAsync(typeof(T), openAfter)) as T; + async UniTask LoadUiAsync(bool openAfter = false) where T : UiPresenter => (await LoadUiAsync(typeof(T), openAfter)) as T; /// /// Loads the UI of the specified type asynchronously. @@ -122,7 +123,7 @@ public interface IUiService /// Whether to open the UI after loading. /// A task that completes with the loaded UI. /// Thrown if the service does not contain a UI configuration for the specified type. - Task LoadUiAsync(Type type, bool openAfter = false); + UniTask LoadUiAsync(Type type, bool openAfter = false); /// /// Loads all UI presenters from the specified UI set asynchronously. @@ -132,7 +133,7 @@ public interface IUiService /// The ID of the UI set to load from. /// An array of tasks that complete with each loaded UI. /// Thrown if the service does not contain a UI set with the specified ID. - Task>[] LoadUiSetAsync(int setId); + IList> LoadUiSetAsync(int setId); /// /// Unloads the UI of the specified type. @@ -168,14 +169,14 @@ public interface IUiService /// /// The type of UI presenter to open. /// A task that completes when the UI presenter is opened. - async Task OpenUiAsync() where T : UiPresenter => (await OpenUiAsync(typeof(T))) as T; + async UniTask OpenUiAsync() where T : UiPresenter => (await OpenUiAsync(typeof(T))) as T; /// /// Opens a UI presenter asynchronously, loading its assets if necessary. /// /// The type of UI presenter to open. /// A task that completes when the UI presenter is opened. - Task OpenUiAsync(Type type); + UniTask OpenUiAsync(Type type); /// /// Opens a UI presenter asynchronously, loading its assets if necessary, and sets its initial data. @@ -184,7 +185,7 @@ public interface IUiService /// The type of initial data to set. /// The initial data to set. /// A task that completes when the UI presenter is opened. - async Task OpenUiAsync(TData initialData) + async UniTask OpenUiAsync(TData initialData) where T : class, IUiPresenterData where TData : struct => await OpenUiAsync(typeof(T), initialData) as T; @@ -194,7 +195,7 @@ async Task OpenUiAsync(TData initialData) /// The type of UI presenter to open. /// The initial data to set. /// A task that completes when the UI presenter is opened. - Task OpenUiAsync(Type type, TData initialData) where TData : struct; + UniTask OpenUiAsync(Type type, TData initialData) where TData : struct; /// /// Closes a UI presenter and optionally destroys its assets. diff --git a/Runtime/UiAssetLoader.cs b/Runtime/UiAssetLoader.cs index b151dd1..07fc2a2 100644 --- a/Runtime/UiAssetLoader.cs +++ b/Runtime/UiAssetLoader.cs @@ -1,5 +1,4 @@ -using System.IO; -using System.Threading.Tasks; +using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; @@ -20,7 +19,7 @@ public interface IUiAssetLoader /// The UI configuration to instantiate. /// The parent transform to instantiate the prefab under. /// A task that completes with the instantiated prefab game object. - Task InstantiatePrefab(UiConfig config, Transform parent); + UniTask InstantiatePrefab(UiConfig config, Transform parent); /// /// Unloads the given from the game memory @@ -32,7 +31,7 @@ public interface IUiAssetLoader public class UiAssetLoader : IUiAssetLoader { /// - public async Task InstantiatePrefab(UiConfig config, Transform parent) + public async UniTask InstantiatePrefab(UiConfig config, Transform parent) { var operation = Addressables.InstantiateAsync(config.AddressableAddress, new InstantiationParameters(parent, false)); diff --git a/Runtime/UiConfigs.cs b/Runtime/UiConfigs.cs index 0ec4d3f..1f44e12 100644 --- a/Runtime/UiConfigs.cs +++ b/Runtime/UiConfigs.cs @@ -23,7 +23,7 @@ public struct UiConfig /// ScriptableObject tool to import the & to be used in the /// [CreateAssetMenu(fileName = "UiConfigs", menuName = "ScriptableObjects/Configs/UiConfigs")] - public class UiConfigs : ScriptableObject + public class UiConfigs : ScriptableObject//, IConfigsContainer { [SerializeField] private string _loadingSpinnerType; [SerializeField] diff --git a/Runtime/UiService.cs b/Runtime/UiService.cs index a56464b..2c3802f 100644 --- a/Runtime/UiService.cs +++ b/Runtime/UiService.cs @@ -1,3 +1,4 @@ +using Cysharp.Threading.Tasks; using System; using System.Collections.Generic; using System.Linq; @@ -154,7 +155,7 @@ public List RemoveUiSet(int setId) } /// - public async Task LoadUiAsync(Type type, bool openAfter = false) + public async UniTask LoadUiAsync(Type type, bool openAfter = false) { if (!_uiConfigs.TryGetValue(type, out var config)) { @@ -190,9 +191,9 @@ public async Task LoadUiAsync(Type type, bool openAfter = false) } /// - public Task>[] LoadUiSetAsync(int setId) + public IList> LoadUiSetAsync(int setId) { - var uiTasks = new List>(); + var uiTasks = new List>(); if (_uiSets.TryGetValue(setId, out var set)) { @@ -207,7 +208,7 @@ public Task>[] LoadUiSetAsync(int setId) } } - return Interleaved(uiTasks); + return uiTasks; } /// @@ -235,7 +236,7 @@ public void UnloadUiSet(int setId) } /// - public async Task OpenUiAsync(Type type) + public async UniTask OpenUiAsync(Type type) { var ui = await GetOrLoadUiAsync(type); @@ -245,7 +246,7 @@ public async Task OpenUiAsync(Type type) } /// - public async Task OpenUiAsync(Type type, TData initialData) where TData : struct + public async UniTask OpenUiAsync(Type type, TData initialData) where TData : struct { var ui = await GetOrLoadUiAsync(type); var uiPresenterData = ui as UiPresenterData; @@ -333,7 +334,7 @@ private void OpenUi(Type type) _visibleUiList.Add(type); } - private async Task GetOrLoadUiAsync(Type type) + private async UniTask GetOrLoadUiAsync(Type type) { if (!_uiPresenters.TryGetValue(type, out var ui)) { @@ -364,32 +365,5 @@ private void CloseLoadingSpinner() CloseUi(_loadingSpinnerType); } - - 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); - } - } } } \ No newline at end of file diff --git a/package.json b/package.json index 1a142ba..da8eedf 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,13 @@ "name": "com.gamelovers.uiservice", "displayName": "UiService", "author": "Miguel Tomas", - "version": "0.9.1", + "version": "0.10.0", "unity": "2022.3", "license": "MIT", "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.unity.addressables": "1.22.0" + "com.unity.addressables": "1.22.0", + "com.cysharp.unitask": "2.5.10" }, "type": "library", "hideInEditor": false