Skip to content

Commit da29165

Browse files
committed
**Fixed**
- Added *UniTask* to the package to allow the *UiService* run on WebGL
1 parent eae0014 commit da29165

File tree

7 files changed

+42
-49
lines changed

7 files changed

+42
-49
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@ All notable changes to this package will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html)
66

7+
## [0.9.2] - 2024-11-13
8+
9+
**Fixed**
10+
- Added *UniTask* to the package to allow the *UiService* run on WebGL
11+
712
## [0.9.1] - 2024-11-04
813

914
**Fixed**:
1015
- Fixed the issue that would crash *NonDrawingView* if the *GameObject* would be missing a *CanvasRenderer*
1116

1217
## [0.9.0] - 2024-11-01
1318

19+
***New**:
1420
- Added *GetUi<T>* method to the *IUiService*. It requests the *UiPresenter* by directly using generic T
1521
- Added *IsVisible<T>* method to the *IUiService*. It requests the visibility state of *UiPresenter*
1622
- Added IReadOnlyList property *VisiblePresenters* to the *IUiService* to allow external entities to access the list of visible *UiPresenter*
@@ -20,6 +26,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
2026

2127
## [0.8.0] - 2024-10-29
2228

29+
***New**:
2330
- Added new *PresenterDelayerBase*, *AnimationDelayer* and *TimeDelayer* to support presenters that open/close with a delay
2431
- Added new *DelayUiPresenter* to interact with *PresenterDelayerBase* implementations and allow presenters to open/close with a delay
2532
- Improved performance of *UiService*
@@ -41,13 +48,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
4148

4249
## [0.7.1] - 2021-05-03
4350

51+
***New**:
4452
- Added the possibility for *SafeAreaHelpersView* to maintain the View in the same position if not placed outside of the safe area
4553

4654
**Fixed**:
4755
- Fixed the duplicated memory issue when loading the same *UiPresenter* multiple times at the same time before when of them is finished
4856

4957
## [0.7.0] - 2021-03-12
5058

59+
***New**:
5160
- Added *NonDrawingView* to have an Image without a renderer to not add additional draw calls.
5261
- Added *SafeAreaHelperView* to add the possibility for the *RectTransform* to adjust himself to the screen notches
5362
- Added *AnimatedUiPresenter* to play animation on enter or closing
@@ -61,10 +70,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6170

6271
## [0.6.1] - 2020-09-24
6372

73+
**Fixed**:
6474
- Updated dependency packages
6575

6676
## [0.6.0] - 2020-09-24
6777

78+
***New**:
6879
- Added the possibility for the *IUiService* to allow to open/close already opened/closed *UiPresenters*, and throw an exception if not.
6980
- Added the visible property to UiPresenter of its current visual status Added *IUiServiceInit* to give a new contract interface for the *UiService" initialisation
7081

@@ -75,6 +86,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
7586

7687
## [0.5.0] - 2020-07-13
7788

89+
***New**:
7890
- Added *UiAssetLoader* to load Ui assets to memory
7991

8092
**Changed**:
@@ -88,19 +100,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
88100

89101
## [0.3.2] - 2020-04-18
90102

103+
**Changed**:
91104
- Moved interface *IUiService* to a separate file to improve the code readability
92105

93106
## [0.3.1] - 2020-02-15
94107

108+
**Changed**:
95109
- Updated dependency packages
96110

97111
## [0.3.0] - 2020-02-11
98112

113+
***New**:
99114
- Added new *UiPresenterData* class for the case where the *UiPresenter* needs to be initialized with a default data value
100115
- Added new *OnInitialize* method that is invoked after the *UiPresenter* is initialized
101116

102117
## [0.2.1] - 2020-02-09
103118

119+
***New**:
104120
- Added the possibility to open the ui after adding or loading it to the *UiService*
105121
- Added the possibility to get the canvas reference object based on the given layer
106122
- Added the possibility to remove and unload the *UiPresenter* by only passing it's reference
@@ -110,6 +126,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
110126

111127
## [0.2.0] - 2020-01-19
112128

129+
***New**:
113130
- 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
114131
- 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>(T presenter)*
115132
- Now the *UnloadUi* & *UnloadUiSet* properly unloads the ui from memory and removes it from the service

Runtime/GameLovers.UiService.asmdef

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"rootNamespace": "",
44
"references": [
55
"GUID:84651a3751eca9349aac36a66bba901b",
6-
"GUID:9e24947de15b9834991c9d8411ea37cf"
6+
"GUID:9e24947de15b9834991c9d8411ea37cf",
7+
"GUID:f51ebe6a0ceec4240a699833d6309b23"
78
],
89
"includePlatforms": [],
910
"excludePlatforms": [],

Runtime/IUiService.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Cysharp.Threading.Tasks;
12
using System;
23
using System.Collections.Generic;
34
using System.Threading.Tasks;
@@ -111,7 +112,7 @@ public interface IUiService
111112
/// <param name="openAfter">Whether to open the UI after loading.</param>
112113
/// <returns>A task that completes with the loaded UI.</returns>
113114
/// <exception cref="KeyNotFoundException">Thrown if the service does not contain a UI configuration for the specified type.</exception>
114-
async Task<T> LoadUiAsync<T>(bool openAfter = false) where T : UiPresenter => (await LoadUiAsync(typeof(T), openAfter)) as T;
115+
async UniTask<T> LoadUiAsync<T>(bool openAfter = false) where T : UiPresenter => (await LoadUiAsync(typeof(T), openAfter)) as T;
115116

116117
/// <summary>
117118
/// Loads the UI of the specified type asynchronously.
@@ -122,7 +123,7 @@ public interface IUiService
122123
/// <param name="openAfter">Whether to open the UI after loading.</param>
123124
/// <returns>A task that completes with the loaded UI.</returns>
124125
/// <exception cref="KeyNotFoundException">Thrown if the service does not contain a UI configuration for the specified type.</exception>
125-
Task<UiPresenter> LoadUiAsync(Type type, bool openAfter = false);
126+
UniTask<UiPresenter> LoadUiAsync(Type type, bool openAfter = false);
126127

127128
/// <summary>
128129
/// Loads all UI presenters from the specified UI set asynchronously.
@@ -132,7 +133,7 @@ public interface IUiService
132133
/// <param name="setId">The ID of the UI set to load from.</param>
133134
/// <returns>An array of tasks that complete with each loaded UI.</returns>
134135
/// <exception cref="KeyNotFoundException">Thrown if the service does not contain a UI set with the specified ID.</exception>
135-
Task<Task<UiPresenter>>[] LoadUiSetAsync(int setId);
136+
IList<UniTask<UiPresenter>> LoadUiSetAsync(int setId);
136137

137138
/// <summary>
138139
/// Unloads the UI of the specified type.
@@ -168,14 +169,14 @@ public interface IUiService
168169
/// </summary>
169170
/// <typeparam name="T">The type of UI presenter to open.</typeparam>
170171
/// <returns>A task that completes when the UI presenter is opened.</returns>
171-
async Task<T> OpenUiAsync<T>() where T : UiPresenter => (await OpenUiAsync(typeof(T))) as T;
172+
async UniTask<T> OpenUiAsync<T>() where T : UiPresenter => (await OpenUiAsync(typeof(T))) as T;
172173

173174
/// <summary>
174175
/// Opens a UI presenter asynchronously, loading its assets if necessary.
175176
/// </summary>
176177
/// <param name="type">The type of UI presenter to open.</param>
177178
/// <returns>A task that completes when the UI presenter is opened.</returns>
178-
Task<UiPresenter> OpenUiAsync(Type type);
179+
UniTask<UiPresenter> OpenUiAsync(Type type);
179180

180181
/// <summary>
181182
/// Opens a UI presenter asynchronously, loading its assets if necessary, and sets its initial data.
@@ -184,7 +185,7 @@ public interface IUiService
184185
/// <typeparam name="TData">The type of initial data to set.</typeparam>
185186
/// <param name="initialData">The initial data to set.</param>
186187
/// <returns>A task that completes when the UI presenter is opened.</returns>
187-
async Task<T> OpenUiAsync<T, TData>(TData initialData)
188+
async UniTask<T> OpenUiAsync<T, TData>(TData initialData)
188189
where T : class, IUiPresenterData
189190
where TData : struct => await OpenUiAsync(typeof(T), initialData) as T;
190191

@@ -194,7 +195,7 @@ async Task<T> OpenUiAsync<T, TData>(TData initialData)
194195
/// <param name="type">The type of UI presenter to open.</param>
195196
/// <param name="initialData">The initial data to set.</param>
196197
/// <returns>A task that completes when the UI presenter is opened.</returns>
197-
Task<UiPresenter> OpenUiAsync<TData>(Type type, TData initialData) where TData : struct;
198+
UniTask<UiPresenter> OpenUiAsync<TData>(Type type, TData initialData) where TData : struct;
198199

199200
/// <summary>
200201
/// Closes a UI presenter and optionally destroys its assets.

Runtime/UiAssetLoader.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System.IO;
2-
using System.Threading.Tasks;
1+
using Cysharp.Threading.Tasks;
32
using UnityEngine;
43
using UnityEngine.AddressableAssets;
54
using UnityEngine.ResourceManagement.AsyncOperations;
@@ -20,7 +19,7 @@ public interface IUiAssetLoader
2019
/// <param name="config">The UI configuration to instantiate.</param>
2120
/// <param name="parent">The parent transform to instantiate the prefab under.</param>
2221
/// <returns>A task that completes with the instantiated prefab game object.</returns>
23-
Task<GameObject> InstantiatePrefab(UiConfig config, Transform parent);
22+
UniTask<GameObject> InstantiatePrefab(UiConfig config, Transform parent);
2423

