|  |  |  |  | using System.Collections; | 
					
						
							|  |  |  |  | using System.Collections.Generic; | 
					
						
							|  |  |  |  | using UnityEngine; | 
					
						
							|  |  |  |  | using FairyGUI.Utils; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | namespace FairyGUI | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     public class AsyncCreationHelper | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         public static void CreateObject(PackageItem item, UIPackage.CreateObjectCallback callback) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             Timers.inst.StartCoroutine(_CreateObject(item, callback)); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         static IEnumerator _CreateObject(PackageItem item, UIPackage.CreateObjectCallback callback) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             Stats.LatestObjectCreation = 0; | 
					
						
							|  |  |  |  |             Stats.LatestGraphicsCreation = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             float frameTime = UIConfig.frameTimeForAsyncUIConstruction; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             List<DisplayListItem> itemList = new List<DisplayListItem>(); | 
					
						
							|  |  |  |  |             DisplayListItem di = new DisplayListItem(item, ObjectType.Component); | 
					
						
							|  |  |  |  |             di.childCount = CollectComponentChildren(item, itemList); | 
					
						
							|  |  |  |  |             itemList.Add(di); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             int cnt = itemList.Count; | 
					
						
							|  |  |  |  |             List<GObject> objectPool = new List<GObject>(cnt); | 
					
						
							|  |  |  |  |             GObject obj; | 
					
						
							|  |  |  |  |             float t = Time.realtimeSinceStartup; | 
					
						
							|  |  |  |  |             bool alreadyNextFrame = false; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             for (int i = 0; i < cnt; i++) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 di = itemList[i]; | 
					
						
							|  |  |  |  |                 if (di.packageItem != null) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     obj = UIObjectFactory.NewObject(di.packageItem); | 
					
						
							|  |  |  |  |                     objectPool.Add(obj); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                     UIPackage._constructing++; | 
					
						
							|  |  |  |  |                     if (di.packageItem.type == PackageItemType.Component) | 
					
						
							|  |  |  |  |                     { | 
					
						
							|  |  |  |  |                         int poolStart = objectPool.Count - di.childCount - 1; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                         ((GComponent)obj).ConstructFromResource(objectPool, poolStart); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                         objectPool.RemoveRange(poolStart, di.childCount); | 
					
						
							|  |  |  |  |                     } | 
					
						
							|  |  |  |  |                     else | 
					
						
							|  |  |  |  |                     { | 
					
						
							|  |  |  |  |                         obj.ConstructFromResource(); | 
					
						
							|  |  |  |  |                     } | 
					
						
							|  |  |  |  |                     UIPackage._constructing--; | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |                 else | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     obj = UIObjectFactory.NewObject(di.type); | 
					
						
							|  |  |  |  |                     objectPool.Add(obj); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                     if (di.type == ObjectType.List && di.listItemCount > 0) | 
					
						
							|  |  |  |  |                     { | 
					
						
							|  |  |  |  |                         int poolStart = objectPool.Count - di.listItemCount - 1; | 
					
						
							|  |  |  |  |                         for (int k = 0; k < di.listItemCount; k++) //把他们都放到pool里,这样GList在创建时就不需要创建对象了 | 
					
						
							|  |  |  |  |                             ((GList)obj).itemPool.ReturnObject(objectPool[k + poolStart]); | 
					
						
							|  |  |  |  |                         objectPool.RemoveRange(poolStart, di.listItemCount); | 
					
						
							|  |  |  |  |                     } | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 if ((i % 5 == 0) && Time.realtimeSinceStartup - t >= frameTime) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     yield return null; | 
					
						
							|  |  |  |  |                     t = Time.realtimeSinceStartup; | 
					
						
							|  |  |  |  |                     alreadyNextFrame = true; | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (!alreadyNextFrame) //强制至至少下一帧才调用callback,避免调用者逻辑出错 | 
					
						
							|  |  |  |  |                 yield return null; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             callback(objectPool[0]); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         /// <summary> | 
					
						
							|  |  |  |  |         /// 收集创建目标对象所需的所有类型信息 | 
					
						
							|  |  |  |  |         /// </summary> | 
					
						
							|  |  |  |  |         /// <param name="item"></param> | 
					
						
							|  |  |  |  |         /// <param name="list"></param> | 
					
						
							|  |  |  |  |         static int CollectComponentChildren(PackageItem item, List<DisplayListItem> list) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             ByteBuffer buffer = item.rawData; | 
					
						
							|  |  |  |  |             buffer.Seek(0, 2); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             int dcnt = buffer.ReadShort(); | 
					
						
							|  |  |  |  |             DisplayListItem di; | 
					
						
							|  |  |  |  |             PackageItem pi; | 
					
						
							|  |  |  |  |             for (int i = 0; i < dcnt; i++) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 int dataLen = buffer.ReadShort(); | 
					
						
							|  |  |  |  |                 int curPos = buffer.position; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 buffer.Seek(curPos, 0); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 ObjectType type = (ObjectType)buffer.ReadByte(); | 
					
						
							|  |  |  |  |                 string src = buffer.ReadS(); | 
					
						
							|  |  |  |  |                 string pkgId = buffer.ReadS(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 buffer.position = curPos; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 if (src != null) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     UIPackage pkg; | 
					
						
							|  |  |  |  |                     if (pkgId != null) | 
					
						
							|  |  |  |  |                         pkg = UIPackage.GetById(pkgId); | 
					
						
							|  |  |  |  |                     else | 
					
						
							|  |  |  |  |                         pkg = item.owner; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                     pi = pkg != null ? pkg.GetItem(src) : null; | 
					
						
							|  |  |  |  |                     di = new DisplayListItem(pi, type); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                     if (pi != null && pi.type == PackageItemType.Component) | 
					
						
							|  |  |  |  |                         di.childCount = CollectComponentChildren(pi, list); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |                 else | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     di = new DisplayListItem(null, type); | 
					
						
							|  |  |  |  |                     if (type == ObjectType.List) //list | 
					
						
							|  |  |  |  |                         di.listItemCount = CollectListChildren(buffer, list); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 list.Add(di); | 
					
						
							|  |  |  |  |                 buffer.position = curPos + dataLen; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             return dcnt; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         static int CollectListChildren(ByteBuffer buffer, List<DisplayListItem> list) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             buffer.Seek(buffer.position, 8); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             string defaultItem = buffer.ReadS(); | 
					
						
							|  |  |  |  |             int listItemCount = 0; | 
					
						
							|  |  |  |  |             int itemCount = buffer.ReadShort(); | 
					
						
							|  |  |  |  |             for (int i = 0; i < itemCount; i++) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 int nextPos = buffer.ReadShort(); | 
					
						
							|  |  |  |  |                 nextPos += buffer.position; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 string url = buffer.ReadS(); | 
					
						
							|  |  |  |  |                 if (url == null) | 
					
						
							|  |  |  |  |                     url = defaultItem; | 
					
						
							|  |  |  |  |                 if (!string.IsNullOrEmpty(url)) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     PackageItem pi = UIPackage.GetItemByURL(url); | 
					
						
							|  |  |  |  |                     if (pi != null) | 
					
						
							|  |  |  |  |                     { | 
					
						
							|  |  |  |  |                         DisplayListItem di = new DisplayListItem(pi, pi.objectType); | 
					
						
							|  |  |  |  |                         if (pi.type == PackageItemType.Component) | 
					
						
							|  |  |  |  |                             di.childCount = CollectComponentChildren(pi, list); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                         list.Add(di); | 
					
						
							|  |  |  |  |                         listItemCount++; | 
					
						
							|  |  |  |  |                     } | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |                 buffer.position = nextPos; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             return listItemCount; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         /// <summary> | 
					
						
							|  |  |  |  |         ///  | 
					
						
							|  |  |  |  |         /// </summary> | 
					
						
							|  |  |  |  |         class DisplayListItem | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             public PackageItem packageItem; | 
					
						
							|  |  |  |  |             public ObjectType type; | 
					
						
							|  |  |  |  |             public int childCount; | 
					
						
							|  |  |  |  |             public int listItemCount; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             public DisplayListItem(PackageItem pi, ObjectType type) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 this.packageItem = pi; | 
					
						
							|  |  |  |  |                 this.type = type; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } |