FindFailureAssetsWnd.ts 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. const FairyGUI = CS.FairyGUI;
  2. const FairyEditor = CS.FairyEditor
  3. import FileUtils from "./FileUtils";
  4. import UIWindow, { WindData } from "./UIWindow"
  5. const App = FairyEditor.App;
  6. type FailureAssetData = {
  7. url: string,
  8. failure: string[],
  9. }
  10. export default class FindFailureAssetsWnd extends UIWindow {
  11. constructor() {
  12. super(new WindData("Extend", "FindFailureAssets"))
  13. }
  14. static show() {
  15. let url = FileUtils.joinUrl("Extend", "FindFailureAssets")
  16. if (UIWindow.FindUrl(url) == undefined) {
  17. UIWindow.add(new this)
  18. }
  19. super.show(url)
  20. }
  21. private state: CS.FairyGUI.Controller;
  22. private check: CS.FairyGUI.GButton
  23. private progress: CS.FairyGUI.GProgressBar
  24. private resList: CS.FairyGUI.GList;
  25. private assets = new Map<string, FindFailureAssetsWnd>()
  26. protected onInit(): void {
  27. super.onInit();
  28. this.state = this.contentPane.GetController("state");
  29. this.check = this.contentPane.GetChild("check").asButton;
  30. this.progress = this.contentPane.GetChild("progress").asProgress;
  31. this.resList = this.contentPane.GetChild("resList").asList;
  32. this.resList.itemRenderer = this.onItemRenderer.bind(this);
  33. this.resList.onClickItem.Add(this.onListClickItem.bind(this))
  34. this.check.onClick.Add(this.onCheckClick.bind(this))
  35. let cancel = this.contentPane.GetChild("close").asButton
  36. cancel.onClick.Add(this.onCancelClick.bind(this))
  37. this.resList.SetVirtual();
  38. }
  39. protected onShown(): void {
  40. super.onShown();
  41. }
  42. protected onHide(): void {
  43. super.onHide();
  44. this.resList.data = null;
  45. this.resList.numItems = 0;
  46. }
  47. private async onCheckClick() {
  48. if (this.state.selectedIndex == 0) {
  49. this.state.selectedIndex = 1;
  50. this.assets.clear();
  51. let pkgs = App.project.allPackages;
  52. this.progress.value = 0;
  53. this.progress.max = FileUtils.getAllPackageItemsCount();
  54. for (let index = 0; index < pkgs.Count; index++) {
  55. let pkg = pkgs.get_Item(index);
  56. if (this.state.selectedIndex == 0) break
  57. for (let j = 0; j < pkg.items.Count; j++) {
  58. if (this.state.selectedIndex == 0) break
  59. let item = pkg.items.get_Item(j);
  60. this.progress.value += 1
  61. if (item.type != CS.FairyEditor.FObjectType.COMPONENT) {
  62. continue
  63. }
  64. //@ts-ignore
  65. this.getFailureAssets(item, this.assets, 0)
  66. if (this.progress.value % 30 == 0) {
  67. await FileUtils.sleep(0)
  68. }
  69. }
  70. }
  71. App.consoleView.Log("查找完毕")
  72. this.state.selectedIndex = 0;
  73. let asset = Array.from(this.assets).map(item => item[1]);
  74. this.resList.data = asset;
  75. this.resList.numItems = asset.length;
  76. this.contentPane.GetChild("projectCount").asTextField.templateVars = FileUtils.getTemplateVars(['value'],[asset.length.toString()]);
  77. } else {
  78. this.state.selectedIndex = 0;
  79. }
  80. }
  81. private onItemRenderer(index: number, obj: CS.FairyGUI.GComponent): void {
  82. let data = this.resList.data[index] as FailureAssetData;
  83. obj.data = data;
  84. let packageItem = App.project.GetItemByURL(data.url)
  85. obj.GetChild("title").text = packageItem.name
  86. obj.__onDispose = () => {
  87. obj.GetChild("title").text = ''
  88. obj.data = null;
  89. }
  90. }
  91. private onListClickItem(item: CS.FairyGUI.EventContext): void {
  92. let data = item.data.data as FailureAssetData;
  93. let packageItem = App.project.GetItemByURL(data.url)
  94. App.consoleView.Log(FileUtils.getUBBUrl(packageItem.GetURL(),`包含无效URL的组件:${packageItem.name}`))
  95. for (let index = 0; index < data.failure.length; index++) {
  96. App.consoleView.Log('无效URL:'+data.failure[index])
  97. }
  98. }
  99. private onCancelClick() {
  100. let self = this;
  101. this.Hide();
  102. FairyGUI.Timers.inst.Add(0.05, 1, () => {
  103. UIWindow.remove(self)
  104. })
  105. }
  106. /**查找失效资源 */
  107. private getFailureAssets(item: CS.FairyEditor.FPackageItem, map: Map<string, { url: string, failure: string[] }>, quertIndex) {
  108. let xml = CS.FairyEditor.XMLExtension.Load(item.file)
  109. if (!xml) {
  110. App.consoleView.LogError(`PackageItem找不到配置文件. Name:${item.name} Index:${quertIndex} File:${item.file}`)
  111. return quertIndex;
  112. }
  113. let rootElements = xml.Elements()
  114. for (let index = 0; index < rootElements.Count; index++) {
  115. let child = rootElements.get_Item(index)
  116. if (child.name != 'displayList') continue
  117. let childElements = child.Elements();
  118. for (let index = 0; index < childElements.Count; index++) {
  119. const element = childElements.get_Item(index);
  120. if (element.name == 'loader' || element.name == 'loader3D') {
  121. if (element.GetAttribute('clearOnPublish')) continue
  122. let url = element.GetAttribute('url')
  123. if (!url) continue
  124. //没清理依赖
  125. let packageItem = App.project.GetItemByURL(url)
  126. if (!packageItem) {
  127. if (!map.has(item.GetURL())) {
  128. map.set(item.GetURL(), {
  129. url: item.GetURL(),
  130. failure: []
  131. })
  132. }
  133. map.get(item.GetURL()).failure.push(`name:${element.GetAttribute("name")} file:${element.GetAttribute("fileName")} url:${url}`)
  134. }
  135. else if (!map.has(packageItem.GetURL())) {
  136. if (packageItem.type == FairyEditor.FPackageItemType.COMPONENT) {
  137. quertIndex = this.getFailureAssets(packageItem, map, quertIndex)
  138. }
  139. quertIndex += 1;
  140. }
  141. } else {
  142. let src = element.GetAttribute("src")
  143. if (!src) {
  144. //系统资源 不需要依赖
  145. continue
  146. }
  147. let pkg = element.GetAttribute("pkg")
  148. if (!pkg) {
  149. //自己依赖包的资源 所以不需要pkg
  150. pkg = item.owner.id;
  151. }
  152. let url = `ui://${pkg}${src}`
  153. if (src == null) App.consoleView.Log(element.name)
  154. let packageItem = App.project.GetItemByURL(url)
  155. if (!packageItem) {
  156. if (!map.has(item.GetURL())) {
  157. map.set(item.GetURL(), {
  158. url: item.GetURL(),
  159. failure: []
  160. })
  161. }
  162. map.get(item.GetURL()).failure.push(`name:${element.GetAttribute("name")} file:${element.GetAttribute("fileName")} url:${url}`)
  163. }
  164. else if (!map.has(packageItem.GetURL())) {
  165. if (packageItem.type == FairyEditor.FPackageItemType.COMPONENT) {
  166. quertIndex = this.getFailureAssets(packageItem, map, quertIndex)
  167. }
  168. quertIndex += 1;
  169. }
  170. }
  171. }
  172. }
  173. return quertIndex
  174. }
  175. }