Skip to content

Commit f2bbc54

Browse files
committed
Add async loading mechanism of UIPackage
1 parent 06caee2 commit f2bbc54

File tree

3 files changed

+195
-78
lines changed

3 files changed

+195
-78
lines changed

Assets/Scripts/Core/NAudioClip.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using UnityEngine;
1+
using System;
2+
using UnityEngine;
23

34
namespace FairyGUI
45
{
@@ -7,6 +8,8 @@ namespace FairyGUI
78
/// </summary>
89
public class NAudioClip
910
{
11+
public static Action<AudioClip> CustomDestroyMethod;
12+
1013
/// <summary>
1114
///
1215
/// </summary>
@@ -37,7 +40,14 @@ public void Unload()
3740
if (destroyMethod == DestroyMethod.Unload)
3841
Resources.UnloadAsset(nativeClip);
3942
else if (destroyMethod == DestroyMethod.Destroy)
40-
Object.DestroyImmediate(nativeClip, true);
43+
UnityEngine.Object.DestroyImmediate(nativeClip, true);
44+
else if (destroyMethod == DestroyMethod.Custom)
45+
{
46+
if (CustomDestroyMethod == null)
47+
Debug.LogWarning("NAudioClip.CustomDestroyMethod must be set to handle DestroyMethod.Custom");
48+
else
49+
CustomDestroyMethod(nativeClip);
50+
}
4151

4252
nativeClip = null;
4353
}
@@ -48,6 +58,9 @@ public void Unload()
4858
/// <param name="audioClip"></param>
4959
public void Reload(AudioClip audioClip)
5060
{
61+
if (nativeClip != null && nativeClip != audioClip)
62+
Unload();
63+
5164
nativeClip = audioClip;
5265
}
5366
}

Assets/Scripts/Core/NTexture.cs

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,17 @@ public enum DestroyMethod
1313
Destroy,
1414
Unload,
1515
None,
16-
ReleaseTemp
16+
ReleaseTemp,
17+
Custom
1718
}
1819

1920
/// <summary>
2021
///
2122
/// </summary>
2223
public class NTexture
2324
{
25+
public static Action<Texture> CustomDestroyMethod;
26+
2427
/// <summary>
2528
///
2629
/// </summary>
@@ -146,8 +149,11 @@ public NTexture(Texture texture, Rect region)
146149
_nativeTexture = texture;
147150
_region = region;
148151
_originalSize = new Vector2(_region.width, _region.height);
149-
uvRect = new Rect(region.x / _nativeTexture.width, 1 - region.yMax / _nativeTexture.height,
150-
region.width / _nativeTexture.width, region.height / _nativeTexture.height);
152+
if (_nativeTexture != null)
153+
uvRect = new Rect(region.x / _nativeTexture.width, 1 - region.yMax / _nativeTexture.height,
154+
region.width / _nativeTexture.width, region.height / _nativeTexture.height);
155+
else
156+
uvRect.Set(0, 0, 1, 1);
151157
}
152158

153159
/// <summary>
@@ -406,23 +412,33 @@ public void Reload(Texture nativeTexture, Texture alphaTexture)
406412

407413
void DestroyTexture()
408414
{
409-
if (destroyMethod == DestroyMethod.Destroy)
410-
{
411-
Object.DestroyImmediate(_nativeTexture, true);
412-
if (_alphaTexture != null)
413-
Object.DestroyImmediate(_alphaTexture, true);
414-
}
415-
else if (destroyMethod == DestroyMethod.Unload)
416-
{
417-
Resources.UnloadAsset(_nativeTexture);
418-
if (_alphaTexture != null)
419-
Resources.UnloadAsset(_alphaTexture);
420-
}
421-
else if (destroyMethod == DestroyMethod.ReleaseTemp)
415+
switch (destroyMethod)
422416
{
423-
RenderTexture.ReleaseTemporary((RenderTexture)_nativeTexture);
424-
if (_alphaTexture is RenderTexture)
425-
RenderTexture.ReleaseTemporary((RenderTexture)_alphaTexture);
417+
case DestroyMethod.Destroy:
418+
Object.DestroyImmediate(_nativeTexture, true);
419+
if (_alphaTexture != null)
420+
Object.DestroyImmediate(_alphaTexture, true);
421+
break;
422+
case DestroyMethod.Unload:
423+
Resources.UnloadAsset(_nativeTexture);
424+
if (_alphaTexture != null)
425+
Resources.UnloadAsset(_alphaTexture);
426+
break;
427+
case DestroyMethod.ReleaseTemp:
428+
RenderTexture.ReleaseTemporary((RenderTexture)_nativeTexture);
429+
if (_alphaTexture is RenderTexture)
430+
RenderTexture.ReleaseTemporary((RenderTexture)_alphaTexture);
431+
break;
432+
case DestroyMethod.Custom:
433+
if (CustomDestroyMethod == null)
434+
Debug.LogWarning("NTexture.CustomDestroyMethod must be set to handle DestroyMethod.Custom");
435+
else
436+
{
437+
CustomDestroyMethod(_nativeTexture);
438+
if (_alphaTexture != null)
439+
CustomDestroyMethod(_alphaTexture);
440+
}
441+
break;
426442
}
427443

428444
_nativeTexture = null;

Assets/Scripts/UI/UIPackage.cs

Lines changed: 145 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ public class UIPackage
4040
/// <returns></returns>
4141
public delegate object LoadResource(string name, string extension, System.Type type, out DestroyMethod destroyMethod);
4242

43+
/// <summary>
44+
/// A async load resource callback. After loaded, call item.owner.SetItemAsset.
45+
/// </summary>
46+
/// <param name="name"></param>
47+
/// <param name="extension"></param>
48+
/// <param name="type"></param>
49+
/// <param name="item"></param>
50+
/// <returns></returns>
51+
public delegate void LoadResourceAsync(string name, string extension, System.Type type, PackageItem item);
52+
4353
/// <summary>
4454
///
4555
/// </summary>
@@ -57,6 +67,7 @@ public class UIPackage
5767
string _customId;
5868
bool _fromBundle;
5969
LoadResource _loadFunc;
70+
LoadResourceAsync _loadAysncFunc;
6071

6172
class AtlasSprite
6273
{
@@ -79,14 +90,14 @@ class AtlasSprite
7990
public const string URL_PREFIX = "ui://";
8091

8192
#if UNITY_EDITOR
82-
static LoadResource _loadFromAssetsPath = (string name, string extension, System.Type type, out DestroyMethod destroyMethod) =>
93+
public static LoadResource _loadFromAssetsPath = (string name, string extension, System.Type type, out DestroyMethod destroyMethod) =>
8394
{
8495
destroyMethod = DestroyMethod.Unload;
8596
return AssetDatabase.LoadAssetAtPath(name + extension, type);
8697
};
8798
#endif
8899

89-
static LoadResource _loadFromResourcesPath = (string name, string extension, System.Type type, out DestroyMethod destroyMethod) =>
100+
public static LoadResource _loadFromResourcesPath = (string name, string extension, System.Type type, out DestroyMethod destroyMethod) =>
90101
{
91102
destroyMethod = DestroyMethod.Unload;
92103
return Resources.Load(name, type);
@@ -336,6 +347,29 @@ public static UIPackage AddPackage(byte[] descData, string assetNamePrefix, Load
336347
return pkg;
337348
}
338349

350+
/// <summary>
351+
/// 使用自定义的加载方式载入一个包。
352+
/// </summary>
353+
/// <param name="descData">描述文件数据。</param>
354+
/// <param name="assetNamePrefix">资源文件名前缀。如果包含,则载入资源时名称将传入assetNamePrefix_resFileName这样格式。可以为空。</param>
355+
/// <param name="loadFunc">载入函数</param>
356+
/// <returns></returns>
357+
public static UIPackage AddPackage(byte[] descData, string assetNamePrefix, LoadResourceAsync loadFunc)
358+
{
359+
ByteBuffer buffer = new ByteBuffer(descData);
360+
361+
UIPackage pkg = new UIPackage();
362+
pkg._loadAysncFunc = loadFunc;
363+
if (!pkg.LoadPackage(buffer, assetNamePrefix))
364+
return null;
365+
366+
_packageInstById[pkg.id] = pkg;
367+
_packageInstByName[pkg.name] = pkg;
368+
_packageList.Add(pkg);
369+
370+
return pkg;
371+
}
372+
339373
/// <summary>
340374
/// Remove a package. All resources in this package will be disposed.
341375
/// </summary>
@@ -1183,67 +1217,110 @@ public object GetItemAsset(PackageItem item)
11831217
}
11841218
}
11851219

1186-
void LoadAtlas(PackageItem item)
1220+
/// <summary>
1221+
///
1222+
/// </summary>
1223+
/// <param name="item"></param>
1224+
/// <param name="asset"></param>
1225+
/// <param name="destroyMethod"></param>
1226+
public void SetItemAsset(PackageItem item, object asset, DestroyMethod destroyMethod)
11871227
{
1188-
string ext = Path.GetExtension(item.file);
1189-
string fileName = item.file.Substring(0, item.file.Length - ext.Length);
1228+
switch (item.type)
1229+
{
1230+
case PackageItemType.Atlas:
1231+
if (item.texture == null)
1232+
item.texture = new NTexture(null, new Rect(0, 0, item.width, item.height));
1233+
item.texture.Reload((Texture)asset, null);
1234+
item.texture.destroyMethod = destroyMethod;
1235+
break;
11901236

1191-
Texture tex = null;
1192-
Texture alphaTex = null;
1193-
DestroyMethod dm;
1237+
case PackageItemType.Sound:
1238+
if (item.audioClip == null)
1239+
item.audioClip = new NAudioClip(null);
1240+
item.audioClip.Reload((AudioClip)asset);
1241+
item.audioClip.destroyMethod = destroyMethod;
1242+
break;
11941243

1195-
if (_fromBundle)
1196-
{
1197-
if (_resBundle != null)
1198-
tex = _resBundle.LoadAsset<Texture>(fileName);
1199-
else
1200-
Debug.LogWarning("FairyGUI: bundle already unloaded.");
1244+
case PackageItemType.Spine:
1245+
#if FAIRYGUI_SPINE
1246+
item.skeletonAsset = (Spine.Unity.SkeletonDataAsset)asset;
1247+
#endif
1248+
break;
12011249

1202-
dm = DestroyMethod.None;
1250+
case PackageItemType.DragoneBones:
1251+
#if FAIRYGUI_DRAGONBONES
1252+
item.skeletonAsset = (DragonBones.UnityDragonBonesData)asset;
1253+
#endif
1254+
break;
12031255
}
1204-
else
1205-
tex = (Texture)_loadFunc(fileName, ext, typeof(Texture), out dm);
1256+
}
12061257

1207-
if (tex == null)
1208-
Debug.LogWarning("FairyGUI: texture '" + item.file + "' not found in " + this.name);
1209-
else if (!(tex is Texture2D))
1258+
void LoadAtlas(PackageItem item)
1259+
{
1260+
string ext = Path.GetExtension(item.file);
1261+
string fileName = item.file.Substring(0, item.file.Length - ext.Length);
1262+
1263+
if (_loadAysncFunc != null)
12101264
{
1211-
Debug.LogWarning("FairyGUI: settings for '" + item.file + "' is wrong! Correct values are: (Texture Type=Default, Texture Shape=2D)");
1212-
tex = null;
1265+
_loadAysncFunc(fileName, ext, typeof(Texture), item);
1266+
if (item.texture == null)
1267+
item.texture = new NTexture(null, new Rect(0, 0, item.width, item.height));
1268+
item.texture.destroyMethod = DestroyMethod.None;
12131269
}
12141270
else
12151271
{
1216-
if (((Texture2D)tex).mipmapCount > 1)
1217-
Debug.LogWarning("FairyGUI: settings for '" + item.file + "' is wrong! Correct values are: (Generate Mip Maps=unchecked)");
1218-
}
1272+
Texture tex = null;
1273+
Texture alphaTex = null;
1274+
DestroyMethod dm;
12191275

1220-
if (tex != null)
1221-
{
1222-
fileName = fileName + "!a";
12231276
if (_fromBundle)
12241277
{
12251278
if (_resBundle != null)
1226-
alphaTex = _resBundle.LoadAsset<Texture2D>(fileName);
1279+
tex = _resBundle.LoadAsset<Texture>(fileName);
1280+
else
1281+
Debug.LogWarning("FairyGUI: bundle already unloaded.");
1282+
1283+
dm = DestroyMethod.None;
12271284
}
12281285
else
1229-
alphaTex = (Texture2D)_loadFunc(fileName, ext, typeof(Texture2D), out dm);
1230-
}
1286+
tex = (Texture)_loadFunc(fileName, ext, typeof(Texture), out dm);
12311287

1288+
if (tex == null)
1289+
Debug.LogWarning("FairyGUI: texture '" + item.file + "' not found in " + this.name);
12321290

1233-
if (tex == null)
1234-
{
1235-
tex = NTexture.CreateEmptyTexture();
1236-
dm = DestroyMethod.Destroy;
1237-
}
1291+
else if (!(tex is Texture2D))
1292+
{
1293+
Debug.LogWarning("FairyGUI: settings for '" + item.file + "' is wrong! Correct values are: (Texture Type=Default, Texture Shape=2D)");
1294+
tex = null;
1295+
}
1296+
else
1297+
{
1298+
if (((Texture2D)tex).mipmapCount > 1)
1299+
Debug.LogWarning("FairyGUI: settings for '" + item.file + "' is wrong! Correct values are: (Generate Mip Maps=unchecked)");
1300+
}
12381301

1239-
if (item.texture == null)
1240-
{
1241-
item.texture = new NTexture(tex, alphaTex, (float)tex.width / item.width, (float)tex.height / item.height);
1242-
item.texture.destroyMethod = dm;
1243-
}
1244-
else
1245-
{
1246-
item.texture.Reload(tex, alphaTex);
1302+
if (tex != null)
1303+
{
1304+
fileName = fileName + "!a";
1305+
if (_fromBundle)
1306+
{
1307+
if (_resBundle != null)
1308+
alphaTex = _resBundle.LoadAsset<Texture2D>(fileName);
1309+
}
1310+
else
1311+
alphaTex = (Texture2D)_loadFunc(fileName, ext, typeof(Texture2D), out dm);
1312+
}
1313+
1314+
if (tex == null)
1315+
{
1316+
tex = NTexture.CreateEmptyTexture();
1317+
dm = DestroyMethod.Destroy;
1318+
}
1319+
1320+
if (item.texture == null)
1321+
item.texture = new NTexture(tex, alphaTex, (float)tex.width / item.width, (float)tex.height / item.height);
1322+
else
1323+
item.texture.Reload(tex, alphaTex);
12471324
item.texture.destroyMethod = dm;
12481325
}
12491326
}
@@ -1268,24 +1345,35 @@ void LoadSound(PackageItem item)
12681345
string ext = Path.GetExtension(item.file);
12691346
string fileName = item.file.Substring(0, item.file.Length - ext.Length);
12701347

1271-
AudioClip audioClip = null;
1272-
DestroyMethod dm;
1273-
1274-
if (_resBundle != null)
1348+
if (_loadAysncFunc != null)
12751349
{
1276-
audioClip = _resBundle.LoadAsset<AudioClip>(fileName);
1277-
dm = DestroyMethod.None;
1350+
_loadAysncFunc(fileName, ext, typeof(AudioClip), item);
1351+
if (item.audioClip == null)
1352+
item.audioClip = new NAudioClip(null);
1353+
item.audioClip.destroyMethod = DestroyMethod.None;
12781354
}
12791355
else
12801356
{
1281-
audioClip = (AudioClip)_loadFunc(fileName, ext, typeof(AudioClip), out dm);
1282-
}
1357+
AudioClip audioClip = null;
1358+
DestroyMethod dm;
12831359

1284-
if (item.audioClip == null)
1285-
item.audioClip = new NAudioClip(audioClip);
1286-
else
1287-
item.audioClip.Reload(audioClip);
1288-
item.audioClip.destroyMethod = dm;
1360+
if (_fromBundle)
1361+
{
1362+
if (_resBundle != null)
1363+
audioClip = _resBundle.LoadAsset<AudioClip>(fileName);
1364+
dm = DestroyMethod.None;
1365+
}
1366+
else
1367+
{
1368+
audioClip = (AudioClip)_loadFunc(fileName, ext, typeof(AudioClip), out dm);
1369+
}
1370+
1371+
if (item.audioClip == null)
1372+
item.audioClip = new NAudioClip(audioClip);
1373+
else
1374+
item.audioClip.Reload(audioClip);
1375+
item.audioClip.destroyMethod = dm;
1376+
}
12891377
}
12901378

12911379
byte[] LoadBinary(PackageItem item)

0 commit comments

Comments
 (0)