2524
/// <summary>
2625
/// Unloads the given <paramref name="asset"/> from the game memory
@@ -32,7 +31,7 @@ public interface IUiAssetLoader
3231
public class UiAssetLoader : IUiAssetLoader
3332
{
3433
/// <inheritdoc />
35-
public async Task<GameObject> InstantiatePrefab(UiConfig config, Transform parent)
34+
public async UniTask<GameObject> InstantiatePrefab(UiConfig config, Transform parent)
3635
{
3736
var operation = Addressables.InstantiateAsync(config.AddressableAddress, new InstantiationParameters(parent, false));
3837

Runtime/UiConfigs.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public struct UiConfig
2323
/// ScriptableObject tool to import the <seealso cref="UiConfig"/> & <seealso cref="UiSetConfig"/> to be used in the <see cref="IUiService"/>
2424
/// </summary>
2525
[CreateAssetMenu(fileName = "UiConfigs", menuName = "ScriptableObjects/Configs/UiConfigs")]
26-
public class UiConfigs : ScriptableObject
26+
public class UiConfigs : ScriptableObject//, IConfigsContainer<UiConfig>
2727
{
2828
[SerializeField] private string _loadingSpinnerType;
2929
[SerializeField]

Runtime/UiService.cs

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Cysharp.Threading.Tasks;
12
using System;
23
using System.Collections.Generic;
34
using System.Linq;
@@ -154,7 +155,7 @@ public List<UiPresenter> RemoveUiSet(int setId)
154155
}
155156

156157
/// <inheritdoc />
157-
public async Task<UiPresenter> LoadUiAsync(Type type, bool openAfter = false)
158+
public async UniTask<UiPresenter> LoadUiAsync(Type type, bool openAfter = false)
158159
{
159160
if (!_uiConfigs.TryGetValue(type, out var config))
160161
{
@@ -190,9 +191,9 @@ public async Task<UiPresenter> LoadUiAsync(Type type, bool openAfter = false)
190191
}
191192

192193
/// <inheritdoc />
193-
public Task<Task<UiPresenter>>[] LoadUiSetAsync(int setId)
194+
public IList<UniTask<UiPresenter>> LoadUiSetAsync(int setId)
194195
{
195-
var uiTasks = new List<Task<UiPresenter>>();
196+
var uiTasks = new List<UniTask<UiPresenter>>();
196197

197198
if (_uiSets.TryGetValue(setId, out var set))
198199
{
@@ -207,7 +208,7 @@ public Task<Task<UiPresenter>>[] LoadUiSetAsync(int setId)
207208
}
208209
}
209210

210-
return Interleaved(uiTasks);
211+
return uiTasks;
211212
}
212213

213214
/// <inheritdoc />
@@ -235,7 +236,7 @@ public void UnloadUiSet(int setId)
235236
}
236237

237238
/// <inheritdoc />
238-
public async Task<UiPresenter> OpenUiAsync(Type type)
239+
public async UniTask<UiPresenter> OpenUiAsync(Type type)
239240
{
240241
var ui = await GetOrLoadUiAsync(type);
241242

@@ -245,7 +246,7 @@ public async Task<UiPresenter> OpenUiAsync(Type type)
245246
}
246247

247248
/// <inheritdoc />
248-
public async Task<UiPresenter> OpenUiAsync<TData>(Type type, TData initialData) where TData : struct
249+
public async UniTask<UiPresenter> OpenUiAsync<TData>(Type type, TData initialData) where TData : struct
249250
{
250251
var ui = await GetOrLoadUiAsync(type);
251252
var uiPresenterData = ui as UiPresenterData<TData>;
@@ -333,7 +334,7 @@ private void OpenUi(Type type)
333334
_visibleUiList.Add(type);
334335
}
335336

336-
private async Task<UiPresenter> GetOrLoadUiAsync(Type type)
337+
private async UniTask<UiPresenter> GetOrLoadUiAsync(Type type)
337338
{
338339
if (!_uiPresenters.TryGetValue(type, out var ui))
339340
{
@@ -364,32 +365,5 @@ private void CloseLoadingSpinner()
364365

365366
CloseUi(_loadingSpinnerType);
366367
}
367-
368-
private Task<Task<T>>[] Interleaved<T>(IEnumerable<Task<T>> tasks)
369-
{
370-
var inputTasks = tasks.ToList();
371-
var buckets = new TaskCompletionSource<Task<T>>[inputTasks.Count];
372-
var results = new Task<Task<T>>[buckets.Length];
373-
var nextTaskIndex = -1;
374-
375-
for (var i = 0; i < buckets.Length; i++)
376-
{
377-
buckets[i] = new TaskCompletionSource<Task<T>>();
378-
results[i] = buckets[i].Task;
379-
}
380-
381-
foreach (var inputTask in inputTasks)
382-
{
383-
inputTask.ContinueWith(Continuation, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
384-
}
385-
386-
return results;
387-
388-
// Local function
389-
void Continuation(Task<T> completed)
390-
{
391-
buckets[Interlocked.Increment(ref nextTaskIndex)].TrySetResult(completed);
392-
}
393-
}
394368
}
395369
}

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
"name": "com.gamelovers.uiservice",
33
"displayName": "UiService",
44
"author": "Miguel Tomas",
5-
"version": "0.9.1",
5+
"version": "0.9.2",
66
"unity": "2022.3",
77
"license": "MIT",
88
"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",
99
"dependencies": {
10-
"com.unity.addressables": "1.22.0"
10+
"com.unity.addressables": "1.22.0",
11+
"com.cysharp.unitask": "2.5.10"
1112
},
1213
"type": "library",
1314
"hideInEditor": false

0 commit comments

Comments
 (0)